iOS应用加载数据时显示活动指示?

时间:2014-02-05 21:18:33

标签: ios grand-central-dispatch

我的iPhone应用程序首次打开时必须加载3个数据集。我有3个视图控制器,每个数据集一个。我注意到,当我在真正的iPhone上并首先打开应用程序并触摸视图控制器时,可能会有一个很长的暂停,我假设正在加载数据,但我不确定。

以下是我AppDelegate中的相关代码:     #import“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

这里是我调用其中一个Web服务并加载数据的地方:

#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];
}

[编辑] 我忘记了我打电话给代码的那部分代码 [编辑]

一个可能的错误是我为三个进程中的每一个使用相同的后台队列?请参阅此位代码顶部的#define kBgQueue

处理此问题的最佳做法是什么?我不应该把它放在后台队列上并提醒用户等待吗?

[谢谢。我改变了这个并重新编译。应用程序第一次启动时,界面会在某个时刻冻结,并且在12秒左右的时间内无法执行任何操作,然后它就会出现。随后没有停顿。例如,当我第一次打开应用程序时,我可以进入我的第一个视图,按姓名雇员,如果我触摸它以列出它们,它可能会进入列表但是空白。因此,我将向后触摸导航,然后停止12秒(左右),然后它将返回主菜单,当我回到那里时,有员工。从那时起它永远不会停止。我无法弄清楚为什么如果这是在背景上它正在阻止界面。我可以跑去试图确定何时发生这种情况?]

1 个答案:

答案 0 :(得分:1)

如果您的应用无法在没有数据的情况下工作,请在后台进行数据处理,并向用户显示一些活动指示。如果你的应用程序可以在没有数据的情况下工作,那么让用户做他想做的任何事情,在加载数据后,只需用新数据重新加载UI。