iPhone - проблема с загрузкой данных из веб-сервиса в таблицу - PullRequest
0 голосов
/ 15 ноября 2011

Я использую приложение на основе Windows, а затем загружаю свой начальный контроллер на основе навигационной панели в части appDelegate - приложение didFinishLaunchingwithOptions (ОБНОВЛЕНО)

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.

    self.window.rootViewController = self.navigationController;
    [self.window makeKeyAndVisible];
    return YES;
}

Метод получения данных из веб-службы обычно запускается в этом методе viewdidload .... в [self getData]; метод.

- (void)viewDidLoad
{
    [super viewDidLoad];


    if (_refreshHeaderView == nil) {

        EGORefreshTableHeaderView *view = [[EGORefreshTableHeaderView alloc] initWithFrame:CGRectMake(0.0f, 0.0f - self.tableView.bounds.size.height, self.view.frame.size.width, self.tableView.bounds.size.height)];
            view.delegate = self;
        [self.tableView addSubview:view];
        _refreshHeaderView = view;
        [view release];

    }

    //  update the last update date
        [_refreshHeaderView refreshLastUpdatedDate];


        [self loadImages];


    HUDMB = [[MBProgressHUD alloc] initWithView:self.view];
    [self.view addSubview:HUDMB];

    HUDMB.dimBackground = YES;

        // Regiser for HUD callbacks so we can remove it from the window at the right time
    HUDMB.delegate = self;

    HUDMB.labelText = @"Loading..";

    [HUDMB show:TRUE];
    [self getData];
    [self.tableView reloadData];



}

Перед загрузкой, если пользователь не зарегистрирован / не имеет учетных данных, он переводит пользователя в контроллер вида входа в систему.

