2014-02-05 1 views
1

내 iPhone 앱을 처음 열 때 3 개의 데이터 세트를로드해야합니다. 3 개의 뷰 컨트롤러가 있으며 각 데이터 세트마다 하나씩 있습니다. 나는 진짜 아이폰에있을 때 먼저 앱을 열고 뷰 컨트롤러를 터치하면 데이터가로드되는 동안 매우 긴 일시 중지가 발생할 수 있음을 알지만 확실하지 않습니다. 여기 iOS 앱이 데이터를로드 할 때 활동 표시기를 표시 하시겠습니까?

AppDelegate의 관련 코드입니다 : "AppDelegate.h" # import를 "MasterViewController.h"

@implementation AppDelegate 

- (void)application:(UIApplication *)application performFetchWithCompletionHandler: (void (^)(UIBackgroundFetchResult))completionHandler 
{ 
    // Background Fetch for Employees 
    EmployeeDatabase *tmpEmployeeDatabase = [[EmployeeDatabase alloc] init]; 
    [tmpEmployeeDatabase updateEmployeeData]; 
    completionHandler(UIBackgroundFetchResultNewData); 
} 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 

    // Set Background Fetch Interval 
    [application setMinimumBackgroundFetchInterval: UIApplicationBackgroundFetchIntervalMinimum]; 

    // Take Database Name and get DatabasePath for later use 
    self.databaseName = @"employees.db"; 
    self.databaseNameLocations = @"locations.db"; 
    self.databaseNameContacts = @"contacts.db"; 
    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentDir = [documentPaths objectAtIndex:0]; 
    self.databasePath =[documentDir stringByAppendingPathComponent:self.databaseName]; 
    self.databasePathLocations =[documentDir stringByAppendingPathComponent:self.databaseNameLocations]; 
    self.databasePathContacts =[documentDir stringByAppendingPathComponent:self.databaseNameContacts]; 

    // See if we need to initialize the employee db 
    EmployeeDatabase *tmpEmployeeDatabase = [[EmployeeDatabase alloc] init]; 
    if (![tmpEmployeeDatabase checkIfDatabaseExists]) { 
     [tmpEmployeeDatabase updateEmployeeData]; 
    } 

    // See if we need to initialize the contact db 
    ContactsDatabase *tmpContactsDatabase = [[ContactsDatabase alloc] init]; 
    if (![tmpContactsDatabase checkIfDatabaseExists]) { 
     [tmpContactsDatabase updateContactsData]; 
    } 

    // See if we need to initialize the Locations db 
    LocationDatabase *tmpLocationDatabase = [[LocationDatabase alloc] init]; 
    if (![tmpLocationDatabase checkIfDatabaseExists]) { 
     [tmpLocationDatabase updateLocationData]; 
    } 

    return YES; 
} 

#pragma mark - Application's Documents directory 

// Returns the URL to the application's Documents directory. 
- (NSURL *)applicationDocumentsDirectory { 
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; 
} 

@end 

# import를 그리고 여기가 웹 서비스 중 하나를 호출하고로드 할 곳이다 데이터 :

#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) 
- (void)callWebService { 

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; 
    manager.requestSerializer = [AFJSONRequestSerializer serializer]; 
    [manager.requestSerializer setAuthorizationHeaderFieldWithUsername:@"xxxxxx" password:@"xxxxxxxxxxxx"]; 
    manager.responseSerializer = [AFJSONResponseSerializer serializer]; 

    AFHTTPRequestOperation *operation = [manager GET: @"https://xxxx/mobile/mobilede.nsf/restPeople.xsp/People" 
      parameters: [self jsonDict] 
      success: ^(AFHTTPRequestOperation *operation, id responseObject) 

     { 
       NSMutableArray *employees = (NSMutableArray *)responseObject; 
       FMDatabase *db = [FMDatabase databaseWithPath:self.employeeDatabasePath]; 
       [db open]; 
       for (NSDictionary *dict in employees) { 
       BOOL success = [db 
        executeUpdate: 
         @"INSERT INTO employees " 
         "(id,fstNme,midNme,lstNme,fulNme,locNbr,supID," 
         "mrkSeg,geoLoc,lvl,vp,ema,ofcPhn,mobPhn) VALUES " 
         "(?,?,?,?,?,?,?,?,?,?,?,?,?,?);", 
         [dict objectForKey:@"id"], [dict objectForKey:@"fstNme"], 
         [dict objectForKey:@"midNme"], [dict objectForKey:@"lstNme"], 
         [dict objectForKey:@"fulNme"], [dict objectForKey:@"locNbr"], 
         [dict objectForKey:@"supId"], [dict objectForKey:@"mrkSeg"], 
         [dict objectForKey:@"geoLoc"], [dict objectForKey:@"lvl"], 
         [dict objectForKey:@"vp"], [dict objectForKey:@"ema"], 
         [dict objectForKey:@"ofcPhn"],[dict objectForKey:@"mobPhn"], nil]; 
       if (success) { 
       } // Only to remove success error 
       } 
     } 

     failure: 
      ^(AFHTTPRequestOperation * operation, NSError * error) { 
      NSLog(@"Error: %@", error); 
      } 
    ]; 
    [operation start]; 
} 
I 내가 [EDIT]

