2015-01-21 1 views
2

У меня есть огромная проблема, я тестировал свое приложение в Метро, ​​и когда я нахожусь в суперплоской зоне обслуживания, приложение временно замораживает (например, 30 sec o 1 мин) на первом экране, начиная приложение из cero, а затем все начинает работать как шарм.Приложение iOS некоторое время зависает при запуске, когда сетевое соединение плохое

У меня есть две функции, которые отвечают за поиск информации в моем WS (ответ JSON), и я установил время ожидания этого NSURLRequest до 2,5 секунд, поэтому, если сервер немного медленнее по какой причине я ищу свои файлы JSON, хранящиеся в iPhone, а не те, которые находятся на сервере.

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

Если я добавляю точки останова в Xcode, все выполняется как всегда (я имею в виду быстрый), а последняя функция, называемая viewWillAppear :.

У кого-нибудь есть схожая проблема? или у кого-нибудь есть представление о том, что может произойти?

Любая мысль будет оценена по достоинству.

Заранее спасибо.

Это те функции я использую, чтобы получить JSON:

-(NSData *)getMainMenuJsonData{ 
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 
    if ([[defaults objectForKey:@"OnLine"] boolValue]) { 
     NSString *urlAsString = [NSString stringWithFormat:@"%@%@/%@/%@",[configs valueForKey:@"wsURL"], [configs valueForKey:@"clientToken"], [configs valueForKey:@"appToken"], [CommonsUtils getCommonUtil].getAppLanguage]; 
     NSURLRequest * urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:urlAsString] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:2.5]; 
     NSURLResponse * response = nil; 
     NSError * error = nil; 
     NSData * data = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&error]; 

     plistPath = [[NSBundle mainBundle] pathForResource:@"Config" ofType:@"plist"]; 
     configs = [[NSDictionary alloc] initWithContentsOfFile:plistPath]; 
     NSUInteger statusCode = ((NSHTTPURLResponse *)response).statusCode; 

     if (statusCode == 200 && error == Nil) { 
      if (error != Nil) { 
       return Nil; 
      } else { 
       return data; 
      } 
     } 
     else { 
      return Nil; 
     } 
    } 
    else { 
     return Nil; 
    } 
} 

-(NSData *)getSpecificJsonData:(NSString *)itemId{ 
    NSString *urlAsString = [NSString stringWithFormat:@"%@%@/%@/%@/%@",[configs valueForKey:@"wsURL"], [configs valueForKey:@"clientToken"], [configs valueForKey:@"appToken"], [CommonsUtils getCommonUtil].getAppLanguage, itemId]; 
    NSURLRequest * urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:urlAsString] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:2.5]; 
    NSURLResponse * response = nil; 
    NSError * error = nil; 
    NSData * data = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&error]; 

    plistPath = [[NSBundle mainBundle] pathForResource:@"Config" ofType:@"plist"]; 
    configs = [[NSDictionary alloc] initWithContentsOfFile:plistPath]; 
    NSUInteger statusCode = ((NSHTTPURLResponse *)response).statusCode; 

    if (statusCode == 200 && error == Nil) { 
     if (error != Nil) { 
      return Nil; 
     } else { 
      return data; 
     } 
    } 
    else { 
     return Nil; 
    } 
} 

И это весь код моего главного экрана, после загрузки и viewWillAppear: называется, если я прикоснуться к одной из кнопок на экран это занимает некоторое время (например, 30 сек 1 мин о) для выполнения btnAction: функция:

// 
// vcMainScreen.m 
// SmartHotel 
// 
// Created by GoSmart on 08/07/13. 
// Copyright (c) 2013 GoSmart. All rights reserved. 
// 

#import "vcMainScreen.h" 
#import "Util.h" 
#import "Reachability.h" 
#import "CommonsUtils.h" 

@interface vcMainScreen() 
@property (nonatomic) Reachability *reachabilityInfo; 
@end 

@implementation vcMainScreen { 
    NSDictionary *dValue; 
    NSData *jsonData; 
    NSDictionary *dConfiguration, *configs, *languages; 
    Util *util; 
    BOOL ok; 
    NSString *plistPath, *language; 
} 

