使用后台线程

时间:2016-03-16 10:36:09

标签: ios objective-c calendar eventkit

我必须根据服务器的响应(事件)更新日历。我创建了一个数组来保存所有事件对象并迭代它以将事件保存在日历上。它的工作但问题是它只创建一个随机事件而不是全部。

  1. 我必须显示所有事件(most important right now)
  2. 如何使用后台队列更新日历。
  3. 我必须每隔5分钟更新日历,因此必须在后台每5分钟执行一次方法。
  4. 当我的用户将在主页viewDidLoad方法中登录到应用时,调用服务器来创建事件。日历是否需要时间来创建事件,如果用户登录并立即退出应用程序,将会发生什么。日历会更新或不更新?我认为在创建日历上的所有活动之前,主页不会加载?
  5. 这是代码。

    - (void)calUpdateWebService
    {
        NSString *urlString = @"http://www.xxxx.com";
    
        NSURL *url = [NSURL URLWithString:urlString];
    
        NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];
    
        NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
    
        NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject];
    
        NSURLSessionDataTask * dataTask = [defaultSession dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
            if (!error)
            {
                NSDictionary *responseJson = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
    
                NSMutableArray *eventArray = responseJson[@"result"];
    
                eventData = [NSMutableArray new];
                for(NSDictionary *eventDict in eventArray)
                {
                    NSDictionary *eventDic =@{@"startDate":[eventDict valueForKey:@"start_date"],@"endDate":[eventDict valueForKey:@"end_date"],@"eventSlot":[eventDict valueForKey:@"slot"],@"eventTitle":[eventDict valueForKey:@"package_title"]};
    
                    [eventData addObject:eventDic] ;
                }
                /** call method to create events**/
                [self addBooking];
            }
    
        }];
        [dataTask resume];
    }
    
    /** method to create events **/
    -(void)addBooking
    {
        EKEventStore *eventStore = [[EKEventStore alloc]init];
        [eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
            if (granted)
            {
                addEventGranted =1;
    
                EKEvent *event =[EKEvent eventWithEventStore:eventStore];
                for (int i = 0; i<[eventData count]; ++i)
                {
                    [event setTitle:[[eventData objectAtIndex:i] valueForKey:@"eventTitle"]];
                    NSString *startDate = [[eventData objectAtIndex:i] valueForKey:@"startDate"];
                    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
                    [dateFormatter setDateFormat:@"yyyy-MM-dd"];
                    NSDate *eventStrtdate = [dateFormatter dateFromString:startDate];
                    [event setStartDate:eventStrtdate];
                    [event setEndDate:[[NSDate alloc]initWithTimeInterval:1200 sinceDate:event.startDate]];
                    [event setCalendar:[eventStore defaultCalendarForNewEvents]];
                    NSError *err;
                    [eventStore saveEvent:event span:EKSpanThisEvent error:&err];
                }
            }
        }];
    }@end
    

1 个答案:

答案 0 :(得分:0)

关键问题是你在循环之前一次实例化你的事件,因此反复更新同一个事件,而你想要在循环中实例化一个新事件:

// don't instantiate this here
//
// EKEvent *event =[EKEvent eventWithEventStore:eventStore];

for (int i = 0; i<[eventData count]; ++i) {
    // but rather do it here

    EKEvent *event = [EKEvent eventWithEventStore:eventStore];

    // now carry on updating the event and saving it
}

在设置流程方面是否在后台运行每五分钟一次(我假设您的意思是在应用程序未运行时),这不是iOS中通常可能的模式。 Apple只允许在非常狭窄的情况下(导航应用程序,VoIP,音乐应用程序等)进行这种连续的后台操作,因为这种模式会杀死用户的电池(想象一下,如果所有应用程序都这样做了!)。

请参阅 iOS应用程序编程指南中的Background Execution章节。

但是,有两种方法可以用来完成你需要的工作。

  1. 后台获取:这在aforementioned app programming guide中讨论。您无法控制操作系统执行后台获取的频率,但肯定不是每五分钟(更有可能是每天)。操作系统会查看用户使用您的应用程序的频率,新数据的可用频率,设备是否已插入以及无线网络等,以确定检查更新的频率。但它完成了与你所要求的相似的东西,尽管不那么频繁。

  2. 推送通知。如果您参考Local and Remote Notification Programming Guide,您将看到您可以将服务器配置为将通知推送到客户端应用程序,而不是应用程序每隔五分钟不断轮询服务器以获取更新。这是更有效的设计,避免在可能没有任何数据的情况下对服务器进行浪费的查询。