MBProgressHUD 与 NSURLConnection XCode 7
MBProgressHUD with NSURLConnection XCode 7
背景:
请不要将其标记为重复。我已经尝试了所有其他相关的 post,但它们对我不起作用。我看过无数示例 (Whosebug/MBProgressHUD Demo/etc.) 试图让它发挥作用。我觉得大多数示例都已过时,因为某些方法已被弃用。这是我得到的最接近的。
我希望代码做什么:
在我开始连接到 JSON 之前,MBProgress HUD 应该显示带有 "Preparing" 的默认加载屏幕。当我连接时,我希望模式在收到响应时更改为 AnnularDeterminate。加载完成后,我希望进度条显示我将数据添加到字典的进度。完成后,将模式更改为显示复选标记图像和 "Completed".
的 CustomView
问题:
MBProgress HUD 将显示。但是,它只显示默认加载屏幕,其下方有 "Preparing...",然后在进度为 1.0 后,它会显示 "Completed" 并带有复选标记自定义视图。中间没有我更新进度的确定视图。
我的代码
- (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
补充评论
当我尝试添加时
dispatch_async(dispatch_get_main_queue()
在我的连接委托内的所有 MBProgress 方法调用之外,
我再次获得默认加载屏幕。但在进度达到 1.0 后,确定加载屏幕视图显示(完全加载)"Completed",然后在延迟 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
这是一个有用的参考,它涉及 UI不同线程上的调用:
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(), ^{
//...
}
希望这对其他人有帮助。我花了一整天的时间,这是一个如此简单的误会...
背景:
请不要将其标记为重复。我已经尝试了所有其他相关的 post,但它们对我不起作用。我看过无数示例 (Whosebug/MBProgressHUD Demo/etc.) 试图让它发挥作用。我觉得大多数示例都已过时,因为某些方法已被弃用。这是我得到的最接近的。
我希望代码做什么:
在我开始连接到 JSON 之前,MBProgress HUD 应该显示带有 "Preparing" 的默认加载屏幕。当我连接时,我希望模式在收到响应时更改为 AnnularDeterminate。加载完成后,我希望进度条显示我将数据添加到字典的进度。完成后,将模式更改为显示复选标记图像和 "Completed".
的 CustomView问题:
MBProgress HUD 将显示。但是,它只显示默认加载屏幕,其下方有 "Preparing...",然后在进度为 1.0 后,它会显示 "Completed" 并带有复选标记自定义视图。中间没有我更新进度的确定视图。
我的代码
- (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
补充评论
当我尝试添加时
dispatch_async(dispatch_get_main_queue()
在我的连接委托内的所有 MBProgress 方法调用之外, 我再次获得默认加载屏幕。但在进度达到 1.0 后,确定加载屏幕视图显示(完全加载)"Completed",然后在延迟 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
这是一个有用的参考,它涉及 UI不同线程上的调用: 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(), ^{
//...
}
希望这对其他人有帮助。我花了一整天的时间,这是一个如此简单的误会...