Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

openParentApplication:reply: error with asynchronous network call in containing app

I'm getting stuck with an error when using my Watchkit Application. When I launch it, I ask the containing iOS app to get some data from network. The problem is that I get an error saying the containing app never calls 'reply()' :o But looking at my code, it should call it.

I tried to debug every step from openParentApplication to the 'reply()' call, and it seems to work well =X

Here is my code in the Watchkit extension

- (void)initDiaporamasWithSuccess:(void (^)())success andFailure:(void (^)(NSError*))failure {
NSLog(@"Ask to load diapos");
__weak typeof(self) weakSelf = self;
[WKInterfaceController openParentApplication:@{@"watchKit": @"watchKit.initDiapos"} reply:^(NSDictionary *replyInfo, NSError *error) {
    if (error) {
        NSLog(@"%@", error);
        if (failure) {
            failure(error);
        }
        return;
    }

    NSLog(@"got items : %@", replyInfo[@"diapos"]);
    weakSelf.diaporamas = replyInfo[@"diapos"];
    [weakSelf setDiaporama:replyInfo[@"firstDiapo"] AtIndex:0];
    if (success) {
        success();
    }
}];

}

The result should be an NSDictionary containing an NSArray with some diaporamas basic informations, and an object (Diapo) containing the full informations of the first diaporama (e.g. self.diaporamas[0])

And here is the code in the containing app's AppDelegate :

- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *))reply {
// Maybe we could handle multiple watchKit extension calls that way ?
// Something like a key-value 'protocol' to run the right block of code
NSString *watchKitCall = userInfo[@"watchKit"];
NSLog(@"watchKit handled");

if ([watchKitCall isEqualToString:@"watchKit.initDiapos"]) {
    [AppDelegate watchInitialObjects:^(NSDictionary *info) {
        NSLog(@"Managed to get initial infos");
        reply(info);
    } failure:^(NSError *error) {
        NSLog(@"Fail : %@", error);
        reply(@{@"error": error});
    }];
}

}

+ (void) watchInitialObjects:(void (^)(NSDictionary *info))success failure:(void (^)(NSError *error))failure {
NSDictionary *parameters = @{@"site" : @(14), @"limit" : @(10)};
[AppDelegate  requestDiapoListWithParams:parameters success:^(NSArray *items) {
    if ([items count] == 0)
    {
        NSError *error = [NSError errorWithDomain:@"com.domain.app" code:404 userInfo:nil];
        failure(error);
        return;
    }

    Diapo *firstDiapo = [items firstObject];
    [AppDelegate requestDiapoDetailWithDiapo:firstDiapo success:^(Diapo *diapo) {
        if (!diapo)
        {
            NSError *error = [NSError errorWithDomain:@"com.domain.app" code:404 userInfo:nil];
            failure(error);
            return;
        }

        NSDictionary *result = @{
                                 @"firstDiapo" : diapo,
                                 @"diapos" : items
                                 };
        success(result);
    } failure:^(NSError *error) {
        failure(error);
    }];
} failure:^(NSError *error) {
    failure(error);
}];

}

In the watchKitHandler, I call watchInitialObjects to get the diaporamas array and the first diaporama's informations. In the watchInitialObjects, I make a first network call to get the array, and on success, I make an other network call to get the firs diaporama informations.

To make the calls and map the JSON into objects, I use RESTKit

I really don't get what could be the error =x

UPDATE

I forgot to write the error I get, here it is :

Error Domain=com.apple.watchkit.errors Code=2 "The UIApplicationDelegate in the iPhone App never called reply() in -[UIApplicationDelegate application:handleWatchKitExtensionRequest:reply:]" UserInfo=0x7fcb53e12830 {NSLocalizedDescription=The UIApplicationDelegate in the iPhone App never called reply() in -[UIApplicationDelegate application:handleWatchKitExtensionRequest:reply:]}

And I kept trying to know why I get this error, and I think I found it: It seems that there is a (very little) timeout to do the work in the containing app. But I mapped the JSON data I received directly in the containing app and then, send those custom objects in the reply(). But when I removed the mapping part, it worked well !

So...that's why I think that was the problem =X Does anybody could approve my thoughts or corrects me ?

like image 596
Bilkix Avatar asked Mar 19 '15 09:03

Bilkix


1 Answers

After hours of searching and testing different codes, I finally found my problem...and it's obvious when we read the Apple documentation about 'application:handleWatchKitExtensionRequest:reply:' seriously...

here is the answer : (it's in the documentation)

The contents of the dictionary must be serializable to a property list file.

Which means that objects can ONLY be dictionaries, arrays, strings, numbers (integer and float), dates, binary data, or Boolean values

...I feel dumb ><

like image 115
Bilkix Avatar answered Nov 11 '22 07:11

Bilkix