Xcode: Как бы я сделал одноразовый UIAlertView? - PullRequest
1 голос
/ 04 сентября 2011

У меня есть приложение, которое я хочу вызвать в виде предупреждения, чтобы спросить их, могут ли они просмотреть приложение?

Любая помощь приветствуется!

Ответы [ 3 ]

5 голосов
/ 04 сентября 2011

Не. Это плохой UX. Вместо этого попробуйте следующее:

  • имеет раздел "О программе" в вашем приложении, содержащий ваш бренд, и ссылку на страницу обзора
  • имеет кнопку «Просмотреть это приложение» в неотвлекающем месте в углу или на боковой части экрана, где это не мешает работе пользователя.
2 голосов
/ 04 сентября 2011

Что-то вроде этого сделало бы:

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"UIAlertView" message:@"<Alert message>" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil];
[alert show];
[alert release];
0 голосов
/ 05 сентября 2011

* Важное обновление

Apple добавила дополнительное правило для приложений, представляемых в магазине приложений.

Мы больше не можем хранить произвольные файлы данных в папке «Документы».Только содержимое, сгенерированное пользователем, например текстовый файл, который он вручную набрал и сохранил, или фотография, сделанная камерой, могут быть сохранены в папке «Документы».

Теперь мы должны хранить файлы, созданные в приложении, в Библиотека / Кэш вместо папки «Документы».Кроме того, мы должны отметить файлы, которые мы не хотим синхронизировать с iCloud, с помощью атрибута skip backup .

Невыполнение этого требования приведет к отклонению приложения Apple.

Причина: теперь используется папка «Документы»для синхронизации с iCloud.iCloud выполняет синхронизацию каждые несколько минут, и если бы нам нужно, чтобы мегабайты файлов, сгенерированных нашим приложением, сохранялись в папке «Документы», он смешивался с собственными синхронизированными файлами iCloud пользователя.

Обновление MediaDirectory.m файлы с этим новым кодом для безопасности:

+ (NSString *) mediaPathForFileName:(NSString *) fileName
{   
    NSArray *directoryPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    NSString *cachesDirectory = [directoryPaths objectAtIndex:0];
    NSString *filePath = [NSString stringWithFormat:@"%@/%@", cachesDirectory, fileName];

    return filePath;
}

+ (BOOL)addSkipBackupAttributeToFile:(NSString *) fileName
{
    NSArray *directoryPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    NSString *cachesDirectory = [directoryPaths objectAtIndex:0];
    NSString *filePathStr = [NSString stringWithFormat:@"%@/%@", cachesDirectory, fileName];

    const char* filePath = [filePathStr fileSystemRepresentation];

    const char* attrName = "com.apple.MobileBackup";
    u_int8_t attrValue = 1;

    int result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0);
    return result == 0;
}

Не забудьте пометить тот текстовый файл, который мы сгенерировали, с помощью атрибута пропуска резервного копирования, например, после создания файла:

[MediaDirectory addSkipBackupAttributeToFile:@"fileStatus.txt"];

У меня также была опечатка ранее, я сказал записать в файл "firstLaunch.txt", когда он должен был быть "fileStatus.txt" (плохие навыки копирования и вставки: P)

Оригинальный текст

Вы можете попробовать записать значение (например, «нет») в текстовый файл и сохранить его в папке «Песочница» приложения, когда пользователь нажимает кнопку «Больше не спрашивать».

В следующий раз, когда приложение загрузится, ваш контроллер представления прочитает значение из этого текстового файла и, если оно «нет», не будет отображать предупреждение.

Надеюсь, это поможет.

Написание однократного представления предупреждений пользовательского интерфейса

ОК, позвольте мне сначала объяснить процесс, который мы собираемся пройти:

1) Метод делегата приложения didFinishLaunchingWithOption является методомкоторый вызывается при запуске приложения.

2) Этот метод вызывается только один раз при запуске приложения, поэтому именно здесь мы создаем текстовый файл, и мы записываем наш статус представления оповещения: "показать снова "или" не показывать снова "для UIAlertView

3) Мы собираемся вызвать представление предупреждений в методе viewDidLoad вашего UIViewController.Однако мы только отображаем этот UIAlertView, ЕСЛИ значение в нашем текстовом файле НЕ «больше не показывать».Если значение в текстовом файле «показать снова», мы показываем UIAlertView, если это «не показывать снова», мы не показываем UIAlertView, имеет смысл?

(Эти значения толькоСтрока, вы можете установить любое значение, которое вы хотите, я использую только эти случайные значения для демонстрации).

Правильно, теперь мы получили общий процесс, давайте реализуем его.

Код

В вашем заголовочном файле AppDelegate.h:

@interface MyAppDelegate : NSObject
{
    ...
    bool isFirstLaunch;
}

Теперь в вашем файле реализации AppDelegate.m:

