Каков идеальный способ выйти из приложения IOS?

Приведенный ниже код работает, но содержит ошибку. Сценарий таков: я начинаю с входа в систему приложений. После успешного входа в систему приложение установит UserDefaults (UserId). После этого я могу перемещаться по представлениям приложения с сохраненным UserId. Как только я перехожу к настройкам и выходу из вкладки, это очистит UserId и перейдет в режим входа в систему.

ОШИБКА: когда я снова вхожу в приложение и нажимаю кнопку «Домой», чтобы перейти на рабочий стол iPhone, закрыть приложение и вернуться, чтобы открыть его снова, оно все еще сохраняет идентификатор пользователя. Итак, если я перейду к настройке и выйду из системы, это очистит UserId и не перейдет в режим входа в систему. Я не знаю почему.

Код:

- (IBAction)resetKeychain:(id)sender {

    UIActionSheet *actionSheet = [[UIActionSheet alloc] 
                 initWithTitle:@"Are you sure you want to logout?" 
                 delegate:self 
                 cancelButtonTitle:@"Cancel" 
                 destructiveButtonTitle:@"Logout"
                 otherButtonTitles:nil];
    actionSheet.actionSheetStyle = UIActionSheetStyleDefault;
    [actionSheet showFromTabBar:self.tabBarController.tabBar];
    [actionSheet release];

}

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    if (buttonIndex ==0) {
        //logout
        NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
        //delete user ID fro user Defaults
        [defaults setObject:nil forKey:@"UserId"];
        //redirect to login view

        NewClassMoonAppDelegate * appsDelegate =[[UIApplication sharedApplication] delegate];
        [appsDelegate.window addSubview:[appsDelegate.login view]];

    }
}

person Montaser El-sawy    schedule 31.01.2013    source источник
comment
Идеального решения не существует. Помните, лучшее — враг хорошего.   -  person Eric    schedule 31.01.2013


Ответы (3)


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

а) ваше значение @"UserID" не синхронизируется с NSUserDefaults, потому что вы не вызываете метод -synchronize. NSUserDefaults обновит свое хранилище ключей и значений в памяти, но не запишет его на диск, что означает, что оно потеряно в произвольное время.

б) Тот факт, что он не собирается в loginView, может быть связан с несколькими причинами, скорее всего, это уже подвид вашего UIWindow. Таким образом, вместо повторного использования свойства login в делегате приложения создайте новую переменную экземпляра View Controller и вместо этого установите ее как rootViewController.

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {

    if (buttonIndex == 0) {
        NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
        [defaults setObject:nil forKey:@"UserId"];
        [defaults synchronize];
        //redirect to login view

        NewClassMoonAppDelegate * appsDelegate =[[UIApplication sharedApplication] delegate];
        LoginViewController *login = [[LoginViewController alloc] initWithNibName...];
        [appsDelegate.window setRootViewController:nil];
        [appsDelegate.window setRootViewController:login];

    }
}
person max_    schedule 31.01.2013
comment
Привет, max_, твое решение отличное, но у меня есть сомнения, нужно ли мне удалять все остальные MVC из памяти, которую я загрузил, перед выходом из приложения? если нет, что происходит с этими MVC? останутся в памяти? как этот сценарий должен быть обработан? - person RockandRoll; 10.09.2014
comment
Любой из представленных rootViewController и сам rootViewController будет освобожден из памяти. Это не произойдет немедленно, так как вы можете сохранить ссылку в другом месте приложения или компилятор может быть не готов к этому. - person max_; 10.09.2014

Свифт:

Из ответа max_ с некоторыми изменениями:

let objectsToSave: [String] = [obj1, obj2, obj3]
for key in objectsToSave {
    NSUserDefaults.standardUserDefaults().removeObjectForKey(key)
}

 let appsDelegate = UIApplication.sharedApplication().delegate
 let storyboard = UIStoryboard(name: "MainStoryboard", bundle: nil)
 let newLoginVC: LoginViewController = storyboard.instantiateInitialViewController() as! LoginViewController
 appsDelegate?.window!!.rootViewController = nil
 appsDelegate?.window!!.rootViewController = newLoginVC

РЕДАКТИРОВАТЬ: Единственные изменения, которые я сделал, заключаются в том, что я инициализирую newLoginVC через раскадровки вместо initWitName.

person gabuchan    schedule 16.12.2015
comment
пожалуйста, объясните еще немного, почему это изменение и чего вы с ним достигаете. - person davejal; 16.12.2015
comment
Это решение работает для возврата к loginVC, однако контроллеры представления, которые были выделены для предыдущего пользовательского сеанса, не освобождаются при выходе из системы. Как мы можем освободить все контроллеры представления? - person Chris; 11.10.2018

Сделайте свойство контроллера UINavigation и синтезируйте его, и напишите ниже код на кнопке выхода

AppDelegate * appDelegateObj =[[UIApplication sharedApplication] delegate];
    login *loginObj = [[login alloc]initWithNibName:@"login" bundle:nil];
    [appDelegateObj.window setRootViewController:nil];
    navObj=[[UINavigationController alloc]initWithRootViewController:loginObj];
    [appDelegateObj.window setRootViewController:navObj];
person amar    schedule 06.04.2016
comment
Почему требуется UINavigationController? OP не представляет контроллер входа в стек навигации. Кроме этого, я не вижу никаких дополнений к другим уже опубликованным ответам. - person UditS; 06.04.2016