Watchkit,带WatchKit扩展的openParentApplication

时间:2015-08-01 16:40:10

标签: watchkit appdelegate apple-watch background-task

第一次不起作用“Null”(在iPhone中打开App之前)

有些时候不起作用,但我想要一个循环或计时器来重复这个获取结果的请求:

这是我的代码

- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *))reply
{
    // Temporary fix, I hope.
    // --------------------
    __block UIBackgroundTaskIdentifier bogusWorkaroundTask;
    bogusWorkaroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
        [[UIApplication sharedApplication] endBackgroundTask:bogusWorkaroundTask];
    }];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [[UIApplication sharedApplication] endBackgroundTask:bogusWorkaroundTask];
    });
    // --------------------

    __block UIBackgroundTaskIdentifier realBackgroundTask;
    realBackgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
        reply(nil);
        [[UIApplication sharedApplication] endBackgroundTask:realBackgroundTask];
    }];

    // Kick off a network request, heavy processing work, etc.

    // Return any data you need to, obviously.
    // reply(nil);
    reply(@{@"Confirmation" : @"Text was received."});

    [[UIApplication sharedApplication] endBackgroundTask:realBackgroundTask];

    //  NSLog(@"User Info: %@", userInfo);




}

观看应用代码

- (void)willActivate {
    // This method is called when watch view controller is about to be visible to user
    [super willActivate];




    NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:@"MyCamande", @"OK", nil];

    [InterfaceController openParentApplication:dictionary reply:^(NSDictionary *replyInfo, NSError *error) {
        NSLog(@"Reply received by Watch app: %@", replyInfo);
    }];

}

怎样才能回忆起最后的结果

2 个答案:

答案 0 :(得分:1)

好吧,我不建议您使用与观看本身的网络操作相关的任何内容。首先是因为Apple出于显而易见的原因不建议这样做。直接在手表上执行的唯一网络是加载图像。

我一直在努力开展网络运营并观察一周,并得出结论,现在最稳定的方式并不明显。

主要问题是WKInterfaceController.openParentApplication(...)无法正常工作。人们不能要求打开iPhone应用程序并按原样回复响应。有很多解决方案声明在- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *))reply中创建背景线程可以正常工作,但实际上并没有。问题是此方法必须立即发送reply(...);。即使创建同步请求也无济于事,您将继续收到“错误-2 iPhone应用程序没有回复...”,就像我们的10次一样。

所以,我的解决方案如下:

您实施:

func requestUserToken() {
        WKInterfaceController.openParentApplication(["request" : "token"], reply: responseParser)
    }

并解析对iPhone没有响应时可能发生的错误的响应。

在iOS端

- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *))reply
{


    __block UIBackgroundTaskIdentifier watchKitHandler;
    watchKitHandler = [[UIApplication sharedApplication] beginBackgroundTaskWithName:@"backgroundTask"
                                                                   expirationHandler:^{
                                                                       watchKitHandler = UIBackgroundTaskInvalid;
                                                                   }];

    NSString *request = userInfo[@"request"];

    if ([request isEqualToString:@"token"])
    {
        reply(@{@"token" : @"OK"});

        [PSWatchNetworkOperations.shared loginUser];
    } 

    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];
    } );
}

此代码只创建一个强制iPhone发送网络请求的后台线程。让我们假设你的iPhone应用程序中有一个特殊的类可以发送这些请求并发送回答。目前,这只能使用App Groups来完成。因此,您必须为应用程序和watchkit扩展创建一个应用程序组。之后,我建议您使用MMWormhole来建立应用和扩展程序之间的通信。手册非常自我解释。

现在这一切都是重点。您必须实现向服务器发送请求并通过虫洞发送响应。我使用ReactiveCocoa,因此我的代码中的示例如下:

- (void)fetchShoppingLists
{
    RACSignal *signal = [PSHTTPClient.sharedAPIClient rac_GET:@"list/my" parameters:@{@"limit":@20, @"offset":@0} resultClass:PSShoppingListsModel.class];
    [signal subscribeNext:^(PSShoppingListsModel* shoppingLists) {
        [self.wormHole passMessageObject:shoppingLists identifier:@"shoppingLists"];
    }];

    [signal subscribeError:^(NSError *error) {
        [self.wormHole passMessageObject:error identifier:@"error"];
    }];
}

如您所见,我发送回响应对象或错误。请注意,您通过虫洞发送的所有内容都应与NSCoding兼容。

现在观看你可能会解析这样的反应:

override func awakeWithContext(context: AnyObject?) {
    super.awakeWithContext(context)

    PSWatchOperations.sharedInstance.requestUserToken()

    PSWatchOperations.sharedInstance.wormhole.listenForMessageWithIdentifier("token", listener: { (messageObject) -> Void in
        // parse message object here
        }
    })

}

所以,得出结论。您向父应用程序发送请求以从后台唤醒并启动异步操作。立即发送回复()。当您收到来自操作发送通知的答案时,您已收到回复。同时在你的watchExtension中听取回应。

对不起,这是很多文字,但我只是希望它有助于保持一个人的屁股很酷,因为我已经花了很多精力。

答案 1 :(得分:0)

可能您可以尝试更清楚地解释确切的问题。但是你可能想要做的一件事是在awakeWithContext中调用openParentApp:而不是willActivate。