我正在寻找一种触发应用程序从远程REST服务获取数据的方法。该方法不应要求轮询。
iOS推送通知似乎不是一个选项,因为它可以被用户停用。但是,我可能错了。
有没有最佳做法来完成这项工作?
答案 0 :(得分:5)
实际上推送通知是最佳选择。
在ios8及更高版本上,默认情况下会启用推送通知,原因正是您想要的。 您无法向用户显示某些内容(意味着不会显示包含带警报的json的推送),但您的应用程序正在获取有效负载,并且可以在收到推送后启动操作。
用户的通知设置仅控制系统 在屏幕上显示本地或远程通知。 无论如何 通知设置,本地和远程通知将传递到 您的应用在适当的时间。
答案 1 :(得分:1)
从宁静的服务中获取数据
嘿@Scholle,这可以通过多种方式完成.1。 NSURLRequest:,通过对NSURLRequest进行网络调用并确认NSURLConnetionDelegate协议方法。然后序列化JSON响应。
在NSUrlConnectionDidReceiveData方法中
NSError *error = nil;
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:myNSData options:kNilOptions error:&error];
if (error != nil) {
NSLog(@"Error parsing JSON.");
}
else {
NSLog(@"Array: %@", jsonArray);
}
2. AFNetworking 只需在项目中导入最新的afnetworking 3.0即可。并使用以下代码进行带有参数列表的网络调用。
- (void)requestWithURL:(NSString *)url parameterDictionary:(NSMutableDictionary *)data requestType:(NSString *)reqType handler:(NSObject *)handler selector:(SEL)selector{
// Request Type is GET or POST
// handler is set to be self if we want to handle response in selector method defined in same viewController
NSError *error;
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
NSMutableURLRequest *req = [[AFJSONRequestSerializer serializer] requestWithMethod:reqType URLString:[NSString stringWithFormat:@"%@",url] parameters:nil error:nil];
req.timeoutInterval= [[[NSUserDefaults standardUserDefaults] valueForKey:@"timeoutInterval"] longValue];
[req setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[req setValue:@"application/json" forHTTPHeaderField:@"Accept"];
if (data != nil) {
NSLog(@"Data is not nil");
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:data options:0 error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
[req setHTTPBody:[jsonString dataUsingEncoding:NSUTF8StringEncoding]];
}else{
NSLog(@"Data is nil");
}
[[manager dataTaskWithRequest:req completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
if (!error) {
// NSLog(@"Reply JSON: %@", responseObject);
[handler performSelector:selector withObject:responseObject];
if ([responseObject isKindOfClass:[NSDictionary class]]) {
//blah blah
}
} else {
NSLog(@"Error: %@, %@, %@", error, response, responseObject);
[handler performSelector:selector withObject:responseObject];
}
}] resume];
}
答案 2 :(得分:1)
在iOS的早期,背景提取是不可能的。随着时间的推移,Apple已经放松了一点,但最终他们希望应用程序成为执行重点任务的低能耗软件。
我相信它是iOS 5或6,Apple推出了一项增强功能,用户使用最多的应用程序可以保持更长时间。如果应用程序进行后台提取(对于用户最常用的应用程序),系统也可以更新多任务轮播中应用程序的预览。
需要定期检查新内容的应用可以询问 系统唤醒它们,以便它们可以启动一个获取操作 那个内容。要支持此模式,请启用后台提取选项 来自您的“功能”选项卡的“背景模式”部分 Xcode项目。 (您也可以通过添加支持来启用此支持 UIBackgroundModes键与应用程序的Info.plist中的获取值 文件。)启用此模式并不能保证系统能够提供 您的应用随时都可以执行后台提取。系统必须 平衡您的应用需要根据其他应用的需求获取内容 和系统本身。在评估该信息后,系统 在有良好机会的情况下为应用程序提供时间。
检查documentation以了解如何使用beginBackgroundTaskWithName实现后台获取:expirationHandler:
答案 3 :(得分:1)
由于你不能使用轮询和套接字,并且我认为无法预测事件时间,我想你可以做的最好的事情是使用通知并经常警告用户启用它们,应用程序应该应对这个事实可能没有启用通知。
如果抓取对于应用程序至关重要,我不会丢弃轮询,我会使用先前方法的通知,如果被禁用则回退到轮询。