Tôi đang đau đầu với chủ đề. Tôi đang làm việc trên một ứng dụng mà cần phải thăm dò ý kiến một máy chủ web thường xuyên, để kiểm tra dữ liệu mới. Dựa trên thông tin được trả lại, tôi muốn gửi thông báo cục bộ cho người dùng.setKeepAliveTimeout và BackgroundTasks
Tôi biết rằng phương pháp này hơi khác so với mô tả được Apple mô tả, trong đó máy chủ từ xa thực hiện công việc, đẩy thông báo từ xa, dựa trên APNS. Tuy nhiên, có nhiều lý do mà tôi không thể xem xét cách tiếp cận này. Một cho tất cả, là cơ chế xác thực người dùng. Máy chủ từ xa, vì lý do bảo mật, không thể tính đến thông tin đăng nhập của người dùng. Tất cả những gì tôi có thể làm là để di chuyển đăng nhập và lấy lõi, cho khách hàng (iPhone).
Tôi nhận thấy rằng Apple cung cấp cơ hội cho các ứng dụng đánh thức và tiếp tục mở kết nối Ổ cắm (ví dụ: ứng dụng VoIP).
Vì vậy, tôi bắt đầu điều tra theo cách này. Thêm thông tin cần thiết trong plist, tôi có thể "đánh thức" ứng dụng của tôi, sử dụng một cái gì đó như thế này trong appdelegate tôi:
[[UIApplication sharedApplication] setKeepAliveTimeout:1200 handler:^{
NSLog(@"startingKeepAliveTimeout");
[self contentViewLog:@"startingKeepAliveTimeout"];
MyPushOperation *op = [[MyPushOperation alloc] initWithNotificationFlag:0 andDataSource:nil];
[queue addOperation:op];
[op release];
}];
Các NSOperation, sau đó bắt đầu một công việc nền sử dụng mã khối như sau:
#pragma mark SyncRequests
-(void) main {
NSLog(@"startSyncRequest");
[self contentViewLog:@"startSyncRequest"];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
NSLog(@"exipiration handler triggered");
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
[self cancel];
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSMutableURLRequest *anURLRequest;
NSURLResponse *outResponse;
NSError *exitError;
NSString *username;
NSString *password;
NSLog(@"FirstLogin");
anURLRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:webserverLogin, username, password]]];
[anURLRequest setHTTPMethod:@"GET"];
[anURLRequest setTimeoutInterval:120.00];
[anURLRequest setCachePolicy:NSURLRequestReloadIgnoringCacheData];
exitError = nil;
NSData *tmpData = [NSURLConnection sendSynchronousRequest:anURLRequest returningResponse:&outResponse error:&exitError];
[anURLRequest setTimeoutInterval:120.00];
if(exitError != nil) { //somethings goes wrong
NSLog(@"somethings goes wrong");
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
[self cancel];
return;
}
//do some stuff with NSData and prompt the user with a UILocalNotification
NSLog(@"AlltasksCompleted");
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
[self cancel];
});
}
}
Đoạn mã trên dường như làm việc (đôi khi), nhưng nhiều người khác nó bị treo ứng dụng của tôi, với các thông tin đăng nhập sau:
Exception Type: 00000020
Exception Codes: 0x8badf00d
Highlighted Thread: 3
Application Specific Information:
DemoBackApp[5977] has active assertions beyond permitted time:
{(
<SBProcessAssertion: 0xa9da0b0> identifier: UIKitBackgroundCompletionTask process: DemoBackApp[5977] permittedBackgroundDuration: 600.000000 reason: finishTask owner pid:5977 preventSuspend preventIdleSleep
)}
Elapsed total CPU time (seconds): 0.010 (user 0.010, system 0.000), 100% CPU
Elapsed application CPU time (seconds): 0.000, 0% CPU
Đối với những người hỏi, vâng. Tôi cũng đã thử phương pháp Async NSURLConnection. Không vấn đề. Nó sụp đổ như nhau, ngay cả khi tôi sử dụng một cách tiếp cận không đồng bộ với xử lý thời gian chờ và didFinishLoading: WithError.
Tôi bị kẹt. Bất kỳ gợi ý nào đều được đánh giá cao.
cảm ơn bạn đã trả lời. Trước hết, từ chối không phải là một vấn đề, vì ứng dụng là một ứng dụng riêng tư không dành cho AppStore. Về thời gian chờ 30 giây, tôi đã đọc về nó, nhưng tôi không thể hiểu tại sao nhật ký sự cố cho tôi biết về thời gian chờ 600.00 giây, chứ không phải 30 giây. Hơn nữa, đôi khi các phương pháp hoạt động, những người khác thì không. – valvoline
@valvoline: Thời gian không hoạt động, nhiệm vụ nền của bạn rõ ràng là mất quá nhiều thời gian. Các tài liệu nói 30 giây, nhưng có lẽ đó là số mềm và hệ điều hành thực sự cung cấp cho bạn 10 phút, tôi không chắc chắn. Tuy nhiên, chúng tôi biết rằng có điều gì đó đang bị chặn và không thể hoàn thành, và vì VIOP được thiết kế để kiểm tra nhanh, có thể việc xử lý lỗi từ hệ điều hành bị nhầm lẫn (như không gọi khối hủy của bạn) . –
@ jason: Bạn có bất kỳ chi tiết cụ thể nào về những gì họ yêu cầu trong cửa sổ VOIP này không? Liệu nó nói rằng bất cứ nơi nào công cộng? –