Подтвердить что ты не робот

Принудительное приложение iphone для программной перезагрузки

Я пытаюсь заставить приложение для iPhone перезапускаться программно при нажатии кнопки "Выход".

Кто-нибудь получил образец кода для обмена? Я прочитал, что это возможно, изменив файл main.m, но не смог найти код, связанный с этим.

Любая помощь будет оценена.

4b9b3361

Ответ 1

Прежде всего, хотя можно убить приложение, это запрещено Apple, и оно будет отклонено. Даже если он не был отклонен, невозможно перезапустить приложение после его убийства. Вам просто нужно найти способ reset вашего приложения через ваш код, как сказал Jason Coco. Это может быть больше работы, но не стоит отказываться от Apple.

Ответ 2

Примечание:

Хотя на этот вопрос ответили как "невозможно", я думаю, что это правильный вопрос для нового разработчика iOS, и есть что-то, что они могут сделать, что, вероятно, они хотят.

Существует способ "перезапустить" ваше приложение с точки зрения пользователя, которое не перезапускается или не выходит из приложения iOS. Как указано в других ответах, приложение iOS никогда не должно явно выходить из него, потому что это запрещено в iOS.

Мой ответ:

Если вы хотите, чтобы ваше приложение возвращалось в состояние, в котором оно было запущено, это не на 100% возможно, но я объясню, как получить большую часть пути, который должен быть достаточным для всех допустимых целей.

Первое, что нужно сделать, это воссоздать контроллер корневого представления. Я рекомендую сделать это из метода в делегате приложения следующим образом:

- (void)resetAppToFirstController
{
    self.window.rootViewController = [[MyMainViewController alloc] initWithNibName:nil bundle:nil];
}

Во многих случаях этого будет достаточно, но любое приложение-состояние, которое у вас есть, также должно быть reset в этом методе. Например, выведите пользователя из системы, reset любое непостоянное состояние и аннулируйте (освободите) все объекты, которые вы можете. Этот метод также можно использовать для первоначального создания вашего первого контроллера вида с application:didFinishLaunchingWithOptions.

Классы Framework и Singletons:

Вы не сможете полностью reset состояние любых фреймворческих синглетонов или экземпляров для каждого приложения, например:

[UIApplication sharedApplication];
[NSNotificationCenter defaultCenter];
[NSUserDefaults standardUserDefaults];
[UIScreen screens];
// etc...

Это, вероятно, отлично, так как вы не должны сохранять какое-либо непостоянное состояние в них в любом случае (кроме NSNotificationCenter, но все зарегистрированные наблюдатели должны были быть удалены при выпуске объектов). Если вы хотите инициализировать или reset любое состояние каркаса, вы можете сделать это в том же методе resetAppToFirstController. Во всяком случае, не нужно будет воссоздавать их или объект window.

Если у вас есть какие-либо из ваших собственных синглонов, вы можете воссоздать их, сохранив их в классе singleton-holder (который сам по себе является реальным синглом). Концептуально это простой одноэлементный класс со свойствами для каждого из ваших других синглетонов и метод reset для аннулирования и освобождения всех. Ваши другие синглтоны должны использовать этот класс (вместо статической или глобальной переменной) для хранения экземпляров singleton. Будьте осторожны, если вы используете какие-либо сторонние библиотеки, так как они могут также использовать синглтоны, и вам нужно будет обеспечить, чтобы они также использовали ваш сингл-держатель, чтобы вы могли reset их по мере необходимости. Я думаю, что этот метод является хорошей практикой в ​​любом случае, потому что в некоторых случаях (например, модульное тестирование) вам нужны объекты, которые обычно являются одиночными, чтобы уйти и повторно инициализировать до первозданного состояния. Тем не менее, вы не хотите связывать реализации singleton с вашим одноэлементным держателем, поэтому хорошим способом реализовать это является использование NSMutableDictionary в качестве ассоциированного объекта на [UIApplication sharedApplication] с именами одноэлементного класса в качестве ключей. Тем не менее, я немного отклоняюсь от темы, поскольку это более сложный метод, выходящий за рамки этого вопроса.