@synthesize tabController; 

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
{ 
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 
    if (self) { 

    } 
    return self; 
} 

- (void)viewDidLoad 
{ 
    _reachabilityInfo = [Reachability reachabilityWithHostname:@"www.google.com"]; 
    [_reachabilityInfo startNotifier]; 

    [super viewDidLoad]; 
    util = [[Util alloc] crearUtil]; 
    [[self navigationController] setNavigationBarHidden:YES animated:NO]; 

    NetworkStatus internetStatus = [_reachabilityInfo currentReachabilityStatus]; 
    NSData *mainData = Nil; 
    if (internetStatus != NotReachable) 
    mainData = [util getMainMenuJsonData]; 

    if (mainData != Nil) { 
     jsonData = mainData; 
    } 
    else { 
     plistPath = [[NSBundle mainBundle] pathForResource:@"Config" ofType:@"plist"]; 
     configs = [[NSDictionary alloc] initWithContentsOfFile:plistPath]; 
     languages = [configs valueForKey:@"Languages"]; 

     for (NSString * appLanguage in [NSLocale preferredLanguages]) 
     { 
      language = [[languages valueForKey:appLanguage] objectAtIndex:0]; 
      if ([language isEqual:[NSNull null]]) { 
       language = [[languages valueForKey:@"default"] objectAtIndex:0]; 
      } 
      else{ 
       break; 
      } 
     } 

     NSString *jsonPath = [NSString stringWithFormat:@"%@/%@.json",[NSSearchPathForDirectoriesInDomains (NSDocumentDirectory,NSUserDomainMask, YES) objectAtIndex:0],language]; 
     jsonData = [NSData dataWithContentsOfFile:jsonPath]; 
    } 

    dConfiguration =[NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:nil]; 
    [self createTabBar]; 
    NSInteger count = 0; 
    for (UIView* subView in self.view.subviews) 
    { 
     if ([subView isKindOfClass:[UIButton class]]) { 
      UIButton *bCustom = (UIButton *)subView; 
      [bCustom addTarget:self action:@selector(btnAction:) forControlEvents:UIControlEventTouchUpInside]; 
      count ++; 
     } 
    } 
    dValue = [[dConfiguration objectForKey:@"BackgroundImage"] objectAtIndex:0]; 
    _ivBackGround.image = [UIImage imageNamed:[util getBackgroundImageName:[dValue objectForKey:@"Image"] andRetrina:[dValue objectForKey:@"ImageRetina"]]]; 
    self.navigationItem.title = @"Home"; 
} 

- (void)viewWillAppear:(BOOL)animated 
{ 
    [self.navigationController setNavigationBarHidden:YES animated:animated]; 
    [super viewWillAppear:animated]; 

    // Tracking view for analytics 
    id tracker = [[GAI sharedInstance] defaultTracker]; 
    [tracker set:kGAIScreenName value:self.navigationItem.title]; 
    [tracker send:[[GAIDictionaryBuilder createAppView] build]]; 
} 

- (void)viewWillDisappear:(BOOL)animated 
{ 
    [self.navigationController setNavigationBarHidden:YES animated:animated]; 
    [super viewWillDisappear:animated]; 
} 

- (BOOL)shouldAutorotate 
{ 
    return YES; 
} 

- (NSUInteger)supportedInterfaceOrientations 
{ 
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { 
     return UIInterfaceOrientationMaskPortrait; 
    } else { 
     return UIInterfaceOrientationMaskAll; 
    } 
} 

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation 
{ 
    return UIInterfaceOrientationPortrait; 
} 

- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
} 

