2014-12-18 2 views
0

비동기 작업에서 주소록의 JSON (NSString *)을 얻으려고하지만 비동기 적으로 완료 블록을 원합니다.objective-c 완료 블록 문제

내가 그러나 나는 다음과 같은 컴파일러 오류가 완료 블록을 추가하고 때, 완료 블록없이 쉬운 검색 관리해야 : 여기 NSString *(^)(bool, CFErrorRef)' to parameter of type 'ABAddressBookRequestAccessCompletionHandler' (aka 'void (^)(bool, CFErrorRef)')

을 통과

호환되지 않는 블록 포인터 타입은 내 코드

입니다
+ (NSString *) getAddressBook:(id (^)())block { 
ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus(); 

if (status == kABAuthorizationStatusDenied) 
{ 
    // if you got here, user had previously denied/revoked permission for your 
    // app to access the contacts, and all you can do is handle this gracefully, 
    // perhaps telling the user that they have to go to settings to grant access 
    // to contacts 
    [[[UIAlertView alloc] initWithTitle:nil message:@"This app requires access to your contacts to function properly. Please visit to the \"Privacy\" section in the iPhone Settings app." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show]; 
    return nil; 
} 
CFErrorRef error = NULL; 
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error); 

if (error) 
{ 
    NSLog(@"ABAddressBookCreateWithOptions error: %@", CFBridgingRelease(error)); 
    if (addressBook) CFRelease(addressBook); 
    return nil; 
} 

if (status == kABAuthorizationStatusNotDetermined) 
{ 
    // present the user the UI that requests permission to contacts ... 
    ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) -> THE ERROR OCCURS HERE ! 
              {... 

문제가 내 완료 블록 내에 있다고 생각하지만 일부 유용한 예제/튜토리얼을 찾을 수 없어 내 특정 문제에 대해 도움이 될 수 있다면 정말 기뻐할 것입니다.

-(void)block:(BOOL)aBool error:(CFErrorRef*)error 

블록이 꽤 있습니다

+0

오류는이 블록이 아무것도 반환하지 기대하면서 블록이 리턴는 NSString * 전달되는 것을 말하고있다. – jamihash

+0

하지만 NSString을 반환하고 싶습니다. -O 어떻게하면됩니까? – ColdSteel

+0

다른 작업을해야하지만 ABAddressBookRequestAccessCompletionHandler를 사용할 수는 없습니다. – jamihash

답변

2

귀하의 문제는이 같은 getAddressBook를 선언하는 (우리가 블록을 제거하는 경우)

-(id)block 

그리고 당신은 유형의 함수로 전달하려고하는 것입니다 (신속하게 개선되는) 구문에 익숙하지 않지만 확실하지 않은 경우이 사이트를 항상 참고하고 있습니다.

block syntax reference

업데이트 :

실제로 비동기 메서드가 완료 될 때까지 기다려야합니다. 또한 official documentation

+ (void) getAddressBook:((^)(NSString* result))block { 
    ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus(); 

    if (status == kABAuthorizationStatusDenied) 
    { 
     // if you got here, user had previously denied/revoked permission for your 
     // app to access the contacts, and all you can do is handle this gracefully, 
     // perhaps telling the user that they have to go to settings to grant access 
     // to contacts 
     [[[UIAlertView alloc] initWithTitle:nil message:@"This app requires access to your contacts to function properly. Please visit to the \"Privacy\" section in the iPhone Settings app." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show]; 
     block(nil); 
    } 
    CFErrorRef error = NULL; 
    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error); 

    if (error) 
    { 
     NSLog(@"ABAddressBookCreateWithOptions error: %@", CFBridgingRelease(error)); 
     if (addressBook) CFRelease(addressBook); 
     block(nil); 
    } 

    if (status == kABAuthorizationStatusNotDetermined) 
    { 


     // present the user the UI that requests permission to contacts ... 
     ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) -> THE ERROR OCCURS HERE ! 
               { 
                NSString* result = whatever 

                block(result); 
               }); 
    } 
} 

을 참조하여 다음과 같이 사용할 수 있습니다

[YourClass getAddressBook:^(NSString* result) 
{ 
    //now you really have result 
}]; 
+0

시도해 보겠습니다. – ColdSteel

+0

편집으로 코드를 게시했습니다. 유용하다고 생각합니다. –

+0

나는 이미 그것을 마쳤다. 그러나 질문이있다. 나는 여전히 블록이 필요한가? 내 메서드 선언>에? – ColdSteel