ios - 在WatchKit中解析查询

标签 ios objective-c iphone parse-platform watchkit

我在Parse应用程序中执行了iPhone查询,但是在Parse应用程序中尝试执行相同的Watch查询时出现错误。

这是我的iPhone应用程序中的查询:

- (void)viewDidLoad {
    // GMT Date from Phone
    NSDate *gmtNow = [NSDate date];
    NSLog(@"GMT Now: %@", gmtNow);

    // Query Parse
    PFQuery *query = [self queryForTable];
    [query whereKey:@"dateGame" greaterThanOrEqualTo:gmtNow];

    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
        if (!error) {
            NSMutableArray *localMatchup = [@[] mutableCopy];

            for (PFObject *object in objects) {
                // Add objects to local Arrays
                [localMatchup addObject:[object objectForKey:@"matchup"]];

                // App Group
                NSString *container = @"group.com.me.off";
                NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:container];

                // Matchup
                [defaults setObject:localMatchup forKey:@"KeyMatchup"];
                NSArray *savedMatchup = [defaults objectForKey:@"KeyMatchup"];
                NSLog(@"Default Matchup: %@", savedMatchup);
                savedMatchup = matchupArray;
            }

            dispatch_async(dispatch_get_main_queue(), ^{
                [self.tableView reloadData];
            });

        }
    }];
}

这是我在WatchKit应用中尝试过的查询...
- (void)awakeWithContext:(id)context {
    // GMT Date from Phone
    NSDate *gmtNow = [NSDate date];
    NSLog(@"GMT Now: %@", gmtNow);

    // Query Parse
    PFQuery *query = [self queryForTable];
    [query whereKey:@"dateGame" greaterThanOrEqualTo:gmtNow];

    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
        if (!error) {
            NSMutableArray *localMatchup = [@[] mutableCopy];

            for (PFObject *object in objects) {
                // Add objects to local Arrays
                [localMatchup addObject:[object objectForKey:@"matchup"]];

                // App Group
                NSString *container = @"group.com.me.off";
                NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:container];

                // Matchup
                [defaults setObject:localMatchup forKey:@"KeyMatchup"];
                NSArray *savedMatchup = [defaults objectForKey:@"KeyMatchup"];
                NSLog(@"Default Matchup: %@", savedMatchup);
                savedMatchup = self.matchupArray;
            }

            dispatch_async(dispatch_get_main_queue(), ^{
                [self.tableView reloadData];
            });
        }
    }];
}

但是我在这两行上都出错了...
`PFQuery *query = [self queryForTable];`

`[self.tableView reloadData];`

因为我无法执行与猜测的table相关的相同代码,但是我不确定将其更改为什么。

编辑:每个@cnoon答案添加代码
WatchKit InterfaceController.m:

我如何要求我的查询在这里运行?
-(void)awakeWithContext:(id)context {
[super awakeWithContext:context];
    [WKInterfaceController openParentApplication:nil reply:^(NSDictionary *replyInfo, NSError *error) {
        // What to put here?
        NSLog(@"Open Parent Application");
    }];

-和-

iPhone AppDelegate.h
我如何要求我的PFQuery运行?
- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void(^)(NSDictionary *replyInfo))reply {
    // What to put here?
}

最佳答案

WatchKit应用程序中没有UITableView这样的东西。相反,您必须使用WKInterfaceTable。在继续之前,我还建议您通读WatchKit Programming Guide中的文档。作为有抱负的Apple Watch开发人员,它将使您更好地了解所有可用的工具集。

WKInterfaceTable

一旦了解了WKInterfaceTable的来龙去脉,您将很快了解为什么您的方法存在缺陷的两个原因。首先,您没有reloadData方法。 WatchKit中的替代方法是setNumberOfRows(_:withRowTypes:)。然后,您需要遍历每一行并对其进行配置。

WatchKit扩展中的PFQuery

您遇到问题的第二个原因是由于使用了PFQuery

这是一些附带建议,请保留或保留。我的经验是,我已经构建了一个非常大的基于页面的Watch App,可以与iOS App进行大量通信。