- (void)loadView {
    [super loadView];

    if([Preferences isValid]?YES:NO)
    {

    }
    else
    {
        int r = arc4random() % 5;


        switch (r) {
            case 0:
            {
                loginViewController *sampleView = [[loginViewController alloc] initWithNibName:@"loginViewController" bundle:nil];
                [self.navigationController presentModalViewController:sampleView animated:YES];
                [sampleView release];
            }
                break;
            case 1:
            {
                loginViewController *sampleView = [[loginViewController alloc] initWithNibName:@"loginViewController" bundle:nil];                
                [sampleView setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
                [self.navigationController presentModalViewController:sampleView animated:YES];
                [sampleView release];
            }
                break;
            case 2:
            {
                loginViewController *sampleView = [[loginViewController alloc] initWithNibName:@"loginViewController" bundle:nil];
                [sampleView setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
                [self.navigationController presentModalViewController:sampleView animated:YES];
                [sampleView release];
            }
                break;
            case 4:
            {
                loginViewController *sampleView = [[loginViewController alloc] initWithNibName:@"loginViewController" bundle:nil];
                [sampleView setModalTransitionStyle:UIModalTransitionStylePartialCurl];
                [self.navigationController presentModalViewController:sampleView animated:YES];
                [sampleView release];
            }
                break;
            case 3:
            {
                loginViewController *sampleView = [[loginViewController alloc] initWithNibName:@"loginViewController" bundle:nil];
                [sampleView setModalTransitionStyle:UIModalTransitionStyleCoverVertical];
                [self.navigationController presentModalViewController:sampleView animated:YES];
                [sampleView release];
            }
                break;

            default:
                break;
        }  
    }


}

Я думаю, что функция getdata создает много проблем. Итак, позвольте мне добавить это, а также соответствующие функции, которые я использую для извлечения данных и сериализации.

-(void)getData{


    NSLog(@"loggin into call sheet page");

    [self getCallSheetData]; 

    NSLog(@"after call sheet");
}

- (void)getCallSheetData
{

    NSString *postCMD = @"Blah... Blah... Blah...";
    NSMutableData *postDataCMD = (NSMutableData *)[postCMD dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
    NSURL *url = [NSURL URLWithString:[Preferences getURL]];
        //    NSLog(@"get call Sheet");
    NSString *postLengthCMD = [NSString stringWithFormat:@"%d", [postDataCMD length]+1];
        //    NSLog(@"The CS String: %@",[Preferences retriveSession]);
    requestCMD = [ASIHTTPRequest requestWithURL:url];
    [requestCMD setURL:url];
    [requestCMD addRequestHeader:@"Content-Length" value:postLengthCMD];
    [requestCMD addRequestHeader:@"Content-Type" value:@"application/x-www-form-urlencoded"];
    [requestCMD addRequestHeader:@"user-Agent" value:@"Mobile 1.4" ];
    [requestCMD addRequestHeader:@"Content-Language" value:@"en-US"];
    [requestCMD addRequestHeader:@"Accept-Encoding" value:@"gzip"];
    [requestCMD addRequestHeader:@"Cookie" value:[Preferences retriveSession]];


    [requestCMD setPostBody:postDataCMD]; 

    [requestCMD setDelegate:self];
    [requestCMD startAsynchronous];
}




- (void)requestFinished:(ASIHTTPRequest *)request
{

    NSMutableArray *CSArray = [[NSMutableArray alloc] init];
    if( [[request responseString] isEqualToString:@"OK"]){
        return;
    }

        // Use when fetching binary data
    NSData *responseData = [request responseData];
    NSDateFormatter *formatter1=[[NSDateFormatter alloc]init];
    [formatter1 setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"];
    NSTimeZone *gmt = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
    [formatter1 setTimeZone:gmt];

    NSDateFormatter *formatterFinal=[[NSDateFormatter alloc]init];
    [formatterFinal setDateStyle:NSDateFormatterMediumStyle];
    [formatterFinal setTimeStyle: NSDateFormatterShortStyle];
    [formatterFinal setLocale:[NSLocale currentLocale]];

    JSONDecoder *jCSArray = [[JSONDecoder alloc]init];



    NSMutableArray *theObject = [jCSArray objectWithData:responseData];
        //        CallSheet= [NSMutableArray arrayWithCapacity:50];





    for(id key in theObject)
    {

        csr = [[CallSheetRecord alloc] init];

            //        cName,cCompany,cId,cMemberId,crcStatus,crcTarget,cImportance,cLastContact  
        csr.importance = @"1";
        csr.rcstatus = @"1";
        csr.rcTarget = @"1";
        csr.company = @"";
        csr.lastContact= @"";

        if([key valueForKey:@"firstName"]  != Nil) 
        {

            csr.name = [NSString stringWithFormat:@"%@",[key valueForKey:@"firstName"]] ;

            if ([key valueForKey:@"lastName"]  != Nil) {
                csr.name = [csr.name stringByAppendingString:@" "];
                csr.name = [csr.name stringByAppendingString:[NSString stringWithFormat:@"%@",[key valueForKey:@"lastName"]]];
            }

        }



        if([key valueForKey:@"company"] != Nil) 
        {

            csr.company = [NSString stringWithFormat:@"%@",[key valueForKey:@"company"]] ;


        }

        if([key valueForKey:@"memberId"]  != Nil) 
        {
            csr.memberId = [NSString stringWithFormat:@"%@",[key valueForKey:@"memberId"]] ;

        }

        if([key valueForKey:@"id"] != Nil) 
        {
            csr.id_ = [NSString stringWithFormat:@"%@",[key valueForKey:@"id"]] ;

        }

        if([key valueForKey:@"lastContact"]  != Nil) 
        {
            NSDate *finalDate =[formatter1 dateFromString:[NSString stringWithFormat:@"%@",[key valueForKey:@"lastContact"]]];


                //NSString *timeStamp = [formatter1 stringFromDate:[finalDate descriptionWithLocale:[NSLocale currentLocale]]];
                //NSLog(@"Time stamp : %@",[finalDate descriptionWithLocale:[NSLocale currentLocale]]);
                //NSLog(@"Time stamp : %@",timeStamp);
                //csr.lastContact = [key valueForKey:@"lastContact"];
            csr.lastContact = [formatterFinal stringFromDate:finalDate];


        }

        if([key valueForKey:@"importance"] != Nil) 
        {
            csr.importance = [NSString stringWithFormat:@"%@",[key valueForKey:@"importance"]];

        }

        if([key valueForKey:@"rcStatus"] != Nil) 
        {
            csr.rcstatus= [NSString stringWithFormat:@"%@",[key valueForKey:@"rcStatus"]] ;

        }

        if([key valueForKey:@"rcTarget"]  != Nil) 
        {
            csr.rcTarget = [NSString stringWithFormat:@"%@",[key valueForKey:@"rcTarget"]] ;

        }


        [CSArray addObject:csr]; 



    }
    CSD = [CSArray mutableCopy];

    [CSArray release];
    [formatter1 release];
    [formatterFinal release];

        //CallSheetArray = [CSArray mutableCopy];
        //[csr release];
    [jCSArray release];

    [HUDMB hide:TRUE];
    [self.tableView reloadData];







}

- (void)requestFailed:(ASIHTTPRequest *)request
{
    NSError *error = [request error];
    UIAlertView *message = [[[UIAlertView alloc] initWithTitle:@"Hello World!"
                                                      message:[NSString stringWithFormat:@"%@",error]
                                                     delegate:nil
                                            cancelButtonTitle:@"OK"
                                            otherButtonTitles:nil]autorelease];

    [message show];


}

затем сразу после этого я пытаюсь загрузить таблицу с помощью [self getData]; , которую я получаю с помощью вызова веб-службы с использованием asiHTTP .. для этого вопроса, скажем, для получения данных требуется 3 секунды и затем десериализовать это. теперь ... мой вопрос, это работает хорошо в более поздних запусках, поскольку я сохраняю имя пользователя и пароль в определенном месте ... но в первую очередь .... я не могу получить данные для загрузки в таблица ... я много чего перепробовал ...

1. Первоначально методы извлечения данных были в разных методах .. поэтому я подумал, что это может быть проблемой, а затем переместил его в то же место, что и tbleviewController (navigationController)

2. Я добавил событие перезагрузить данные в конце функциональности для анализа и десериализации данных ... ничего не происходит.

3. Экран чёрный, на нем ничего не отображается в течение хороших 5 секунд при последовательных запусках приложения .... так что мы могли бы создать что-то вроде MBPorgressHUD для того же.

Может кто-нибудь, пожалуйста, помочь для этих сценариев и руководство о том, какие пути выбрать отсюда. ...

Обновление: Щедрость Просто ответьте на 2 вопроса как можно лучше ... Свойство я попробовал, но это не сработало ... но моя проблема не в этом ... Моя проблема в том, что мой экран не может загрузить данные из веб-сервис после того, как я войду в систему, пока я не сделаю «тянуть, чтобы обновить». Следующий запуск моего приложения занимает около 5 секунд, чтобы показать экран (до тех пор, пока он не покажет черный экран) ... что является лучшим способом показать пустой экран приложений конечному пользователю, когда они попадают в приложение. Я не хочу, чтобы пользователь думал, что приложение не работает или оказало негативное влияние на его телефон.

Ответы [ 2 ]

0 голосов
/ 25 ноября 2011

Вы все еще не дали достаточно информации, чтобы люди могли реально помочь, мы просто догадываемся.

  1. Весьма вероятно, что задержка вызвана getData.Попробуйте закомментировать это или заключить в скобки с NSLog утверждениями для проверки.

  2. Вы должны показать нам больше кода, особенно то, что происходит в getData и любые реализации делегата или обработки уведомлений, связанныедля загрузки данных.

  3. Вам не нужно явно вызывать [tableView reloadData] в viewDidLoad.tableView автоматически загружает данные при первом отображении.

Как сказал @dmatt, если вы загружаете данные асинхронно, тогда getData немедленно вернется без задержки.Обычно вы отвечаете на сообщения или уведомления делегатов (в зависимости от того, как вы загружаете данные), чтобы перезагрузить таблицу после завершения загрузки и сериализации данных.

В SO есть много людей, которые с удовольствиемпопытаться помочь вам, если дано достаточно информации.Особенно, когда вы предлагаете награду.

0 голосов
/ 23 ноября 2011

Здесь есть ряд потенциальных проблем.Первый связан с [self getData] - это блокировка или нет?

1.getData блокирует (синхронно)

Если этот метод блокирует (т.е. не возвращает сразу), это объяснит, почему вы не видите ничего на экране в течение нескольких секунд.В настоящее время вы вызываете этот метод в главном потоке, поэтому он не позволяет обновлять пользовательский интерфейс до его завершения.

Вы можете запустить его в фоновом режиме, выполнив следующее:

- (void) getDataInBackgroundThread
{
   NSAutoReleasePool *pool = [[NSAutoReleasePool alloc] init];

   [self getData];

   // force the table to redraw - UI operations must be on the main thread
   [tableView performSelectorOnMainThread:@selector( reloadData )];

   [pool drain];
}

В вашем основном коде теперь вместо вызова [self getData] вызывайте [self getDataInBackgroundThread];

2.getData не блокирует (асинхронный)

Даже если getData блокирует, если он запускается в основном потоке, он все равно вызывает зависание пользовательского интерфейса.Кроме того, если он использует много процессорного времени, это замедлит работу интерфейса и создаст впечатление, что он не работает в фоновом режиме.

Чтобы решить эту проблему, вам нужно убедиться, что длительная операция getData действительно не выполняется в основном потоке, а также периодически вызывать вызовы sleep (), чтобы дать время для обновления пользовательского интерфейса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...