012 불리는 코드의 일부를 잊었다 [EDIT]

한 가지 가능한 실수는 세 가지 프로세스 각각에 대해 동일한 백그라운드 대기열을 사용하고 있다는 것입니다. 이 코드의 맨 위에있는 #define kBgQueue을 참조하십시오.

이 문제를 해결하는 가장 좋은 방법은 무엇입니까? 나는 이것을 배경 대기열에 두지 말고 기다려야한다고 경고해야합니까?

[감사합니다. 나는 이것을 변경하고 다시 컴파일했다. 앱이 처음 시작될 때 인터페이스가 언젠가는 멈추고 12 초 정도는 아무 것도 할 수 없으며 인터페이스가 종료됩니다. 이어서 일시 중지가 없습니다. 예를 들어, 앱을 처음 열면 Employees by Name이라는 첫 번째보기로 이동할 수 있습니다. 목록에 표시하면 목록에 표시 될 수도 있지만 비워 둘 수 있습니다. 그래서 네비게이션을 뒤로 터치 한 다음 12 초 동안 멈추고 메인 메뉴로 돌아갑니다. 내가 다시 들어가면 직원들이 있습니다. 그리고 그때부터 멈추지 않습니다. 나는 이것이 배경 대기열에 있다면 그것이 인터페이스를 고수하고있는 이유를 알 수 없다. 이 문제가 언제 발생하는지 판단하기 위해 무엇을 실행할 수 있습니까?]

+0

데이터로드 메소드를 실제로 전달하는 코드를 표시하십시오. – rocky

+0

죄송합니다. 죄송합니다. 코드가 추가되었습니다. –

+0

백그라운드 스레드에서 실행될 때 UI에 일시 중지가 없어야한다고 생각합니다. 데이터가 없을 수도 있고 계정도 있어야하지만 UI가 실제로 업데이트 될 때까지 일시 중지 할 필요는 없습니다. 백그라운드 스레드의 UI도 업데이트하고 있습니까? 그것은 항상 주 프로세스에서 수행되어야합니다. – ansible

답변

1

데이터없이 데이터를 처리 할 수없는 경우 데이터를 백그라운드에서 처리하고 사용자에게 몇 가지 활동 표시기를 표시합니다. 응용 프로그램이 데이터없이 작동 할 수 있다면 사용자가 원하는 모든 작업을 수행 할 수 있으며 데이터가로드 된 후에 UI에 새 데이터를 다시로드하면됩니다.

+0

내 앱이 데이터없이 작동하지 않으므로 일부 활동 표시기를 표시해야합니다. 친절하게도이 일을하는 방법에 대해 가르쳐 주시겠습니까? –

+0

데이터가 백그라운드 스레드에로드되고 저장되는지 확인하십시오. 메인 스레드에서 애니메이션 액티비티 표시기를 보여줍니다 (예를 들어 보이는 뷰 컨트롤러 위에 흰색 UIActivityIndicator가있는 어두운 투명 UIView의 맨 위에 추가). – Moonkid

+0

#define kBgQueue dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)는 백그라운드 대기열이 아닙니다. DISPATCH_QUEUE_PRIORITY_BACKGROUND는 (는) 백그라운드 대기열이 아닙니다. – Moonkid