Firebase * ref = nil;
NSInteger iid = [[API sharedInstance] userid];
NSString * path = [NSString stringWithFormat: @"http://example.firebaseIO.com/user/%d/conversations", iid];
ref = [[Firebase alloc] initWithUrl:path];
if(ref) {
NSString * path = [NSString stringWithFormat: @"http://example.firebaseIO.com/conversations"];
Firebase * conv = [[Firebase alloc] initWithUrl: path];
[ref observeEventType:FEventTypeChildAdded withBlock:^(FDataSnapshot *snapshot) {
// name of conversation
NSString * name = snapshot.name;
Firebase * ref1 = [conv childByAppendingPath: name];
[ref1 observeSingleEventOfType:FEventTypeValue withBlock:^(FDataSnapshot *snapshot) {
if(snapshot.value != [NSNull null] && ![snapshot.value isKindOfClass: [NSString class]])
{
FDataSnapshot * chatsnapshot = [snapshot childSnapshotForPath: @"chats"];
NSInteger numChatMessages = chatsnapshot.childrenCount;
numberOfTotalChatMessages += numChatMessages;
NSMutableDictionary *m = [snapshot.value mutableCopy];
[m setValue: snapshot.name forKey: @"ref_name"];
NSInteger current_user = [[API sharedInstance] userid];
NSString * userpath = [NSString stringWithFormat: @"users/%d", current_user];
FDataSnapshot * usersnapshot = [snapshot childSnapshotForPath: userpath];
if(usersnapshot.value != [NSNull null] && ![usersnapshot.value isKindOfClass: [NSString class]])
{
NSDictionary * userdict = usersnapshot.value;
NSInteger numUserMessagesRead = [userdict[@"numOfMessages"] intValue];
numberOfMessagesRead += numUserMessagesRead;
if(numberOfTotalChatMessages > numberOfMessagesRead) {
[m setValue: @"true" forKey: @"bubble"];
}
}
[self.chats addObject: m];
NSNumber * index = [NSNumber numberWithInt: self.chats.count - 1];
[read setValue: index forKey: snapshot.name];
PLRightMenuViewController * rightPanel = (PLRightMenuViewController *) self.viewController.rightPanel;
[rightPanel.tableView reloadData];
self.numChats = numberOfTotalChatMessages - numberOfMessagesRead;
[[UIApplication sharedApplication] setApplicationIconBadgeNumber: self.numChats];
}
}];
}];
[ref observeEventType:FEventTypeChildChanged withBlock:^(FDataSnapshot *snapshot) {
NSString * name = snapshot.name;
Firebase * ref1 = [conv childByAppendingPath: name];
[ref1 observeSingleEventOfType:FEventTypeValue withBlock:^(FDataSnapshot *snapshot)
{
if(snapshot.value != [NSNull null] && ![snapshot.value isKindOfClass: [NSString class]])
{
numberOfTotalChatMessages += 1;
NSMutableDictionary *m = [snapshot.value mutableCopy];
[m setValue: snapshot.name forKey: @"ref_name"];
[m setValue: @"true" forKey: @"bubble"];
[self.chats addObject: m];
if([read objectForKey: snapshot.name])
{
NSInteger index = [[read objectForKey: snapshot.name] intValue];
[self.chats removeObjectAtIndex: index];
NSNumber * index1 = [NSNumber numberWithInt: self.chats.count - 1];
[read setValue: index1 forKey: snapshot.name];
}
self.numChats = numberOfTotalChatMessages - numberOfMessagesRead;
[[UIApplication sharedApplication] setApplicationIconBadgeNumber: self.numChats];
PLRightMenuViewController * rightPanel = (PLRightMenuViewController *) self.viewController.rightPanel;
[rightPanel.tableView reloadData];
}
}];
}];
}
我上面的代码基本上使用firebase检查任何新的聊天对话并更改应用程序徽章编号。如何在应用程序的后台运行代码,以便无论某人当前是否正在使用该应用程序,都会更改应用程序徽章编号?
基本上,我如何在后台运行上面的代码?我应该在Appdelegate中更改什么?
答案 0 :(得分:3)
除非你作弊,否则你不能。目前,iOS或Apple分别不允许应用程序进入后台,只有极少数例外。如定位服务或播放音频。
假装大声播放有些作弊。
到目前为止,您必须使用推送通知才能通知应用有关收到的消息并更新徽章。
或者......等待iOS 7发布。假设您有一个开发者帐户,您可以访问文档和预览/测试资源并自行准备,直到iOS 7和SDK等为GA。
答案 1 :(得分:1)
// @interface
// Declare Private property
@property (nonatomic) UIBackgroundTaskIdentifier backgroundTask;
//@end
// ...
// Copy into
//@implementation
- (void)setupBackgrounding {
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(appBackgrounding:)
name: UIApplicationDidEnterBackgroundNotification
object: nil];
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(appForegrounding:)
name: UIApplicationWillEnterForegroundNotification
object: nil];
}
- (void)appBackgrounding: (NSNotification *)notification {
[self keepAlive];
}
- (void) keepAlive {
self.backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:self.backgroundTask];
self.backgroundTask = UIBackgroundTaskInvalid;
[self keepAlive];
}];
}
- (void)appForegrounding: (NSNotification *)notification {
if (self.backgroundTask != UIBackgroundTaskInvalid) {
[[UIApplication sharedApplication] endBackgroundTask:self.backgroundTask];
self.backgroundTask = UIBackgroundTaskInvalid;
}
}
答案 2 :(得分:0)
您需要使用Apple Push Notification服务,通常缩写为APN。
答案 3 :(得分:0)
你可以通过推送通知来完成这里是一个很好的解释。
例http://www.raywenderlich.com/32960/apple-push-notification-services-in-ios-6-tutorial-part-1
注意:您需要一个会通知您的申请的APNS。
在iOS7中提供了fetchAPI功能,它允许你在后台工作,但请注意它不承认你的应用程序将在后台运行,因为系统将决定何时允许应用程序在后台运行。
在iOS7中,还有一件事叫做无声 - 推送通知,这将允许您在通知到来时更新您的视图,这意味着如果您的应用程序在后台和通知中,您可以在后台更改应用程序徽章编号。
答案 4 :(得分:0)
您可以使用这些方法,再运行后台任务..
- (UIBackgroundTaskIdentifier)beginBackgroundTaskWithExpirationHandler:(void(^)(void))handler NS_AVAILABLE_IOS(4_0);
- (void)endBackgroundTask:(UIBackgroundTaskIdentifier)identifier NS_AVAILABLE_IOS(4_0);
- (BOOL)setKeepAliveTimeout:(NSTimeInterval)timeout handler:(void(^)(void))keepAliveHandler NS_AVAILABLE_IOS(4_0);
- (void)clearKeepAliveTimeout NS_AVAILABLE_IOS(4_0);
- (void)getDataFromServer
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self beginBackgroundUpdateTask];
NSURLResponse * response = nil;
NSError * error = nil;
NSData * responseData = [NSURLConnection sendSynchronousRequest: request returningResponse: &response error: &error];
// Do something with the result
[self endBackgroundUpdateTask];
});
}
- (void) beginBackgroundUpdateTask
{
self.backgroundUpdateTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[self endBackgroundUpdateTask];
}];
}
- (void) endBackgroundUpdateTask
{
[[UIApplication sharedApplication] endBackgroundTask: self.backgroundUpdateTask];
self.backgroundUpdateTask = UIBackgroundTaskInvalid;
}
如果你想让应用程序保持活力,你可以使用它: -
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store
// enough application state information to restore your application to its current state in case
// it is terminated later.
//
// If your application supports background execution,
// called instead of applicationWillTerminate: when the user quits.
if ([application respondsToSelector:@selector(setKeepAliveTimeout:handler:)])
{
[application setKeepAliveTimeout:600 handler:^{
DDLogVerbose(@"KeepAliveHandler");
// Do other keep alive stuff here.
}];
}
}
它可能对你有帮助.. 在iOS 7中,可能有更好的方法来做到这一点......