Какъв е идеалният начин да направите излизане от приложението за IOS?

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

ГРЕШКАТА: Когато вляза отново в приложението и щракна върху бутона за начало, за да отида на работния плот на iPhone и да затворя приложението, и се върна, за да го отворя отново, то все още съхранява UserId. Така че, ако отида до настройката и изляза, това ще изчисти 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 ще актуализира своето хранилище за ключ-стойност в паметта, но няма да го запише на диска, което означава, че е изгубено в произволен момент.

b) Фактът, че не отива към 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

Swift:

От отговора на 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 чрез Storyboards вместо 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