The UIApplicationDelegate in the iPhone App never called reply

后端 未结 3 508
予麋鹿
予麋鹿 2021-02-13 22:21

I am trying to launch my iPhone app from watch simulator using the below code :

WKInterfaceController subclass

[WKInterfaceController op         


        
相关标签:
3条回答
  • 2021-02-13 22:42

    I would like to add that it is important to start a background task in handleWatchKitExtensionRequest as specified in the documentation. This ensures that the main app on the iPhone is not suspended before it can send its reply. (Not initiating a background task does not cause a problem in the simulator or when the iPhone app is active. However, it causes a problem when the iPhone app is inactive.)

    Code in the app delegate of the main app on iPhone:

    - (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void ( ^)( NSDictionary * ))reply
    {
       __block UIBackgroundTaskIdentifier watchKitHandler;
       watchKitHandler = [[UIApplication sharedApplication] beginBackgroundTaskWithName:@"backgroundTask"
                                                                   expirationHandler:^{
                                                                     watchKitHandler = UIBackgroundTaskInvalid;
                                                                   }];
    
       if ( [[userInfo objectForKey:@"request"] isEqualToString:@"getData"] )
       {
          // get data
          // ...
          reply( data );
       }
    
       dispatch_after( dispatch_time( DISPATCH_TIME_NOW, (int64_t)NSEC_PER_SEC * 1 ), dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{
           [[UIApplication sharedApplication] endBackgroundTask:watchKitHandler];
        } );
    }
    
    0 讨论(0)
  • 2021-02-13 22:54

    Aside from just not calling the reply block, this can happen for at least a couple reasons:

    1. Your iPhone app crashed while it was processing the request and therefore was never able to call the reply block. Check that you are not accidentally putting nil into an NSMutableDictionary, as that will cause a crash.
    2. You are trying to put something that can't be serialized into a plist file into the replyInfo dictionary (hat tip to @duncan-babbage). If you need to pass an NSAttributedString or your custom object, make sure it conforms to NSCoding and do this:

    On the phone side build your reply dictionary:

    NSMutableDictionary *reply = [NSMutableDictionary new];
    MyCustomObject *myObject = <something you need to send>;
    reply[@"myKey"] = [NSKeyedArchiver archivedDataWithRootObject: myObject];
    NSAttributedString *myString = <some attributed string>;
    reply[@"otherKey"] = [NSKeyedArchiver archivedDataWithRootObject: myString];
    

    And unpack it back on the watch side:

    NSData *objectData = replyInfo[@"myKey"];
    MyCustomObject *myObject = [NSKeyedUnarchiver unarchiveObjectWithData: objectData];
    NSData *stringData = replyInfo[@"otherKey"];
    NSAttributedString *myString = [NSKeyedUnarchiver unarchiveObjectWithData: stringData];
    
    0 讨论(0)
  • 2021-02-13 22:54

    You need to call the reply block, even if you return nil. The following will resolve your error:

    - (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void(^)(NSDictionary *replyInfo))reply
    {
    NSLog(@"appdelegate handleWatchKitExtensionRequest");
    NSLog(@"NSDictionary: %@",userInfo);
    NSLog(@"replyInfo: %@",replyInfo);
    reply(nil);
    }
    

    See the Apple documentation for further information. You can also return an NSDictionary reply(myNSDictionary); with whatever information it would be useful to return to your Watchkit extension, although the dictionary can only contain information that can be serializable to a property list file, so for instance you can pass strings but you can't just pass a dictionary containing references to instances of your custom classes without packaging them up as NSData first.

    0 讨论(0)
提交回复
热议问题