// -------------------------------------------------------------------------------------
// I wrote a helper class called "MediaDirectory" that returns me the path to a file
// in the Documents directory of the application sandbox.
// Each application has a copy of the Documents directory so you can safely
// assume this directory will always exist.
//
// This class has been very useful for me, hope you find it useful too.
//
// DOWNLOAD THE FILES AT: 
// 
// http://www.chewedon.com/classes/MediaDirectory.h
// http://www.chewedon.com/classes/MediaDirectory.m
// -------------------------------------------------------------------------------------

#import <Foundation/NSFileManager.h>
#import <Foundation/NSFileHandle.h>
#import "MediaDirectory.h"

-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    ...

    NSString *fileStatus = nil;

    // Here, the NSFileManager defaultManager fileExistsAtPath method needs a path to 
    // the file in the Document directory, to get this path, use the static method from
    // my MediaDirectory class and pass it the name of the file.
    // I called it "fileStatus.txt" 
    //
    // We're checking if the file exist in the Documents directory or not. 
    // If it does not exist then we create the text file and pass it the
    // value "show again", otherwise we do nothing.
    // (We don't want to overwrite the value everytime the app starts)
    if([[NSFileManager defaultManager] fileExistsAtPath:[MediaDirectory mediaPathForFileName:@"fileStatus.txt"]] == NO)
    {            
        // prepare fileStatus.txt by setting "show again" into our string
        // we will write this string into the text file later
        fileStatus = [[NSString alloc] initWithString:@"show again"];

        // now we write the value "show again" so that the UIAlertView will show
        // when it checks for the value, until the user clicks on no and we set
        // this value to "don't show again" later in another piece of code
        [fileStatus writeToFile:[MediaDirectory mediaPathForFileName:@"fileStatus.txt"] 
                      atomically:YES 
                        encoding:NSUTF8StringEncoding 
                           error:nil];
    }

    [fileStatus release];

    ...

    // rest of your didFinishLaunchingWithOptions method
    [window addSubview:[viewController view]];
    [self.window makeKeyAndVisible];
    [self initGlobals];

    return YES;
}

Теперь в вашем классе UIViewController нам нужно сделатьэтот класс соответствует протоколу UIAlertView.Мы собираемся использовать один из методов делегата, который сообщает нам, когда нажимается кнопка в UIAlertView.

@interface MyViewController : UIViewController <UIAlertViewDelegate>
{
   ...
}

В нашем файле реализации (файл MyViewController.m) мы проверяем значение, хранящееся в текстовом файле.перед отображением UIAlertView.

#import "MediaDirectory.h"
#import <Foundation/NSFileManager.h>
#import <Foundation/NSFileHandle.h>

-(void)viewDidLoad
{   
    ...

    BOOL shouldShowAlert = false; 
    NSString *fileStatus = nil;

    // check if the file exists in the Documents directory and read its value
    // if it does. If the value read from file is "show again",
    // we bring up a UIAlertView
    if([[NSFileManager defaultManager] fileExistsAtPath:[MediaDirectory mediaPathForFileName:@"fileStatus.txt"]] == YES)
    {
        fileStatus = [[NSMutableString alloc] initWithContentsOfFile:[MediaDirectory mediaPathForFileName:@"fileStatus.txt"]
                                                             encoding:NSUTF8StringEncoding
                                                                error:nil];

        if([fileStatus isEqualToString:@"show again"] == YES)
        {
            shouldShowAlert = true;
        }
        else if([fileStatus isEqualToString:@"don't show again"] == YES)
        {
            shouldShowAlert = false;
        }
    }

    if(shouldShowAlert == true)
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"My Alert View Title" 
                                                    message:@"my message" 
                                                   delegate:self 
                                          cancelButtonTitle:@"OK" 
                                          otherButtonTitles:@"Don't Show Again", nil];

        // we set a tag for this UIAlertView to distinguish between this UIAlertView
        // and other UIAlertView in case there are any.
        // I use a value of 10, you can use any value but make sure it is unique
        [alert setTag:10];

        [alert show];
        [alert release];
    }
}

Теперь перейдем к последней части, где мы обрабатываем, какую кнопку пользователь нажал для UIAlertView.

Где-то в файле MyViewController.m, напишите этоМетод делегата:

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    // making sure its the UIAlertView we want
    if([alertView tag] == 10)
    {
        // By default, the "cancel" button has an index of 0
        // and the next button would have a index of 1
        // In our case, we set the first button is "OK"
        // and "Don't Show Again" as second button 
        if(buttonIndex == 1)
        {
            NSString *fileStatus = [[NSString alloc] initWithString:@"don't show again"];

            [fileStatus writeToFile:[MediaDirectory mediaPathForFileName:@"fileStatus.txt"] 
                  atomically:YES 
                    encoding:NSUTF8StringEncoding 
                       error:nil];   

            [fileStatus release];
        }
    }
}

Надеюсь, я ничего не пропустил, дайте мне знать, работает ли он или нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...