2016-12-12 2 views
0

Mon application a été refusée par Apple car elle ne peut pas se connecter à un autre appareil exécutant iOS 10.1.1 sur une connexion Wi-Fi connectée à un réseau IPv6.
Lorsque j'appuie sur connecter, l'application continue de rechercher des invités et aucune autre action de l'utilisateur n'est générée.
J'utilise la connectivité multi-homologue et je n'ai jamais testé mon application connectée à un IPv6 (c'est ma première version). Mais l'application fonctionne très bien sans avoir aucune connexion ou être connecté au réseau IPv4.Problème de connexion multipeer avec ipv6 n'obtenez pas d'invitation

Je ne sais pas pourquoi l'application est en cours d'exécution et se connecte très bien en utilisant l'IPv4 et ne se connecte pas à un pair si l'iPad est connecté à un réseau IPv6. Ma question: Est-il possible d'utiliser la connectivité multi-homologue avec IPv6 pour qu'Apple puisse approuver l'application ou comment gérer ce problème?

Voici mon code, peut-être que c'est quelque chose qui ne va pas.

@interface ConnectionManageriOS7() <MCSessionDelegate, MCBrowserViewControllerDelegate> 
{ 
    UILocalNotification *_expireNotification; 
    UIBackgroundTaskIdentifier _taskId; 
} 

@property (nonatomic, strong) MCSession *session; 
@property (nonatomic, strong) MCPeerID *localPeerID; 

@property (nonatomic, strong) MCBrowserViewController *browserVC; 
@property (nonatomic, strong) MCAdvertiserAssistant *advertiser; 

@end 

static ConnectionManageriOS7 *_manager = nil; 

@implementation ConnectionManageriOS7 

+ (ConnectionManageriOS7 *)connectManager { 

    @synchronized([ConnectionManageriOS7 class]){ 

     if (_manager == nil) { 
      _manager = [[ConnectionManageriOS7 alloc] init]; 
     } 
     return _manager; 
    } 
    return nil; 
} 

- (id)init { 

    self = [super init]; 
    if (self) { 
     [self setupSessionAndAdvertiser]; 
    } 
    return self; 
} 

- (void)setupSessionAndAdvertiser { 

    _localPeerID = [[MCPeerID alloc] initWithDisplayName:[UIDevice currentDevice].name];; 
    _session = [[MCSession alloc] initWithPeer:_localPeerID]; 
    _session.delegate = self; 

} 

- (void)connectWithDelegate:(id)delegate { 

    _delegate = delegate; 
    if (_session.connectedPeers.count) { 
     if ([_delegate respondsToSelector:@selector(didConntectedWithManager:)]) { 
      [_delegate didConntectedWithManager:self]; 
     } 
    } else { 
     if (_advertiser == nil) { 
      _advertiser = [[MCAdvertiserAssistant alloc] initWithServiceType:VISUS_Service 
                   discoveryInfo:nil 
                    session:_session]; 

      _isConnected = NO; 

      [_advertiser start]; 
     } 
     if (_browserVC == nil) { 

      _browserVC = [[MCBrowserViewController alloc] initWithServiceType:VISUS_Service session:_session]; 
      _browserVC.delegate = self; 

     } 

     [(UIViewController *)delegate presentViewController:_browserVC 
                animated:YES completion:nil]; 
    } 
} 

- (void)sendMessage:(NSString *)message { 

    NSData *textData = [message dataUsingEncoding:NSASCIIStringEncoding]; 
    NSLog(@"Send Data: %@", message); 
    NSError *error = nil; 
    [_session sendData:textData 
       toPeers:_session.connectedPeers 
       withMode:MCSessionSendDataReliable 
       error:&error]; 

    if (error) { 
     //   
     [self session:_session peer:nil didChangeState:MCSessionStateNotConnected]; 
     NSLog(@"error %@", error.userInfo); 
    } 
} 

- (void)stopService { 

    NSLog(@"Stop Service"); 

    [_advertiser stop]; 
    _advertiser = nil; 

    _browserVC = nil; 
} 

#pragma marks - 
#pragma marks MCBrowserViewControllerDelegate 
- (void) dismissBrowserVC{ 
    [_browserVC dismissViewControllerAnimated:YES completion:nil]; 
} 
// Notifies the delegate, when the user taps the done button 
- (void)browserViewControllerDidFinish:(MCBrowserViewController *)browserViewController { 

    if ([_delegate respondsToSelector:@selector(didConntectedWithManager:)]) { 
     [_delegate didConntectedWithManager:self]; 
    } 

    [self dismissBrowserVC]; 
} 

// Notifies delegate that the user taps the cancel button. 
- (void)browserViewControllerWasCancelled:(MCBrowserViewController *)browserViewController{ 
    if (_browserVC == nil) { 
     [browserViewController dismissViewControllerAnimated:YES completion:nil]; 
    }else { 
     [self dismissBrowserVC]; 
    } 
} 

#pragma marks - 
#pragma marks MCBrowserViewControllerDelegate 

- (void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state { 

    if (state != MCSessionStateConnecting) { 
     if (state == MCSessionStateConnected) { 

      _isConnected = true; 
      if ([_delegate respondsToSelector:@selector(willConntectedWithManager:)]) { 
       [_delegate willConntectedWithManager:self]; 
      } 
     } 
     else { 

      _isConnected = false; 
      [self stopService]; 
      if ([_delegate respondsToSelector:@selector(didDisconntectedWithManager:)]) { 
       [_delegate didDisconntectedWithManager:self]; 
      } 
     } 

    } 

} 

// Received data from remote peer 
- (void)session:(MCSession *)session didReceiveData:(NSData *)data fromPeer:(MCPeerID *)peerID{ 
    // Decode data back to NSString 

    NSString *message = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 

    NSLog(@"Receive Data: %@", message); 

    // append message to text box: 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     if ([_delegate respondsToSelector:@selector(connectionManager:receivedString:)]) { 
      [_delegate connectionManager:self receivedString:message]; 
     } 
    }); 
} 