我建议您停止在WatchKit Extension中制作PFQuery。原因是使用您的Watch App的用户只能打开应用一两秒钟。一切都会很快发生。因此,在Watch App被用户终止之前,很难保证网络通话的成功。这使事情变得更加困难,但这仅仅是事实。

相反,您想在iOS App上运行PFQuery调用,然后通过以下调用将该信息返回给Watch Extension:

  • WKInterfaceController-openParentApplication(_:reply:)
  • UIApplicationDelegate-handleWatchKitExtensionRequest(_:reply:)

  • 您也可以使用shared app group或类似方法将PFQuery缓存到MMWormhole中。下面是一个示例,说明如何让您的Watch Extension请求iOS应用程序运行PFQuery,将数据缓存在MMWormhole中,并在完成后通知Watch Extension。通过始终从高速缓存中读取数据,您可以拥有一致的机制,无论Watch Extension是否仍在运行以及是否关闭和重新打开。

    物镜

    InterfaceController.m
    - (void)willActivate {
        [super willActivate];
    
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2.0 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
            [WKInterfaceController
             openParentApplication:@{@"pfquery_request": @"dumm_val"}
             reply:^(NSDictionary *replyInfo, NSError *error) {
                 NSLog(@"User Info: %@", replyInfo);
                 NSLog(@"Error: %@", error);
    
                 if ([replyInfo[@"success"] boolValue]) {
                     NSLog(@"Read data from Wormhole and update interface!");
                 }
            }];
        });
    }
    

    AppDelegate.m
    - (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *))reply {
        if (userInfo[@"pfquery_request"]) {
            NSLog(@"Starting PFQuery"); // won't print out to console since you're running the watch extension
    
            // 1. Run the PFQuery
            // 2. Write the data into MMWormhole (done in PFQuery completion block)
            // 3. Send the reply back to the extension as success (done in PFQuery completion block)
    
            reply(@{@"success": @(YES)});
        }
    
        reply(@{@"success": @(NO)});
    }
    

    迅速

    InterfaceController.swift
    override func willActivate() {
        super.willActivate()
    
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(2.0 * Float(NSEC_PER_SEC))), dispatch_get_main_queue()) {
            WKInterfaceController.openParentApplication(["pfquery_request": "dummy_val"]) { userInfo, error in
                println("User Info: \(userInfo)")
                println("Error: \(error)")
    
                if let success = (userInfo as? [String: AnyObject])?["success"] as? NSNumber {
                    if success.boolValue == true {
                        println("Read data from Wormhole and update interface!")
                    }
                }
            }
    
            return
        }
    }
    

    AppDelegate.swift
    func application(
        application: UIApplication!,
        handleWatchKitExtensionRequest userInfo: [NSObject : AnyObject]!,
        reply: (([NSObject : AnyObject]!) -> Void)!)
    {
        if let pfqueryRequest: AnyObject = (userInfo as? [String: AnyObject])?["pfquery_request"] {
            println("Starting PFQuery") // won't print out to console since you're running the watch extension
    
            // 1. Run the PFQuery
            // 2. Write the data into MMWormhole (done in PFQuery completion block)
            // 3. Send the reply back to the extension as success (done in PFQuery completion block)
    
            reply(["success": true])
        }
    
        reply(["success": false])
    }
    

    希望这有助于降低采用一致的方式从缓存读取数据以及将网络请求(或PFQueries)卸载到iOS App的复杂性。

    关于ios - 在WatchKit中解析查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29051061/

    相关文章:

    android - 我可以在 Graph API 创建的 Facebook 事件上设置自己的 map 吗?

    ios - UIActionSheet 取消按钮的奇怪行为

    iphone - 自定义广告横幅

    objective-c - 在两列中显示结果

    ios - 如何在键盘选择菜单中编辑自定义键盘名称

    iphone - 在 UITableView 中选择时如何更改单元格标题颜色

    ios - 将 JSON 中的 "sex = 0"转换为 BOOL

    ios - Objective-C 中的混合或多重继承?

    iphone - NSCFTimer 是否存在内存泄漏?

    ios - 在 iOS 版 Google Analytics(分析)中使用数字自定义指标