【问题标题】:MBProgressHUD with NSURLConnection XCode 7MBProgressHUD 与 NSURLConnection XCode 7
【发布时间】:2016-06-15 22:08:57
【问题描述】:

背景:

请不要将此标记为重复。我已经尝试了所有其他相关的帖子,但它们对我不起作用。我看过无数的例子(StackOverflow/MBProgressHUD Demo/etc.)试图让它工作。我觉得大多数示例都已过时,因为某些方法已被弃用。这是我得到的最接近的。

我想让代码做什么:

在我开始连接到 JSON 之前,MBProgress HUD 应该显示带有“正在准备”的默认加载屏幕。当我连接时,我希望在收到响应时将模式更改为 AnnularDeterminate。加载完成后,我希望进度条显示将数据添加到字典的进度。完成后,将模式更改为显示复选标记图像和“已完成”的 CustomView。

问题:

将显示 MBProgress HUD。但是,它仅显示默认加载屏幕,其下方带有“正在准备...”,然后在进度为 1.0 后会显示“已完成”并带有复选标记自定义视图。中间没有我更新进度的确定视图。


我的代码

- (void)viewDidLoad
{
    buildingsDataArray = [[NSMutableArray alloc] init];
    MBProgressHUD *HUD = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
    HUD.delegate = self;
    HUD.label.text = NSLocalizedString(@"Preparing...", @"HUD preparing title");
    [self connect];
    NSLog(@"End of setup");
}

- (void)connect
{
    NSURLRequest *request =[NSURLRequest requestWithURL:[NSURL URLWithString:buildingList]];
    connection = [NSURLConnection connectionWithRequest:request delegate:self];
    [connection start];

   NSLog(@"End of connect");
}


// Connection delegate
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    NSLog(@"connection received response");
    [MBProgressHUD HUDForView:self.view].mode = MBProgressHUDModeAnnularDeterminate;
    NSLog(@"Changed mode");
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [webData appendData:data];
    NSLog(@"connection received data");
    [MBProgressHUD HUDForView:self.view].progress = 0.0f;
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    NSLog(@"Fail with error - %@ %@", [error localizedDescription], [[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
    if ([[error localizedDescription] isEqualToString:@"The Internet connection appears to be offline."]) {
        //do something
    }
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSArray *allDataArray = [NSJSONSerialization JSONObjectWithData:webData options:0 error:nil];
    float count = [allDataArray count];
    float c=1;
    if ([buildingsDataArray count]!=0)
        [buildingsDataArray removeAllObjects];
    for (NSDictionary *dataDict in allDataArray){ //from 1 to 6
        if ([[dataDict objectForKeyedSubscript:@"id"] intValue] != 0)
            [buildingsDataArray addObject:dataDict];
            usleep(200000);
            float p = c/count;
            [MBProgressHUD HUDForView:self.view].progress = p;
            NSLog(@"Progress: %f", [MBProgressHUD HUDForView:self.view].progress);
        });
        c++;
    }
    [MBProgressHUD HUDForView:self.view].customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Checkmark.png"]];
    [MBProgressHUD HUDForView:self.view].label.text = NSLocalizedString(@"Completed", @"HUD done title");
    [MBProgressHUD HUDForView:self.view].mode = MBProgressHUDModeCustomView;
    [[MBProgressHUD HUDForView:self.view] hideAnimated:YES afterDelay:1.0f];
}

这是我的控制台输出

End of connect
End of setup
connection received response
Changed mode
connection received data
connection finished loading
Progress: 0.166667
Progress: 0.333333
Progress: 0.500000
Progress: 0.666667
Progress: 0.833333
Progress: 1.000000

其他 cmets

当我尝试添加时

dispatch_async(dispatch_get_main_queue()

在我的连接委托内的所有 MBProgress 方法调用之外, 我再次获得默认加载屏幕。但是在进度达到 1.0 后,确定的加载屏幕视图显示(完全加载)“已完成”,然后在延迟 1.0 后消失。两者之间仍然没有加载过程。此外,复选标记图像永远不会显示。我不认为这是这样做的方法。

我这样做时的输出是:

End of connect
End of doSetup
connection received response
connection received data
connection finished loading
Changed mode
Progress: 0.166667
Progress: 0.333333
Progress: 0.500000
Progress: 0.666667
Progress: 0.833333
Progress: 1.000000

【问题讨论】:

    标签: xcode asynchronous nsurlconnection mbprogresshud


    【解决方案1】:

    这是一个有用的参考,它基于不同线程上的 UICalls: Is there a way to make drawRect work right NOW?

    这是有效的:

    NSURLConnection 在主线程上被调用。因此,直到连接委托调用完成后,我的所有 UI 更新才会发生。

    所以为了解决这个问题,我将连接放在后台线程中。

    - (void)viewDidLoad{
        //...
    
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{
            NSURL *URL = [NSURL URLWithString:buildingList];
            NSMutableURLRequest *request =[NSMutableURLRequest requestWithURL:URL];
            connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
            [connection setDelegateQueue:[[NSOperationQueue alloc] init]];
            [connection start];
        });
    
    }
    

    在连接委托方法中,我用

    包围了每个 MBProgress 调用
    dispatch_async(dispatch_get_main_queue(), ^{
        //...
    }
    

    希望这对其他人有所帮助。我花了一整天的时间,这是一个如此简单的误解......

    【讨论】:

    • 使用 iOS 9 时,最好使用 NSURLSession。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-25
    • 2012-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-17
    • 1970-01-01
    相关资源
    最近更新 更多