Вышеприведенное должно быть достаточным для "reset" вашего приложения в отношении пользователя. Вы даже можете снова отобразить заставку, если хотите, как ваш первый контроллер представления.

Ответ 3

попробуйте это, он работает для меня.

-(void)restart
{
    MyAppDelegate *appDelegate = (MyAppDelegate *)([UIApplication sharedApplication].delegate);
    [appDelegate.navigationController popToRootViewControllerAnimated:NO];
    UIViewController *topViewController = appDelegate.navigationController.topViewController;
    Class class = [topViewController class];
    NSString *nibName = topViewController.nibName;
    UIViewController *rootViewcontroller = (UIViewController *)([[class alloc] initWithNibName:nibName bundle:nil]);
    [appDelegate.navigationController.view removeFromSuperview];
    appDelegate.navigationController.viewControllers = [NSArray arrayWithObject:rootViewcontroller];
    [appDelegate.window addSubview:appDelegate.navigationController.view];
    [appDelegate.window makeKeyAndVisible];
}

Ответ 4

Objective-C:

exit(0);

Swift:

exit(0)

У меня есть это на двух живых приложениях, и они не были отклонены. Одно из моих приложений даже имеет эту строку кода как функцию на домашней странице моего приложения. Он расположен в верхнем правом углу, где кнопка Twitter находится в Твиттере. Поэтому не беспокойтесь о том, что Apple отвергнет, если это не похоже на неожиданный сбой.

введите описание изображения здесь

Ответ 5

Вот как вы можете это сделать на симуляторе, используя частный API:

    NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:@"%@://%@", scheme, endpointString]];

    Class pClass = NSClassFromString(@"BKSSystemService");
    id service = [[pClass alloc] init];

    SEL pSelector = NSSelectorFromString(@"openURL:application:options:clientPort:withResult:");
    NSMethodSignature *signature = [service methodSignatureForSelector:pSelector];
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
    invocation.target = service;
    NSString *app = @"com.apple.mobilesafari";
    [invocation setSelector:pSelector];
    [invocation setArgument:&URL atIndex:2];
    [invocation setArgument:&app atIndex:3];
    unsigned int i = [service performSelector:NSSelectorFromString(@"createClientPort")];
    [invocation setArgument:&i atIndex:5];
    [invocation invoke];
    exit(0);

Это также должно работать на jailbroken приложениях с соответствующими правами.

Для других приложений может использоваться простая страница html:

    NSString *format = @"https://dl.dropboxusercontent.com/s/rawt1ov4nbqh4yd/launchApp.html?scheme=%@&URL=%@";
    NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:format, scheme, endpointString]];
    [[UIApplication sharedApplication] openURL:URL];
    exit(0);

К сожалению, в этом случае необходимо подключение к Интернету.

Ответ 6

Я выхожу во время -applicationWillResignActive: если приложение находится на стартовом экране, и Apple приняло его на долгие годы. Для пользователя это не будет похоже на сбой. В следующий раз пользователь запустит приложение из значка. Дополнительная проверка, которая не выходит из приложения, если она была запущена сегодня, может быть полезна для пользователей в некоторых случаях.

- (void)applicationWillResignActive:(UIApplication *)application
{
    // called if phone-call comes in!
    if([gameController isGameFinished])
        exit(0);
}

Ответ 7

Поместите это в UIAlertAction, спрашивая пользователя "Сохранить и выйти". Он оживит выход (0), так что, по крайней мере, он выглядит запланированным.

- (void)saveAndQuit
{
    [UIView animateWithDuration:0.8 animations:^{
        self.window.alpha = 0.0; // fade out...
        // ... while pinching to a point
        self.window.transform = CGAffineTransformScale(
                CGAffineTransformMakeTranslation( 0, 0 ), 0.1, 0.1 );
    } completion:^(BOOL finished) {
        exit(0);
    }];
}