2012-10-30 1 views
6

저는 처음에 MKNetworkKit에 새로 왔지만 프로젝트에 추가 할 수 있었으며 도달 가능성 변경 사항을 처리 할 때를 제외하고는 완벽하게 작동합니다.도달 가능성 변경시 MKNetworkKit 작업이 다시 시작되지 않거나 완료되지 않습니다.

  1. 내가 무선 랜을 비활성화하고 응용 프로그램을 실행 : 여기

    상황이다.
  2. 도달 가능성이 없어도 MKNetworkEngine 하위 클래스에서 MKNetworkOperation을 생성하여 데이터를 요청합니다 (POST 사용). 데이터를 요청하기 직전에 작업은 고정 가능으로 설정됩니다 (Mugunth Kumar's doc).
  3. WiFi를 활성화하면 MKNetworkEnginecheckAndRestoreFrozenOperations이 호출되고 대기열에 넣으려는 대기 중 작업 (도달 가능성없이 생성 된 작업)이 하나 있음을 감지합니다.
  4. 그 후 내 onCompletion 블록이 호출되지 않습니다.

동결 작업과 연결 가능성에 대해 이해할 수없는 것이 있습니까? MKNetworkKit? 프리즈는 요청이 시작된 후 도달 가능성이 변경되는 작업에 대해서만 작동합니까? 또는 내 자신의 도달 가능성을 변경해야합니까? 블록이 변경 되었습니까?

다음은 작업을 생성하고 요청을 시작하는 내 MKNetworkEngine 하위 클래스의 코드입니다. 관련성이없는 코드는 표시되지 않습니다.

NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObject:@"value" forKey:@"param"]; 
MKNetworkOperation *op = [self operationWithPath:MYPATH 
              params:params 
             httpMethod:@"POST"]; 
[op setFreezable:YES]; 

[op onCompletion:^(MKNetworkOperation *completedOperation) { 
    // ... 
    // Here is where I process response and send the result to my completion block 
    // It's called when WiFi is available, but not called otherwise. 
    // ... 
} onError:^(NSError *error) { 
    // It's called when WiFi is available, but not called otherwise. 
    DLog(@"Some error"); 
}]; 

[self enqueueOperation:op]; 

return op; 
+0

당신이 호스트에서 설정 했 엔진? 고정 된 작업이 처리되는 방식을 보면 엔진에 정의 된 호스트가 없으면 작동하지 않습니다. –

+0

@KenWoo 예. 내 엔진 하위 클래스의 init 메소드는'[super initWithHostName : ]'을 호출합니다. – msoler

+0

@msoler 작동 시키셨습니까? 나는 비슷한 문제가있다 – alandalusi

답변

6

이 두 가지 문제는 재개 대 ​​완료입니다.

  1. 이력서 : 캐시가

    당신은 AppDelegate에 -didFinishLaunchingWithOptions에 -useCache를 호출해야합니다

    활성화 된 경우 고정/고정 취소 메커니즘은 작동합니다

    self.networkEngine = [[MKNetworkEngine alloc] init ...]; 
    [self.networkEngine useCache]; // <- Add this line 
    
  2. 완성 : 완료 콜백은 이 아니며 네트워크 상태가 변경 될 때이 호출되지 않습니다 (즉, Unfreeze 이후)

    그러나 당신은 줄에 -checkAndRestoreFrozenOperations을 행동 (1)를 타고 MKNetworkOperation.m에 중단 점을 배치하면 :

    [self enqueueOperation:pendingOperation] 
    

    하면 네트워크 연결이 복원 될 때 호출되는 것을 발견하고, 그 것 pendingOperation입니다. 보류중인 POST입니다. 그러나 새로운 MKNetworkOperation이 인스턴스화되었으므로 (완료 블록이 더 이상 존재하지 않을 수도 있음) onCompletion 블록이 호출되지 않습니다. 가능한 한 가지 해결 방법은 콜백 대신 알림을 사용하는 것입니다.

  3. 완전한 수정 : (2) 출시를 통해 작동합니다보다보다 강력한 접근 방식은 NSNotifications하여 ^{} 블록 콜백을 교체하는 것입니다. AppDelegate 에서처럼 청취자를 일찍 등록하십시오.다음은 MKNetworkKit 알림을 알기 쉽게하기 위해 필요한 최소 변경 사항입니다.

    3a. MKNetworkOperation.h

    에서 삽입 알림 상수
    #define MKNetworkOperationCompletionNotification @"MKNetworkOperationCompletionNotification" 
    #define MKNetworkOperationErrorNotification @"MKNetworkOperationErrorNotification" 
    

    3B. 방송 MKNetworkOperation.m -operationSucceeded에 성공 통지 (I 그래서 통지가 메인 스레드에서 말을 듣고 UI를 변경할 수 있습니다 말했다 postNotificationOnMainThread를 사용주의 사항, NSOperation and NSNotificationCenter on the main thread 참조)

    -(void) operationSucceeded { 
        NSDictionary * aUserInfo = [NSDictionary dictionaryWithObjectsAndKeys: 
         self, NSStringFromClass([MKNetworkOperation class]), 
         nil]; 
        NSNotification * notification = [NSNotification notificationWithName:MKNetworkOperationCompletionNotification 
         object:nil 
         userInfo:aUserInfo]; 
        [[NSNotificationCenter defaultCenter] postNotificationOnMainThread:notification]; 
        ... 
    

    3C. 방송 MKNetworkOperation.m -operationFailedWithError

    -(void) operationFailedWithError:(NSError*) error { 
        self.error = error; 
        NSDictionary * aUserInfo = [NSDictionary dictionaryWithObjectsAndKeys: 
         self, NSStringFromClass([MKNetworkOperation class]), 
         error, NSStringFromClass([NSError class]), 
         nil]; 
        NSNotification * notification = [NSNotification notificationWithName:MKNetworkOperationErrorNotification 
         object:nil 
         userInfo:aUserInfo]; 
    
        [[NSNotificationCenter defaultCenter] postNotificationOnMainThread:notification]; 
        ... 
    

    차원에서 실패 알림. 청취자가 (등록 해제하는 것을 잊지 마세요)로의 AppDelegate에처럼 오히려 영속 객체를 등록

    // Listen to POST changes 
        NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter]; 
        [defaultCenter addObserver:self 
         selector:@selector(mkNetworkOperationCompletionNotification:) 
         name:MKNetworkOperationCompletionNotification 
         object:nil]; 
        [defaultCenter addObserver:self 
         selector:@selector(mkNetworkOperationErrorNotification:) 
         name:MKNetworkOperationErrorNotification 
         object:nil]; 
    

    3E를. 청취자의 모습 수 있는지의 샘플 코드 :

    - (void)mkNetworkOperationCompletionNotification:(NSNotification*)notification { 
        MKNetworkOperation *operation = [[notification userInfo] 
         objectForKey:NSStringFromClass([MKNetworkOperation class])]; 
        NSLog(@"operationSucceeded: %@", [operation responseString]); 
    } 
    
    - (void)mkNetworkOperationErrorNotification:(NSNotification*)notification { 
        NSError * error = [[notification userInfo] objectForKey:NSStringFromClass([NSError class])]; 
        NSLog(@"operationFailedWithError: %@", [error localizedDescription]); 
    } 
    

이렇게는, 당신은 완료됩니다. X.

(이전 대답 MKNetworkOperation.h 불필요한 제안 된 변경 사항을 제거하고,하기 편집은^{} 한계를 극복하는 방법을 보여 문단 3.을 추가했다.)

+1

답장을 보내 주신 고맙습니다. @ gothicdev. – msoler