- (void)session:(MCSession *)session didFinishReceivingResourceWithName:(NSString *)resourceName fromPeer:(MCPeerID *)peerID atURL:(NSURL *)localURL withError:(NSError *)error { 

    _isConnected = false; 
    [self stopService]; 
    NSLog(@"----- Error ----- %@", error.localizedDescription); 

} 

// Received a byte stream from remote peer 
- (void)session:(MCSession *)session didReceiveStream:(NSInputStream *)stream withName:(NSString *)streamName fromPeer:(MCPeerID *)peerID { 

} 

// Start receiving a resource from remote peer 
- (void)session:(MCSession *)session didStartReceivingResourceWithName:(NSString *)resourceName fromPeer:(MCPeerID *)peerID withProgress:(NSProgress *)progress { 

} 

- (void) session:(MCSession *)session didReceiveCertificate:(NSArray *)certificate fromPeer:(MCPeerID *)peerID certificateHandler:(void (^)(BOOL accept))certificateHandler 
{ 
    certificateHandler(YES); 
} 


- (void) createExpireNotification 
{ 
    [self killExpireNotification]; 

    if (_session.connectedPeers.count != 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]; 
     _expireNotification = n; 
     _expireNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:msgTime]; 
     _expireNotification.alertBody = @"Bluetooth Connectivity is about to disconnect. Open the app to resume Test"; 
     _expireNotification.soundName = UILocalNotificationDefaultSoundName; 
     _expireNotification.applicationIconBadgeNumber = 1; 

     [UIApplication.sharedApplication scheduleLocalNotification:_expireNotification]; 
    } 
} 

- (void) killExpireNotification 
{ 
    if (_expireNotification != nil) 
    { 
     [UIApplication.sharedApplication cancelLocalNotification:_expireNotification]; 
     _expireNotification = nil; 
    } 
} 

- (void)bacgroundHandling { 

    _taskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^ 
       { 
        [self stopService]; 
        [[UIApplication sharedApplication] endBackgroundTask:_taskId]; 
        _taskId = UIBackgroundTaskInvalid; 
       }]; 
    [self createExpireNotification]; 

} 

- (void)advertiser:(MCNearbyServiceAdvertiser *)advertiser didReceiveInvitationFromPeer:(MCPeerID *)peerID withContext:(NSData *)context invitationHandler:(void(^)(BOOL accept, MCSession *session))invitationHandler 
{ 

    // http://down.vcnc.co.kr/WWDC_2013/Video/708.pdf -- wwdc tutorial, this part is towards the end (p119) 

    // self.arrayInvitationHandler = [NSArray arrayWithObject:[invitationHandler copy]]; 
    // ask the user 
    UIAlertView *alertView = [[UIAlertView alloc] 
           initWithTitle:peerID.displayName 
           message:@"Would like to create a session with you" 
           delegate:self 
           cancelButtonTitle:@"Decline" otherButtonTitles:@"Accept", nil]; 
    [alertView show]; 


} 

- (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex 
{ 
    // retrieve the invitationHandler and check whether the user accepted or declined the invitation... 

    BOOL accept = (buttonIndex != alertView.cancelButtonIndex) ? YES : NO; 

    // respond 
    if(accept) { 
//  void (^invitationHandler)(BOOL, MCSession *) = [self.arrayInvitationHandler objectAtIndex:0]; 
//  invitationHandler(accept, self.mySession); 
    } 
    else 
    { 
     NSLog(@"Session disallowed"); 
    } 
} 

- (void)terminate { 

    [self killExpireNotification]; 
    [self stopService]; 
} 
@end 

Répondre

0

J'ai résolu le problème. Pour tout le monde avec un problème simulaire:
Ce n'était pas un problème avec IPv6, c'est une question d'utilisation de la connectivité Multipeer. Dans mon cas, j'ai essayé la connexion IPv6 avec un iPad et un simulateur. Et j'ai utilisé mon Macbook pour créer un nat64 network. Et la raison pour laquelle le simulateur et l'iPad ne se sont jamais vus le fait qu'ils n'étaient pas connectés au même réseau wifi.
Solution:
Juste prendre pour tester deux iPads et utiliser votre mac comme 0point d'accès nat64 network.