Watchkit 、带有 WatchKit 扩展的 openParentApplication

2024-02-18

第一次不行"Null"(在iPhone中打开应用程序之前)

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

这是我的代码

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

}

如何回忆才能得到最终结果


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

我一直在与网络操作作斗争,观察了大约一周并得出结论,目前最稳定的方法并不明显。

主要问题是WKInterfaceController.openParentApplication(...)不按预期工作。人们不能只是请求打开 iPhone 应用程序并按原样返回响应。有大量的解决方案指出在中创建后台线程- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *))reply本来可以很好地工作,但实际上却不然。问题是这个方法必须发送reply(...);马上。即使创建同步请求也无济于事,您将不断收到“错误 -2 iPhone 应用程序未回复..”,大约是 10 次的 5 倍。

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

您实施:

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 应用程序中有一个特殊的类,它会发送这些请求并发送要观看的答案。目前,这只能通过使用来完成应用程序组 https://developer.apple.com/library/prerelease/ios/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html#//apple_ref/doc/uid/TP40011195-CH4-SW19。因此,您必须为您的应用程序和 watchkit 扩展创建一个应用程序组。之后,我建议使用毫米波虫洞 https://github.com/mutualmobile/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
        }
    })

}

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

抱歉,文字太多了,但我只是希望它能帮助大家保持冷静,因为我为此花费了很多精力。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Watchkit 、带有 WatchKit 扩展的 openParentApplication 的相关文章

随机推荐

  • React 中的 TextField 内无法识别新行 '\n'

    Context 我正在使用 Material UI TextField 并映射从数据库 MongoDB 获取的对象数组 就像是 state map item gt
  • 当模块导入 Angular 时,如何自动运行模块中的服务?

    我想知道在导入模块时如何从模块运行服务而无需任何手动服务注入并运行 就像RouterModule does NgModule imports BroserModule MyModuleWithServicesThatShouldAutoRu
  • .NET 正则表达式 - 创建字符串?

    我有一个正则表达式 用于提取文件夹名称的两个部分 0 9 8 0 9A Ba c BLAH 没问题 这将匹配 12345678 abc BLAH 我有 12345678 和 abc 分为两组 是否可以通过提供带有两个字符串的方法并将它们插入
  • Artifactory 失去了对当地文物的追踪

    我正在使用 Artifactory OSS 4 1 0 和 Java 1 8 0 51 当我尝试从 Artifactory Web 界面下载本地工件之一时 我得到以下信息 errors status 500 message Could no
  • Easy_install 没有安装 Mechanize?

    我正在从旧的 Win2K 机器迁移到新的 功能更强大的 Vista 64 位 PC 大部分迁移都进行得相当顺利 但我确实发现我需要重新安装所有与 Python 相关的工具 我已经下载了 mechanize 0 1 11 tar gz 文件并
  • 在 Matlab 中使用 svmtrain 内存不足

    我有一组数据正在尝试使用 SVM 来学习 对于上下文 数据的维数为 35 包含大约 30 000 个数据点 我之前用这个数据集在 Matlab 中训练过决策树 大约花了 20 秒 由于对错误率不太满意 我决定尝试 SVM 我第一次尝试svm
  • MySql 中的 EntityFunctions 支持

    我在 MySQL 中使用 EntityFunctions DiffMinutes 时遇到错误 下面是我的代码 return db DiscoveredDevices Where m gt EntityFunctions DiffMinute
  • 哪个 Hook 可以更改 WooCommerce 购物车页面中的数量更新?

    当购物车中的产品数量发生变化时 我试图触发一个功能 更具体地说 我想在客户修改购物车中的金额时运行此功能 我正在寻找购物车中剩余的金额 然后拦截更新购物车事件 目前我正在使用 add action woocommerce remove ca
  • 将 pandas 数据框中的单元格拆分为多行

    我有一个包含订单数据的数据框 每个订单都有多个包存储为逗号分隔的字符串 package package code 列 我想拆分包裹数据并为每个包裹创建一行 包括其订单详细信息 这是一个示例输入数据框 import pandas as pd
  • 带有返回旧值的 glob 的行输入运算符

    以下摘录代码在 perl 5 16 3 及更早版本上运行时 具有奇怪的行为 其中对行输入运算符中的 glob 的后续调用会导致 glob 继续返回以前的值 而不是重新运行 glob usr bin env perl use strict u
  • cin >> 对于较大的数字失败,但对于较小的数字有效?

    为什么cin失败 当我输入一个数字 如 3999999999 但它适用于较小的数字 如 5 include
  • 系统.绘图.图形

    我有一个与按给定中心旋转椭圆有关的问题 假设我有一个椭圆 应该是按用户给定的点旋转该椭圆 并且椭圆应该围绕该给定点旋转 我努力了 g RotateTransform g TranslateTransform Code Graphics g
  • 使用公共字段的最佳实践是什么?

    当我编写类时 我总是通过公共属性公开私有字段 如下所示 private int MyField public int MyField get return MyField 什么时候可以像这样公开一个公共字段 public int MyFie
  • 如何查看Python的__builtins__源代码?

    我可以让 python 打印源代码吗 builtins 直接地 或 更优选 源代码的路径名是什么 builtins 我至少知道以下几件事 builtins 是一个模块 通过输入type builtins 我已经尝试过针对这个问题的更一般情况
  • Guice:如何绑定所有类型的泛型?

    假设我的代码中经常重复以下模式 class A
  • 获取 csh 脚本时如何获取 `__FILE__`

    我有一个脚本 用于在调用 csh shell 中设置一些环境变量 其中一些变量取决于脚本的位置 如果该文件是正确的 csh 脚本 我可以使用 0 来访问 FILE 但如果我使用源运行脚本 它只会告诉我 csh 或 tcsh 由于我使用它在父
  • C# 将数据从数据表插入到 SQL Server 数据库

    我几乎尝试了该网站上的所有解决方案 但无法解决这个问题 我有通过 ODBC 连接从数据库检索的数据 数据就在那里 它将很好地进入数据网格视图 但我无法将此数据放入我的本地 SQL 数据库 请告诉我我做错了什么 public partial
  • 按名称调用参数

    任何人都可以给我解释如何在 scala 编译器中按名称调用 该方法的语法快捷方式如下 arg gt Int将转变为arg gt Int并捕获传递给函数的参数 如何闭包 即按名称调用参数的实际类型 例如 Function0 Thanks 正如
  • 目录:资产/tessdata

    我从 github 下载了 OCR 文本识别器 我的问题是 我想在不在线的情况下启动我的应用程序 但每次我在手机上安装 apk 时 它都会开始下载英语和 tesseract OCR 引擎 我找到了一个在线指南 其中说我必须在资产文件夹中创建
  • Watchkit 、带有 WatchKit 扩展的 openParentApplication

    第一次不行 Null 在iPhone中打开应用程序之前 有时不起作用 但我想要一个循环或计时器来重复此请求以获取结果 这是我的代码 void application UIApplication application handleWatch