在WatchKit中解析查询 [英] Parse Query in WatchKit

查看:86
本文介绍了在WatchKit中解析查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的 iPhone 应用中执行 Parse 查询,但我收到错误我的观看 app 中的 Parse 查询相同。

I do a Parse query in my iPhone app, but I am getting errors trying to do the same Parse query in my Watch app.

这是我的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];
            });
        }
    }];
}

但我在这两行上出错...

But I get errors on these two lines...

`PFQuery *query = [self queryForTable];`

`[self.tableView reloadData];`

因为我无法执行与表相关的完全相同的代码我猜,但我只是不确定要改变它。

because I can't do the same exact code related to a table I'm guessing, but I'm just not sure what to change it to.

编辑:每个@cnoon添加代码回答

Adding code per @cnoon answer

WatchKit InterfaceController.m

我如何要求我的查询在这里运行?
- (void)awakeWithContext:(id)context {
[ super awakeWithContext:context];

How would I ask for my query to run here? - (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 要运行吗?

How would I ask for my PFQuery to run?

- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void(^)(NSDictionary *replyInfo))reply {
    // What to put here?
}


推荐答案

没有这样的事情WatchKit应用程序中的 UITableView 。相反,您必须使用 WKInterfaceTable 。在继续之前,我还建议您仔细阅读 WatchKit编程指南。它可以让您更好地了解作为有抱负的Apple Watch开发人员可以使用的所有工具集。

There's no such thing as a UITableView in a WatchKit application. Instead, you have to work with WKInterfaceTable. Before you continue, I'd also suggest you read through the documentation in the WatchKit Programming Guide. It will give you a MUCH better understanding of all the toolsets available to you as an aspiring Apple Watch developer.

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

Once you know the ins and outs of a WKInterfaceTable, you'll quickly see why your approach is flawed for two reasons. First off, you don't have a reloadData method. The alternative in WatchKit is to setNumberOfRows(_:withRowTypes:). Then you need to iterate through each row and configure it.

你的第二个原因会有问题是由于你使用 PFQuery

The second reason you are going to have issues is due to your use of PFQuery.


这是一些侧面建议,所以接受或离开它。我是根据这里的经验说的,已经构建了一个非常大的基于页面的Watch App,它与iOS App进行了大量的通信。

This is a bit of side advice, so take it or leave it. I'm speaking from experience here having already built a very large page-based Watch App that heavily communicates with the iOS App.

I会建议你停止在WatchKit Extension中制作 PFQuery 。原因是使用您的Watch App的用户只能让应用程序打开一两秒钟。一切都会发生得非常快。因此,在用户终止Watch App之前,很难保证网络呼叫的成功。这使得事情变得更加困难,但事实就是如此。

I would advise you to stop making PFQuerys in your WatchKit Extension. The reason is that users using your Watch App are only going to have the app open for a second or two. Everything will happen extremely fast. Because of this, it is extremely difficult to guarantee the success of network calls before the Watch App is terminated by the user. This makes things MUCH more difficult, but is simply the way it is.

相反,你想运行你的 PFQuery 调用iOS应用程序并通过以下调用将该信息返回到Watch Extension:

Instead, you want to run your PFQuery calls on the iOS App and return that information back to the Watch Extension through the following calls:

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

您还可以缓存 PFQuery 进入共享应用组使用 MMWormhole 或类似的方法替代方案。下面是一个示例,说明如何让您的Watch Extension请求iOS应用程序运行PFQuery,将数据缓存在MMWormhole中,并在完成后通知Watch Extension。通过始终从缓存中读取数据,您可以获得一致的机制,无论Watch Extension是否仍在运行以及关闭和重新打开。

You can also cache the PFQuery into the shared app group using MMWormhole or a similar approach alternative. Below is an example of how you can have your Watch Extension request the iOS Application to run a PFQuery, cache the data in MMWormhole and notify the Watch Extension once it is finished. By always reading the data out of the cache, you have a consistent mechanism whether the Watch Extension was still running as well as closed and re-opened.

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






Swift



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应用程序。


Hopefully that helps break down the complexity of having a consistent way to read data from the cache as well as offload network requests (or PFQueries) to the iOS App.

这篇关于在WatchKit中解析查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