39 votes

Est-il possible de faire la distinction entre le verrouillage de l'appareil et l'envoi d'une application d'arrière-plan?

J'ai une application qui a besoin de faire quelque chose quand il est envoyé à l'arrière-plan en utilisant le bouton Home et autre chose lorsque l'appareil est verrouillé à l'aide de haut bouton matériel. Le niveau moyen de résoudre ces exigences sont les notifications et délégué méthodes envoyé par UIApplication. Sur iOS 4, ils ressemblent à ceci:

// Pressing the home button
Will resign active.
Did enter background.
// Tapping app icon on Springboard
Will enter foreground.
Did become active.

// Pressing the lock button
Will resign active.
// Unlocking the device
Did become active.

En d'autres termes, il est assez facile de dire entre le verrouillage et la semi-finition. Sur iOS 5 le comportement a changé:

// Pressing the home button
Will resign active.
Did enter background.
// Tapping app icon on Springboard
Will enter foreground.
Did become active.

// Pressing the lock button
Will resign active.
Did enter background.
// Unlocking the device
Will enter foreground.
Did become active.

Notez que l' didEnterBackground et willEnterForeground notifications sont maintenant envoyés, même quand les (dé)verrouillage de l'appareil, le rendant impossible à dire entre le verrouillage et la semi-finition. Ce changement est-il documenté quelque part? Est-ce une régression? Vous connaissez une autre façon de distinguer les deux cas?

29voto

iOS 6

Dans mes tests préliminaires via le simulateur, la vérification de l'état de l'application avec

[[UIApplication sharedApplication] applicationState]

dans les deux

- (void)applicationWillEnterForeground:(UIApplication *)application

- (void)applicationDidEnterBackground:(UIApplication *)application

permet de faire la différence entre un appel pour verrouiller l'appareil et juste revenir à l'écran d'accueil. Un verrouillage de l'écran sera de retour 1 (UIApplicationStateInactive), tandis qu'un bouton de la maison de la presse vous inscrire en tant que 2 (UIApplicationStateBackground).

Il semble cohérent et devrait fonctionner sur un appareil iOS comme fiable comme il le fait dans le simulateur.

iOS 7

L'iOS 6 méthode ne fonctionne plus sous iOS 7. Pour ce faire, maintenant, vous avez à utiliser CFNotificationCenter écouter un darwin notification (libellé: com.apple.tremplin.lockcomplete). Vous pouvez trouver le dépôt github avec l'exemple de projet ici: https://github.com/binarydev/ios-home-vs-lock-button

Crédit pour l'iOS 7 fixer le sort de wqq

7voto

chown Points 25161

J'ai regardé dans ce tout à fait un peu donc j'aimerais avoir tort ici, si quelqu'un sait quelque chose je n'en ai pas, mais techniquement, il n'est pas documenté de façon de faire la différence entre le verrouillage de l'appareil, et de les envoyer à l'arrière-plan.

Une chose que vous pouvez vérifier cependant, est l' UIApplicationState au cours de la transition, du premier à l'arrière-plan. Le verrouillage d'un appareil donnera UIApplicationStateInactive et le déplacement de l'App en arrière plan donnera UIApplicationStateBackground. Mais, puisque ce comportement n'est pas officiellement documenté, il peut changer dans le futur.

Un exemple de base:

- (void)applicationDidEnterBackground:(UIApplication *)application {
    UIApplicationState state = [[UIApplication sharedApplication] applicationState];
    NSLog(@"Device state: %@", state);
    switch (state) {
        case UIApplicationStateActive:
            /* ... */
            break;
        case UIApplicationStateInactive:
            /* Device was/is locked  */
            break;
        case UIApplicationStateBackground:
            /* User pressed home button or opened another App (from an alert/email/etc) */
            break;
    }
}

UIApplicationState - La gestion d'une application

typedef enum {
    UIApplicationStateActive,   
    UIApplicationStateInactive,
    UIApplicationStateBackground
}

UIApplicationState

Constantes

UIApplicationStateActive - L'application est en cours d'exécution dans le premier plan et actuellement de recevoir des événements. Disponible dans iOS 4.0 et versions ultérieures.

UIApplicationStateInactive - L'application est en cours d'exécution dans le premier plan, mais n'est pas de recevoir des événements. Cela peut arriver suite d'une interruption ou parce que l'application est en phase de transition ou de l'arrière-plan.

UIApplicationStateBackground - L'application est cours d'exécution en arrière-plan.


Selon le UIApplicationDelegate Protocole de Référence:

applicationWillResignActive:
didEnterBackground:
// ...
willEnterForeground:
applicationDidBecomeActive:

sont les seules méthodes que jamais appelés dans les deux situations.


Selon l' iOS 4.3 d'iOS 5.0 API Diff, ce sont les SEULES modifications concernant l' UIApplication ou UIApplicationDelegate, donc je ne pouvais pas trouver où ils ont documenté l'un de ces notification des modifications:

UIApplication.h
Added -[UIApplication setNewsstandIconImage:]
Added UIApplication.userInterfaceLayoutDirection
Added UIApplicationDelegate.window
Added UIApplication(UINewsstand)
Added UIApplicationLaunchOptionsNewsstandDownloadsKey
Added UIRemoteNotificationTypeNewsstandContentAvailability
Added UIUserInterfaceLayoutDirection
Added UIUserInterfaceLayoutDirectionLeftToRight
Added UIUserInterfaceLayoutDirectionRightToLeft

3voto

snowdragon Points 458

C'est plus une solution de contournement/hack, mais selon mon expérience, c'est très fiable. Lorsque l'appareil est en écran de verrouillage (pas seulement du bouton home-ed, si c'est un mot :)) - lié au réseau (UDP) les sockets sont cassés. J'ai été en utilisant GCDAsyncUDPSocket (également AsyncUDPSocket avant) et ils à la fois le feu un réseau/une erreur broken pipe de façon fiable lorsque l'appareil est éteint. Dans mon cas, j'ai besoin de la socket UDP de toute façon, pour d'autres applications, il peut être un peu malodorante, cependant, il suffit de liaison/d'écoute sur une socket UDP sans aucune action n'est pas trop grave si vous avez vraiment besoin de faire la différence.

Cette note ne sera [autodestruction]; est de 5 minutes (Apple ne trouverez pas).

1voto

zoul Points 51637

Il y a un thread sur ce problème sur les Forums des Développeurs Apple (développeurs enregistrés seulement, désolé). L'essentiel est que le nouveau comportement est par la conception. Il y a des demandes pour une nouvelle API fonctionnalité de distinguer entre les deux cas d'utilisation, mais rien encore.

1voto

Florian Points 1459

Voici ce que l'iOS d'Apple Guide de Programmation dit:

En appuyant sur le bouton marche/Veille est un autre type d'interruption qui les causes de votre application pour être désactivé temporairement. Lorsque l'utilisateur appuie sur ce bouton, le système désactive les événements tactiles, se déplace à l'application de la arrière-plan, mais définit la valeur de l'application applicationState propriété pour UIApplicationStateInactive (par opposition à UIApplicationStateBackground), et enfin verrouille l'écran.

http://developer.apple.com/library/ios/#DOCUMENTATION/iPhone/conceptual/iPhoneOSProgrammingGuide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html

Donc, vous devriez vérifier l' UIApplications' applicationState de la propriété en applicationDidEnterBackground:. Si c'est UIApplicationStateBackground l'utilisateur a appuyé sur le bouton home. Mais si c'est UIApplicationStateInactive l'utilisateur verrouillé l'appareil.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X