Mise à JOUR Après l'aide d'un ticket de support pour Apple, ils ont confirmé que l'appel sendData trop souvent et avec trop de données peut provoquer des déconnexions.
J'ai eu des déconnexions lors de la frappe des points de rupture et lorsque la semi-finition. Depuis les points de rupture ne se fera pas sur l'app store, vous devez gérer la semi-finition du cas par le début d'une tâche en arrière-plan lorsque votre application est sur le point d'entrer dans le fond. Puis à la fin de cette tâche lorsque votre application est de retour au premier plan. Sur iOS 7 ce qui donne environ 3 minutes de fond qui est mieux que rien.
Une autre stratégie serait de planifier une notification locale pour peut-être 15 secondes avant que votre arrière-plan de l'expiration de la durée en utilisant [[UIApplication sharedApplication] backgroundTimeRemaining]
, de cette façon, vous pouvez apporter à l'utilisateur de retourner dans l'application avant de la suspend et le multi pairs cadre doit être à l'arrêt. Peut-être que la notification locale permettrait de les avertir que leur session va expirer dans les 10 secondes, ou quelque chose...
Si la tâche en arrière-plan expire et l'application est toujours en arrière-plan, vous avez à abattre tout ce qui concerne le multi-peer connectivité, sinon vous obtiendrez des plantages.
- (void) createExpireNotification
{
[self killExpireNotification];
if (self.connectedPeerCount != 0) // if peers connected, setup kill switch
{
NSTimeInterval gracePeriod = 20.0f;
// create notification that will get the user back into the app when the background process time is about to expire
NSTimeInterval msgTime = UIApplication.sharedApplication.backgroundTimeRemaining - gracePeriod;
UILocalNotification* n = [[UILocalNotification alloc] init];
self.expireNotification = n;
self.expireNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:msgTime];
self.expireNotification.alertBody = TR(@"Text_MultiPeerIsAboutToExpire");
self.expireNotification.soundName = UILocalNotificationDefaultSoundName;
self.expireNotification.applicationIconBadgeNumber = 1;
[UIApplication.sharedApplication scheduleLocalNotification:self.expireNotification];
}
}
- (void) killExpireNotification
{
if (self.expireNotification != nil)
{
[UIApplication.sharedApplication cancelLocalNotification:self.expireNotification];
self.expireNotification = nil;
}
}
- (void) applicationWillEnterBackground
{
self.taskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^
{
[self shutdownMultiPeerStuff];
[[UIApplication sharedApplication] endBackgroundTask:self.taskId];
self.taskId = UIBackgroundTaskInvalid;
}];
[self createExpireNotification];
}
- (void) applicationWillEnterForeground
{
[self killExpireNotification];
if (self.taskId != UIBackgroundTaskInvalid)
{
[[UIApplication sharedApplication] endBackgroundTask:self.taskId];
self.taskId = UIBackgroundTaskInvalid;
}
}
- (void) applicationWillTerminate
{
[self killExpireNotification];
[self stop]; // shutdown multi-peer
}
Vous voudrez aussi de ce gestionnaire dans votre MCSession délégué en raison de bug Apple:
- (void) session:(MCSession*)session didReceiveCertificate:(NSArray*)certificate fromPeer:(MCPeerID*)peerID certificateHandler:(void (^)(BOOL accept))certificateHandler
{
if (certificateHandler != nil) { certificateHandler(YES); }
}