2013-03-14 2 views
1

주소록에서 선택 항목을 큰 형식으로 표시하는 작은 응용 프로그램을 개발하는 7 학년 및 8 학년 팀을 코치하고 있습니다. callmeapp.org에서 일반적인 프로젝트를 확인하실 수 있습니다. 주소록에 액세스 할 수 있도록 사용자에게 권한을 묻는 메시지가 표시됩니다. 기본적으로 사용자 프롬프트가 올바르게 표시되지 않습니다. 참고로, 설정> 일반> 재설정> 위치 재설정 & 개인 정보를 통해 권한 지우기에 대해 이미 알고 있습니다.주소록 권한 팝업을 맨 위에 표시하려면 어떻게합니까?

우리는 xCode 4.6을 사용 중이며 iPhone MC918LL/A에서 6.1.2 버전을 테스트 중입니다.

우리는 appdelegate.m didfinishlaunchingwithoptions 메소드에서이 스레드의 DavidPhilipOster 응답으로부터 코드를 시작했습니다 : How do I correctly use ABAddressBookCreateWithOptions method in iOS 6?. 우리는 오류를 해결하기 위해 몇 가지 편집 작업을 수행했습니다.

지금 바로 앱이 검은 색 화면으로 시작되어 앱이 닫히는 시점에서 24 초 이상 앉아서 아래에있는 권한 프롬프트를 표시합니다. 받아들이면 우리를 바탕 화면으로 보냅니다. 앱을 다시 열면 권한이 삭제 된 것처럼 작동합니다. 또는 화면이 검은 색 인 동안 홈 버튼 (전화의 사각형 하나)을 누르면 위와 같이 권한 프롬프트가 닫힙니다. permisison 창은 매우 짧은 지연 후 표시해야하며 사용자가 허가하면 우리에게 앱을 남겨 둡니다.

우리는 어떤 일이 일어나고 있는지 확인하기 위해 일부 NSLog 지점에 머물러 있습니다. 도움이 필요한 경우 코드에 남겨 두었습니다. 점 1, 2, 5를 표시 한 다음 기다립니다. 전화가 바탕 화면을 표시하더라도 프롬프트 3, 7 및 4를 지우면 입력됩니다.

도움이나 조언을 주시면 감사하겠습니다.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    NSLog(@"Point 1"); 
    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL,NULL); 

    __block BOOL accessGranted = NO; 

    if (ABAddressBookRequestAccessWithCompletion != NULL) { // we're on iOS 6 
     NSLog(@"Point 2"); 
     dispatch_semaphore_t sema = dispatch_semaphore_create(0); 

     ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) { 
      NSLog(@"Point 3"); 
      accessGranted = granted; 
      dispatch_semaphore_signal(sema); 
      NSLog(@"Point 4"); 
     }); 
     NSLog(@"Point 5"); 

     dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); 
     dispatch_release(sema); 
    } else { // we're on iOS 5 or older 
     NSLog(@"Point 6"); 

     accessGranted = YES; 

    } 
    NSLog(@"Point 7"); 

    return YES; 
} 

답변

10

여기에서 가장 중요한 문제는 didFinishLaunchingWithOptions :에서이 작업을 수행하고 있다는 것입니다. 요컨대, 이것은 다른 장소로 이동해야합니다. iOS는 애플리케이션 시작 프로세스에서 발생하는 일과 그 소요 시간에 대한 제한을 설정합니다. 간단한 응용 프로그램의 경우, 이것을 기본 View Controller로 옮기고 최종 사용자에게 결과를 표시하기 전에이를 확인하십시오.

현재이 메서드에서 세마포를 사용하고 있기 때문에 함수가 반환되지 않습니다. iOS는 기다릴 시간에 대해 엄격한 제한을두고 있습니다. 그런 다음 앱을 죽입니다. 즉, 팝업은 계속 열려 있지만 OK를 누르면 app : didFinishLaunchingWithOptions : 메소드가 제 시간에 실행을 완료하지 않았기 때문에 응용 프로그램이 종료됩니다.

또한 세마포어 접근법을 전혀 추천하지 않습니다. 이것을 해결할 더 좋은 방법이 있습니다 (아래 참조). 아래 코드는 예제 일뿐입니다.

- (void)setupViewWithContactsData 
{ 
    // Do Something 
} 

- (void)setupViewWithoutContactsData 
{ 
    // Do Something because Contacts Access has been Denied or Error Occurred 
} 

- (void)viewDidLoad 
{ 
    [self checkForAddressBookAccess]; 
} 

- (void)checkForAddressBookAccess 
{ 
    if (ABAddressBookRequestAccessWithCompletion == NULL) 
    { 
     // iOS5 or Below 
     [self setupViewWithContactsData]; 
     return; 
    } 
    else 
    { 
     // iOS6 
     if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) 
     { 
      ABAddressBookRequestAccessWithCompletion(addressBookRef, ^(bool granted, CFErrorRef error) { 
      if(error) 
        { 
         [self setupViewWithoutContactsData]; 
        } 
        else 
        { 
         [self setupViewWithContactsData]; 
        } 
      }); 
     } 
     else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) 
     { 
      [self setupViewWithContactsData]; 
     } 
     else 
     { 
      [self setupViewWithoutContactsData]; 
     } 
    } 
} 
+0

너무 빨리 답변 해 주셔서 감사합니다. DataViewController didLoad 메서드로 이동하려고 시도하고 같은 문제가있었습니다. 참고로, 우리는 페이지 뷰 앱 템플릿을 기반으로 애플리케이션을 작성했습니다. – EricPerson

+0

우선, 세마포어 방식은이 경우에는 좋은 방법이 아닙니다. 주 스레드를 차단하는 것과는 대조적으로 비동기 방식을 사용하는 것이 좋습니다. 이 답변을보십시오 : http://stackoverflow.com/questions/12648244/programmatically-request-access-to-contacts-in-ios-6 – dtuckernet

+0

제대로 작동합니다. 도와 주셔서 감사합니다. 그 비밀은 [super viewDidLoad] 행 뒤에 놓여있었습니다. – EricPerson

관련 문제