问题描述
我在我的 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
。相反,您必须使用。在继续之前,我还建议您仔细阅读。它可以让您更好地了解作为有抱负的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
.
I会建议你停止在WatchKit Extension中制作 PFQuery
。原因是使用您的Watch App的用户只能让应用程序打开一两秒钟。一切都会发生得非常快。因此,在用户终止Watch App之前,很难保证网络呼叫的成功。这使得事情变得更加困难,但事实就是如此。
I would advise you to stop making PFQuery
s 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
- -
UIApplicationDelegate
-
WKInterfaceController
- openParentApplication(_:reply:)UIApplicationDelegate
- handleWatchKitExtensionRequest(_:reply:)
您还可以缓存 PFQuery
进入使用或类似的方法替代方案。下面是一个示例,说明如何让您的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中解析查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!