在 WatchKit 中解析查询
Parse Query in WatchKit
我在我的 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 {
[超级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. Before you continue, I'd also suggest you read through the documentation in the WatchKit Programming Guide。作为有抱负的 Apple Watch 开发人员,它会让您更好地了解所有可用的工具集。
WK接口表
一旦了解 WKInterfaceTable
的来龙去脉,您很快就会明白为什么您的方法存在缺陷,原因有二。首先,您没有 reloadData
方法。 WatchKit 中的替代方案是 setNumberOfRows(_:withRowTypes:)
。然后你需要遍历每一行并配置它。
WatchKit 扩展中的 PFQuery
您遇到问题的第二个原因是您使用了 PFQuery
。
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.
我建议您停止在 WatchKit 扩展中制作 PFQuery
s。原因是使用您的 Watch App 的用户只会打开该应用程序一两秒钟。一切都会发生得非常快。正因为如此,在Watch App被用户终止之前,网络调用的成功是极难保证的。这使事情变得更加困难,但事实就是如此。
相反,您想 运行 您对 iOS 应用程序的 PFQuery
调用,并 return 通过以下调用将该信息返回到 Watch Extension:
WKInterfaceController
- openParentApplication(_:reply:)
UIApplicationDelegate
- handleWatchKitExtensionRequest(_:reply:)
您还可以将 PFQuery
缓存到 shared app group using MMWormhole 或类似的替代方法中。下面是一个示例,说明如何让您的 Watch Extension 向 iOS 应用程序请求 运行 PFQuery,将数据缓存在 MMWormhole 中,并在完成后通知 Watch Extension。通过始终从缓存中读取数据,无论 Watch Extension 是否仍在 运行ning 以及关闭和重新打开,您都有一个一致的机制。
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)});
}
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 应用程序的复杂性。
我在我的 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 { [超级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. Before you continue, I'd also suggest you read through the documentation in the WatchKit Programming Guide。作为有抱负的 Apple Watch 开发人员,它会让您更好地了解所有可用的工具集。
WK接口表
一旦了解 WKInterfaceTable
的来龙去脉,您很快就会明白为什么您的方法存在缺陷,原因有二。首先,您没有 reloadData
方法。 WatchKit 中的替代方案是 setNumberOfRows(_:withRowTypes:)
。然后你需要遍历每一行并配置它。
WatchKit 扩展中的 PFQuery
您遇到问题的第二个原因是您使用了 PFQuery
。
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.
我建议您停止在 WatchKit 扩展中制作 PFQuery
s。原因是使用您的 Watch App 的用户只会打开该应用程序一两秒钟。一切都会发生得非常快。正因为如此,在Watch App被用户终止之前,网络调用的成功是极难保证的。这使事情变得更加困难,但事实就是如此。
相反,您想 运行 您对 iOS 应用程序的 PFQuery
调用,并 return 通过以下调用将该信息返回到 Watch Extension:
WKInterfaceController
- openParentApplication(_:reply:)UIApplicationDelegate
- handleWatchKitExtensionRequest(_:reply:)
您还可以将 PFQuery
缓存到 shared app group using MMWormhole 或类似的替代方法中。下面是一个示例,说明如何让您的 Watch Extension 向 iOS 应用程序请求 运行 PFQuery,将数据缓存在 MMWormhole 中,并在完成后通知 Watch Extension。通过始终从缓存中读取数据,无论 Watch Extension 是否仍在 运行ning 以及关闭和重新打开,您都有一个一致的机制。
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)});
}
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 应用程序的复杂性。