문 제

UIAlertView 메세지를 출력하는 도중 Home 버튼과 같이 예외 상황이 경우 UIAlertView의 Delegate 이벤트가 제대로 진행되지 않은 현상

현 상

문제 소스

- (void) spotDownloader:(SpotDownloader *)downloader didDownloadAll:(int)allSpot
{
    //마지막에
 if(NaNetworkReachable() == NO)
 {     
  [i_downloader stop];
  NaMessageViewWithOneButton(Na_STR_ERROR_NO_NETWORK, @"확인", self);
  return; 
 } 
 
 i_progressView.downloadAllNum = allSpot+i_downedNum;
 i_progressView.downloadNum   = allSpot+i_downedNum;
 i_bDownloading = NO;
 i_downloading  = NO;
 
    WSTown *town = [getThemeCountWithTownId(i_downloadTownId, i_downloadCityId) retain];
   
    [SQLiteForWingSpoon updateTownInformation:i_downloadTownId
         spotCount:town.i_spotCount
         themeCountArray:town.i_themeArray
           updateDate:nil valid:2]; 
 [SQLiteForWingSpoon updateCityInformation:i_downloadCityId
          valid:2];
 
 [town release];
 
    NaMessageViewWithYesNoButtonWithDelay([NSString stringWithFormat: Na_STR_OK_DOWNLOAD, [i_downloadTargetTown i_name] ], self, 1, 0.1);
}


다운로드를 받고 완료 메세지(NaMessageViewWithYesNoButtonWithDelay)를 출력하는 도중 Home버튼을 누르게 되면 아래와 같은 순서로 이벤트가 발생하였다.

1. 다운로드 완료 처리 중(spotDownloader 진행 중)
2. 홈 버튼 클릭
2. UIAlertViewDelegate - willPresentAlertView (Background로 가기전에 AlertView가 준비상태로 돌입)
3. AppDelegate - applicationDidEnterBackground (Background 상태)
4. 앱 재 실행
5. UIAlertViewDelegate - didPresentAlertView (Foreground 이전에 AlertView가 표시)
6. AppDelegate - applicationWillEnterForeground (Foreground 상태가 됨)
6. UIAlertViewDelegate - didDismissWithButtonIndex (AlertView가 저절로 닫힘)

이런순으로 Delegate가 진행되어 문제가 발생되었다. 즉 Foreground 이전에 didPresentAlertView가 호출되어 이미 메세지가 뜬 상태로 있다가 Foreground 호출 이후 didDissmissWithButtonIndex가 호출되어 메세지 창이 저절로 닫혀버리는 현상이다. 더욱이 이런게 닫힌 창이 다른 UIAlertView가 호출될 때 갑자기 나타나는 것이다. 그로 인해 원래 UIAlertView에서 호출되어 처리되어야 하는 View가 아닌 다른 view에서 호출되어 BAD_EXCEPTION 발생하는 문제가 생겼다. (어떤 경우에는 6번 과정 이후 자동으로 다시 willPresentAlertView가 호출되어 다시 출력되어 문제가 안생기는 경우도 있으나 위 상태에서 중단 되는 경우가 문제 였다)


해결방법

1. didDismissWithButtonIndex 이벤트가 발생될 때 매개변수로 넘어오는 alertView의 객체 상태로 비정상 닫기 인지 정상  닫기 인지 구분하는 방법을 찾았다.

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex

alertView == nil 인 경우 정상 닫힘
alertView != nil 인 경우 비정상 닫힘

2. UIAlertView 내 dismissWithClickedButtonIndex 메시지를 호출하여 AlertView를 다시 출력 안되게끔 막는다.
-> UIAlertView 내 메시지들을 찾아보다가 위 메시지의 역할이 사용자의 Action 없이 AlertView를 닫히게하는 기능이 있다는 것을 깨닫고 비정상 닫힌 경우 위 메시지를 호출하여 다른 UIAlertView와 중복 호출이 안되게 끔 방지하였다

3. 마지막으로 닫혀버린 UIAlertView 메시지를 다시 출력하여 사용자가 AlertView 이상 동작을 못느끼게 재실행한다

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex  // after animation
{
    if(alertView.superview != nil){
        // 기존에 비정상 UIAlertView를 오작동 출력을 방지함
        [alertView dismissWithClickedButtonIndex:buttonIndex animated:NO];
        // 메시지 재출력
        NaMessageViewWithYesNoButton([NSString stringWithFormat: Na_STR_OK_DOWNLOAD, [i_downloadTargetTown i_name] ], self, 1);
       
    }
}





+ Recent posts