Firebase 直接从存储中下载图像
Firebase download image from Storage directly
开始使用 Firebase,到目前为止我喜欢它。但现在我在顶 - 试图从存储中下载图像。但是我不想在后台下载图片,我想直接下载它们-希望我清楚。
到目前为止我测试过:
for (NSInteger iLoop=0; iLoop<aFriendsKey.count; iLoop++) {
NSDictionary *dicFriend = [dicFriends objectForKey:[aFriendsKey objectAtIndex:iLoop]];
FIRStorage *storage = [FIRStorage storage];
FIRStorageReference *storageRef = [storage referenceForURL:[dicFriend objectForKey:@"avatarURL"]];
// Download in memory with a maximum allowed size of 1MB (1 * 1024 * 1024 bytes)
[storageRef dataWithMaxSize:5 * 1024 * 1024 completion:^(NSData *data, NSError *error){
if (error != nil) {
// Uh-oh, an error occurred!
} else {
[aFriendsAvatar addObject:data];
}
}];
}
[_tvFriends reloadData];
它工作正常,但图像没有及时下载,这意味着当我重新加载 UITableView 时它们不可用。正如您从之前的代码中看到的,我正在尝试将所有图像加载到 NSMutableArray 中,并使用此 NSMutableArray 在 UITableView 中显示图像。
但由于后台下载和重新加载数据之间的延迟,从未显示任何图像。
有什么想法或解决方案吗?
在加载图像时阻塞主线程不是一个好主意,否则应用程序将变得对用户完全没有响应。相反,您只是想在所有下载完成后收到通知,然后重新加载 table 视图。这可以通过来自 Grand Central Dispatch (GCD) 的 dispatch_group_t
来完成。
dispatch_group_t group = dispatch_group_create();
for (NSInteger iLoop=0; iLoop<aFriendsKey.count; iLoop++) {
NSDictionary *dicFriend = [dicFriends objectForKey:[aFriendsKey objectAtIndex:iLoop]];
FIRStorage *storage = [FIRStorage storage];
FIRStorageReference *storageRef = [storage referenceForURL:[dicFriend objectForKey:@"avatarURL"]];
// Download in memory with a maximum allowed size of 1MB (1 * 1024 * 1024 bytes)
dispatch_group_enter(group);
[storageRef dataWithMaxSize:5 * 1024 * 1024 completion:^(NSData *data, NSError *error){
if (error != nil) {
// Uh-oh, an error occurred!
} else {
[aFriendsAvatar addObject:data]
}
dispatch_group_leave(group);
}];
}
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
[_tvFriends reloadData];
});
您可以将调度组视为未完成操作的简单计数器。在我们开始每次下载之前,我们调用组上的 dispatch_group_enter
来增加它的计数。每次下载完成后,我们调用 dispatch_group_leave
来减少计数。我们用 dispatch_group_notify
注册一个侦听器块,这样当计数达到 0 时,我们的块被调用并且我们知道所有操作都已完成,并且可以安全地重新加载 table 视图。此外,这种方法不会阻塞主线程,这意味着用户仍然可以在下载过程中与 UI 交互。
开始使用 Firebase,到目前为止我喜欢它。但现在我在顶 - 试图从存储中下载图像。但是我不想在后台下载图片,我想直接下载它们-希望我清楚。
到目前为止我测试过:
for (NSInteger iLoop=0; iLoop<aFriendsKey.count; iLoop++) {
NSDictionary *dicFriend = [dicFriends objectForKey:[aFriendsKey objectAtIndex:iLoop]];
FIRStorage *storage = [FIRStorage storage];
FIRStorageReference *storageRef = [storage referenceForURL:[dicFriend objectForKey:@"avatarURL"]];
// Download in memory with a maximum allowed size of 1MB (1 * 1024 * 1024 bytes)
[storageRef dataWithMaxSize:5 * 1024 * 1024 completion:^(NSData *data, NSError *error){
if (error != nil) {
// Uh-oh, an error occurred!
} else {
[aFriendsAvatar addObject:data];
}
}];
}
[_tvFriends reloadData];
它工作正常,但图像没有及时下载,这意味着当我重新加载 UITableView 时它们不可用。正如您从之前的代码中看到的,我正在尝试将所有图像加载到 NSMutableArray 中,并使用此 NSMutableArray 在 UITableView 中显示图像。
但由于后台下载和重新加载数据之间的延迟,从未显示任何图像。
有什么想法或解决方案吗?
在加载图像时阻塞主线程不是一个好主意,否则应用程序将变得对用户完全没有响应。相反,您只是想在所有下载完成后收到通知,然后重新加载 table 视图。这可以通过来自 Grand Central Dispatch (GCD) 的 dispatch_group_t
来完成。
dispatch_group_t group = dispatch_group_create();
for (NSInteger iLoop=0; iLoop<aFriendsKey.count; iLoop++) {
NSDictionary *dicFriend = [dicFriends objectForKey:[aFriendsKey objectAtIndex:iLoop]];
FIRStorage *storage = [FIRStorage storage];
FIRStorageReference *storageRef = [storage referenceForURL:[dicFriend objectForKey:@"avatarURL"]];
// Download in memory with a maximum allowed size of 1MB (1 * 1024 * 1024 bytes)
dispatch_group_enter(group);
[storageRef dataWithMaxSize:5 * 1024 * 1024 completion:^(NSData *data, NSError *error){
if (error != nil) {
// Uh-oh, an error occurred!
} else {
[aFriendsAvatar addObject:data]
}
dispatch_group_leave(group);
}];
}
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
[_tvFriends reloadData];
});
您可以将调度组视为未完成操作的简单计数器。在我们开始每次下载之前,我们调用组上的 dispatch_group_enter
来增加它的计数。每次下载完成后,我们调用 dispatch_group_leave
来减少计数。我们用 dispatch_group_notify
注册一个侦听器块,这样当计数达到 0 时,我们的块被调用并且我们知道所有操作都已完成,并且可以安全地重新加载 table 视图。此外,这种方法不会阻塞主线程,这意味着用户仍然可以在下载过程中与 UI 交互。