- (void)createTabBar 
{ 
    tabController = [self.storyboard instantiateViewControllerWithIdentifier:@"cCustomTabController"]; 
    dValue = [dConfiguration objectForKey:@"Buttons"]; 
    NSMutableArray *aControllers = [[NSMutableArray alloc] init]; 
    int i = 0; 
    for (NSString* sProperty in dValue) { 
     NSString* d = @"Details"; 
     NetworkStatus internetStatus = [_reachabilityInfo currentReachabilityStatus]; 
     NSData *itemData = Nil; 
     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 
     if (internetStatus != NotReachable && [[defaults objectForKey:@"OnLine"] boolValue]) 
      itemData = [util getSpecificJsonData:[sProperty valueForKeyPath:@"Item"]]; 
     if(itemData != nil){ 
      UIStoryboard *aStoryboard = [UIStoryboard storyboardWithName:@"Main_iPhone" bundle:[NSBundle mainBundle]]; 
      UIViewController *vcCustom = [aStoryboard instantiateViewControllerWithIdentifier:[util getControllerName:[sProperty valueForKeyPath:@"ViewController"]]]; 
      [vcCustom setValue:itemData forKey:@"JsonData"]; 
      [vcCustom setValue:[sProperty valueForKeyPath:@"Item"] forKey:@"Item"]; 
      [vcCustom setValue:d forKey:@"Details"]; 
      [util saveJSON:itemData withName:[NSString stringWithFormat:@"%@%@",[sProperty valueForKeyPath:@"Item"],[CommonsUtils getCommonUtil].getAppLanguage]]; 
      [[vcCustom navigationController] setNavigationBarHidden:NO animated:NO]; 
      vcCustom.navigationItem.leftBarButtonItem = Nil; 
      vcCustom.navigationItem.hidesBackButton = YES; 
      UIImage *imageBtn = [UIImage imageNamed:[util getImageName:[sProperty valueForKeyPath:@"Image"] andRetrina:[sProperty valueForKeyPath:@"ImageRetina"]]]; 
      UIImage *imageBtnPress = [UIImage imageNamed:[util getImageName:[sProperty valueForKeyPath:@"ImageHeighlighted"] andRetrina:[sProperty valueForKeyPath:@"ImageRetinaHeighlighted"]]]; 
      UITabBarItem *tab = [[UITabBarItem alloc] initWithTitle:[sProperty valueForKeyPath:@"Title"] image:imageBtn selectedImage:imageBtnPress]; 
      UIImage * iSelected = imageBtnPress; 
      iSelected = [iSelected imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; 
      [tab setSelectedImage:iSelected]; 
      tab.tag = i; 
      if([[sProperty valueForKeyPath:@"Title"] isEqualToString:@"Notificaciones"]) 
       tab.badgeValue=[sProperty valueForKeyPath:@"Badge"]; 
      [vcCustom setTabBarItem:tab]; 
      [vcCustom setTitle:[sProperty valueForKeyPath:@"Title"]]; 
      UINavigationController *navigationController = [[cCustomNavigationController alloc] initWithRootViewController:vcCustom]; 
      navigationController.navigationBar.tintColor = [UIColor colorWithRed:36.0/255.0 green:134.0/255.0 blue:232.0/255.0 alpha:1]; 
      [aControllers insertObject:navigationController atIndex:i]; 
      i++; 
     } 
     else 
     { 
      UIStoryboard *aStoryboard = [UIStoryboard storyboardWithName:@"Main_iPhone" bundle:[NSBundle mainBundle]]; 
      UIViewController *vcCustom = [aStoryboard instantiateViewControllerWithIdentifier:[util getControllerName:[sProperty valueForKeyPath:@"ViewController"]]]; 
      NSNumber *val = [NSNumber numberWithInteger:i]; 
      NSString *nextJson = [sProperty valueForKeyPath:@"JsonConfigFile"]; 
      [vcCustom setValue:[sProperty valueForKeyPath:@"Item"] forKey:@"Item"]; 
      [vcCustom setValue:nextJson forKey:@"JsonConfigFile"]; 
      [vcCustom setValue:val forKey:@"MenuButtonSelectedTag"]; 
      [[vcCustom navigationController] setNavigationBarHidden:NO animated:NO]; 
      vcCustom.navigationItem.leftBarButtonItem = Nil; 
      vcCustom.navigationItem.hidesBackButton = YES; 
      UIImage *imageBtn = [UIImage imageNamed:[util getImageName:[sProperty valueForKeyPath:@"Image"] andRetrina:[sProperty valueForKeyPath:@"ImageRetina"]]]; 
      UIImage *imageBtnPress = [UIImage imageNamed:[util getImageName:[sProperty valueForKeyPath:@"ImageHeighlighted"] andRetrina:[sProperty valueForKeyPath:@"ImageRetinaHeighlighted"]]]; 
      UITabBarItem *tab = [[UITabBarItem alloc] initWithTitle:[sProperty valueForKeyPath:@"Title"] image:imageBtn selectedImage:imageBtnPress]; 
      UIImage * iSelected = imageBtnPress; 
      iSelected = [iSelected imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; 
      [tab setSelectedImage:iSelected]; 
      tab.tag = i; 
      if([[sProperty valueForKeyPath:@"Title"] isEqualToString:@"Notificaciones"]) 
       tab.badgeValue=[sProperty valueForKeyPath:@"Badge"]; 
      [vcCustom setTabBarItem:tab]; 
      [vcCustom setTitle:[sProperty valueForKeyPath:@"Title"]]; 
      UINavigationController *navigationController = [[cCustomNavigationController alloc] initWithRootViewController:vcCustom]; 
      navigationController.navigationBar.tintColor = [UIColor colorWithRed:36.0/255.0 green:134.0/255.0 blue:232.0/255.0 alpha:1]; 
      [aControllers insertObject:navigationController atIndex:i]; 
      i++; 
     } 


    } 
    tabController.delegate = self; 
    tabController.viewControllers = aControllers; 
    tabController.tabBar.tintColor = [UIColor blackColor]; 
} 

-(BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController{ 
    return YES; 
} 

- (IBAction)btnAction:(id)sender { 
    UIButton *bCustom = (UIButton *)sender; 

    tabController.selectedIndex = bCustom.tag; 

    id<GAITracker> tracker= [[GAI sharedInstance] defaultTracker]; 

    [tracker send:[[GAIDictionaryBuilder createEventWithCategory: @"ui_button" 
                  action: @"button_press" 
                  label: [NSString stringWithFormat:@"%@-%@", self.title, [[tabController.viewControllers objectAtIndex:bCustom.tag] title]] 
                  value: nil] build]]; 

    [self.navigationController pushViewController:tabController animated:YES]; 
} 

@end 

Это такие настройки в моем iPhone:

Network settings

+0

Ваша проблема в том, что вы используете 'sendSynchronousRequest'. Из документа: «Вызывающий поток блокируется, когда асинхронная система загрузки выполняет загрузку URL [...]». Как ваш вызов, что из основного потока вы блокируете его, и пользовательский интерфейс становится невосприимчивым. Это отлично работает на стабильном и быстром подключении к Интернету, потому что приложение зависает в течение нескольких миллисекунд, но в плохой сети повесить будет очень заметно. –

+0

@GuillaumeAlgis Но я не понимаю, почему, когда ответ UI снова, все работает как шарм, я вызываю getSpecificJsonData: itemId каждый раз при нажатии кнопки, поэтому его нельзя отправитьSynchronousRequest, который будет постоянно замораживать мой экран, в факт, когда я нахожусь в режиме самолёта, приложение стало немного медленным (2,5 секунды) каждый раз, когда я касаюсь кнопки, и поведение ожидается, но при низком охвате при запуске приложения замораживание UI и затем работает, m в режиме самолета (2,5 секунды медленно при каждом нажатии кнопки a) –

+0

@GuillaumeAlgis ПРИМЕЧАНИЕ. Я обнаружил, что иногда функция NetworkStatus internetStatus = [_reachabilityInfo currentReachabilityStatus] возвращает NotReachable, а некоторые другие возвращают ReachableViaWWAN, если это ReachableViaWWAN, это будет выполните sendSynchronousRequest, и когда он вернет NotReachable, он не выполнит sendSynchronousRequest, и в обоих случаях пользовательский интерфейс заморозится, это сводит меня с ума –

ответ

2

Там нет правильного ответа на этот вопрос, я был сделать вызов в потоке к моему WS в AppDelegate, который делает замораживание UI, благодаря словам @Guillaume Algis и this я смог найти и решить мою проблему.

Как всегда, спасибо за вашу помощь.