在WatchKit中parsing查询
我在我的iPhone
应用程序中做一个Parse
查询,但我收到错误,试图在我的Watch
应用程序中执行相同的Parse
查询 。
这是我的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 。 在继续之前,我还build议您阅读WatchKit编程指南中的文档。 它将使您更好地了解所有可用于您的Apple Watch开发人员的工具集。
WKInterfaceTable
一旦你了解了WKInterfaceTable
,你很快就会明白为什么你的方法有缺陷,有两个原因。 首先,你没有reloadData
方法。 WatchKit中的替代方法是setNumberOfRows(_:withRowTypes:)
。 然后你需要遍历每一行并configuration它。
PFK在WatchKit扩展
你将会遇到的第二个原因是由于你使用了PFQuery
。
这是一个方面的build议,所以采取或离开它。 我从这里的经验来讲,已经build立了一个非常大的基于页面的手表应用程序,与iOS应用程序进行大量的沟通。
我build议你停止在你的WatchKit扩展中使用PFQuery。 原因是用户使用您的手表应用程序只会打开一两个应用程序。 一切都会发生得非常快。 因此,在Watch App被用户终止之前,保证networking呼叫的成功是非常困难的。 这使事情变得更加困难,但事实就是这样。
相反,您希望在iOS应用上运行您的PFQuery
调用,并通过以下调用将该信息返回给Watch Extension:
-
WKInterfaceController
– openParentApplication(_:reply 🙂 -
UIApplicationDelegate
– handleWatchKitExtensionRequest(_:reply 🙂
您还可以使用MMWormhole或类似的方法将PFQuery
caching到共享的应用程序组中 。 以下是如何让您的Watch Extension请求iOS应用程序运行PFQuery,将数据caching在MMWormhole中,并在完成后通知Watch Extension。 通过总是从caching中读取数据,无论Watch Extension是否仍在运行以及closures和重新打开,您都拥有一致的机制。
Objective-C的
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]) }
希望这有助于打破从caching中读取数据以及将networking请求(或PFQueries)卸载到iOS应用程序的一致方式的复杂性。