-1

嗨,我正在尝试在后台运行 FireBase。

我有以下代码: 代码执行以下操作 - 当应用程序进入后台时,它会不断检查 Firebase 是否有新的聊天消息。然后,如果找到新的聊天消息,它会增加应用程序徽章编号。

- (void)applicationDidEnterBackground:(UIApplication *)application
{

    [self.locationManager startMonitoringSignificantLocationChanges];

    NSLog(@"in background fetching8");

    if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]) { //Check if our iOS version supports multitasking I.E iOS 4
        if ([[UIDevice currentDevice] isMultitaskingSupported]) { //Check if device supports mulitasking
            UIApplication *application = [UIApplication sharedApplication]; //Get the shared application instance


            __block UIBackgroundTaskIdentifier background_task; //Create a task object
            background_task = [application beginBackgroundTaskWithExpirationHandler: ^ {
                [application endBackgroundTask: background_task]; //Tell the system that we are done with the tasks
                background_task = UIBackgroundTaskInvalid; //Set the task to be invalid
                //System will be shutting down the app at any point in time now
            }];


            //Background tasks require you to use asyncrous tasks
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                //Perform your tasks that your application requires


                NSLog(@"in background fetching98");

                inBackGround = YES;

                [self fetch];


                [application endBackgroundTask: background_task]; //End the task so the system knows that you are done with what you need to perform
                background_task = UIBackgroundTaskInvalid; //Invalidate the background_task
            });
        }
    }


    // 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, this method is called instead of applicationWillTerminate: when the user quits.
}

拿来:

- (void) fetch
{
    if([[API sharedInstance] isAuthorized])
    {

        NSLog(@"in background fetching");

        Firebase * ref = nil;

        NSDictionary * investor = [[API sharedInstance] investor];
        NSDictionary * startup = [[API sharedInstance] startup];

        if(investor != nil) {

            NSInteger iid = [[API sharedInstance] userid];
            NSString * path = [NSString stringWithFormat:  @"http://example.firebaseIO.com/investor/%d/conversations", iid];

            ref = [[Firebase alloc] initWithUrl:path];
        }
        else if(startup != nil)
        {
            NSInteger sid = [[startup objectForKey: @"id"] intValue];
            NSString * path = [NSString stringWithFormat:  @"http://example.firebaseIO.com/startup/%d/conversations", sid];
            ref = [[Firebase alloc] initWithUrl:path];
        }


        if(ref)
        {

            NSString * path = [NSString stringWithFormat: @"http://kickcircle.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]])
                    {


                        NSLog(@"in background fetching7");

                        FDataSnapshot * chatsnapshot = [snapshot childSnapshotForPath: @"chats"];

                        NSInteger numChatMessages = chatsnapshot.childrenCount;
                        numberOfTotalChatMessages += numChatMessages;

                        NSMutableDictionary *m = [snapshot.value mutableCopy];
                        [m setValue: snapshot.name forKey: @"ref_name"];

                        // number of messages read for that conversation
                        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];

                            if(numChatMessages > numUserMessagesRead)
                            {
                                if([[m objectForKey: @"last_from_id"] intValue] != [[API sharedInstance] userid])
                                {
                                    [m setValue: @"true" forKey: @"bubble"];

                                    newChats = YES;

                                    if(inBackGround)
                                    {
                                        [self addNotification];
                                    }
                                }
                                else{
                                    numUserMessagesRead = numChatMessages;
                                }
                            }
                            else {
                                numUserMessagesRead = numChatMessages;
                            }

                            numberOfMessagesRead += numUserMessagesRead;

                            [m setValue: [NSNumber numberWithInt: numUserMessagesRead] forKey: @"numMessagesRead"];
                        }
                        else {

                            if([[m objectForKey: @"last_from_id"] intValue] != [[API sharedInstance] userid])
                            {
                                [m setValue: @"true" forKey: @"bubble"];

                                newChats = YES;

                                [m setValue: [NSNumber numberWithInt: 0] forKey: @"numMessagesRead"];


                                if(inBackGround)
                                {
                                    [self addNotification];
                                }
                            }
                            else {
                                numberOfMessagesRead += numChatMessages;

                                [m setValue: [NSNumber numberWithInt: numChatMessages] forKey: @"numMessagesRead"];
                            }
                        }

                        [m setValue: [NSNumber numberWithInt: numChatMessages] forKey: @"numChatMessages"];

                        [self.chats addObject: m];

                        [self calculateChatNumber];

                        NSNumber * index = [NSNumber numberWithInt: self.chats.count - 1];
                        [read setValue: index forKey: snapshot.name];

                        PLRightMenuViewController * rightPanel = (PLRightMenuViewController *) self.viewController.rightPanel;
                        [rightPanel.tableView reloadData];


                    }

                }];

            }];


            [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]])
                    {

                        NSLog(@"in background fetching8");

                        NSMutableDictionary *m = [snapshot.value mutableCopy];
                        [m setValue: snapshot.name forKey: @"ref_name"];

                        numberOfTotalChatMessages += 1;


                        if([read objectForKey: snapshot.name])
                        {
                            NSInteger index = [[read objectForKey: snapshot.name] intValue];

                            // number of current chats for conversation
                            NSInteger numChats = [[[self.chats objectAtIndex: index] objectForKey:  @"numChatMessages"] intValue];

                            // number of messages read
                            NSNumber * readMessages = [[self.chats objectAtIndex: index] objectForKey:  @"numMessagesRead"];
                            NSInteger readMessagesInt = [readMessages intValue];

                            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];

                                if([[m objectForKey: @"last_from_id"] intValue] != [[API sharedInstance] userid]) {

                                    newChats = YES;

                                    [m setValue: @"true" forKey: @"bubble"];

                                    if(numUserMessagesRead > readMessagesInt) {

                                        numberOfMessagesRead += numUserMessagesRead - readMessagesInt;

                                        readMessagesInt = numUserMessagesRead;


                                        if(inBackGround)
                                        {
                                            [self addNotification];
                                        }
                                    }
                                }
                                else {
                                    numberOfMessagesRead += numChats + 1 - readMessagesInt;
                                    readMessagesInt = numChats + 1;
                                }

                            }
                            else {

                                if([[m objectForKey: @"last_from_id"] intValue] != [[API sharedInstance] userid])
                                {
                                    [m setValue: @"true" forKey: @"bubble"];
                                    newChats = YES;


                                    if(inBackGround)
                                    {
                                        [self addNotification];
                                    }
                                }
                                else {
                                    numberOfMessagesRead += numChats + 1 - readMessagesInt;
                                    readMessagesInt = numChats + 1;
                                }
                            }

                            [self.chats removeObjectAtIndex: index];

                            [m setValue: [NSNumber numberWithInt: numChats + 1]  forKey: @"numChatMessages"];
                            [m setValue: [NSNumber numberWithInt: readMessagesInt] forKey: @"numMessagesRead"];


                            [self.chats addObject: m];

                             NSNumber * index1 = [NSNumber numberWithInt: self.chats.count - 1];
                            [read setValue: index1 forKey: snapshot.name];
                        }

                        [self calculateChatNumber];

                        PLRightMenuViewController * rightPanel = (PLRightMenuViewController *) self.viewController.rightPanel;
                        [rightPanel.tableView reloadData];
                    }


                }];

            }];
        }
    }
}

出于某种原因,当应用程序进入后台时,它不起作用(当有新消息时徽章不会增加)。我究竟做错了什么?

4

1 回答 1

2

您尝试在后台运行的方法保留用于后台任务完成 - 实际上它并不意味着代码的操作执行。您应该转向推送通知模型,或等待 iOS 7 合并更新。

beginBackgroundTaskWithExpirationHandler:向 iOS 发出信号,表明您的应用希望在应用暂停之前完成任务,即使应用已进入后台状态也是如此。endBackgroundTask:通知 iOS 应用程序的任务已完成,允许它在需要时将您的应用程序移动到暂停状态。如果应用程序始终处于前台,则这些调用无效,因此使用它们并没有什么坏处。

请注意,后台任务不会自由支配,也不会无限期地完成。beginBackgroundTaskWithExpirationHandler: 的“过期处理程序”部分是一个指定清理代码的块,如果任务超出其生命周期。作为后台任务执行的代码不得进行任何 UI 更新或 openGL 调用(因为应用程序在屏幕外)。

我想你最多可以有 10 分钟。

于 2013-08-13T21:15:43.433 回答