如何从iOS中的URL数组预加载图像?
我有一个音乐应用程序,我想预装专辑艺术。现在,当你点击下一首歌曲时,它会从一个URL加载相册艺术,但如果它已经预装并存储在内存中,那就太好了。我试过一些方法,但似乎都不管用。有人知道一种技术吗?我可以在iOS中预加载图像,然后稍后查找该图像,如果没有,则下载该图像 编辑更多细节… 当我在我的应用程序上播放“电台”时,我会向服务器发出请求,该服务器会返回播放列表的JSON。在这个JSON里面是每首歌以及包括专辑艺术URL在内的数据。当用户去播放“电台”时,我希望为堆栈中的下一个唱片集艺术URL或整个播放列表中的所有唱片集艺术URL预加载图像 无论如何,我已经尝试过在背景中的UIImage中加载下一张专辑艺术URL,就像如何从iOS中的URL数组预加载图像?,ios,objective-c,Ios,Objective C,我有一个音乐应用程序,我想预装专辑艺术。现在,当你点击下一首歌曲时,它会从一个URL加载相册艺术,但如果它已经预装并存储在内存中,那就太好了。我试过一些方法,但似乎都不管用。有人知道一种技术吗?我可以在iOS中预加载图像,然后稍后查找该图像,如果没有,则下载该图像 编辑更多细节… 当我在我的应用程序上播放“电台”时,我会向服务器发出请求,该服务器会返回播放列表的JSON。在这个JSON里面是每首歌以及包括专辑艺术URL在内的数据。当用户去播放“电台”时,我希望为堆栈中的下一个唱片集艺术URL或整
temporaryAlbumArt
一样,然后在播放下一首歌曲时,只需执行albumArt=temporaryAlbumArt
,然后重复将下一首歌曲专辑艺术设置为temp的过程,依此类推
我试过这样的方法:
if (temporaryAlbumArt) {
albumArt = temporaryAlbumArt
} else {
albumArt = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:firstAlbumArtURL]]];
}
temporaryAlbumArt = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:nextAlbumArtURL]]];
我想我的问题是,什么是最好的方法:
- 将一个或多个图像从URL加载到内存中
- 以后使用这些图像时不会出现任何延迟
#define GET_QUEUE dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
// while song is playing...
dispatch_async(GET_QUEUE, ^{
// On a separate thread look for the image locally in the cache and then
// download it if necessary
});
我不确定这是否回答了你的问题
好的,这里有更多的代码-基本上它让我在上下文中问一些有帮助的问题
// Inside some loop/method that plays songs...
if (temporaryAlbumArt)
albumArt = temporaryAlbumArt
else
albumArt = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:firstAlbumArtURL]]];
// If this keeps executing then perhaps temporaryAlbumArt is getting released somehow?
// Are you persisting it correctly through each iteration/method call?
// show art...
// start music
// Call art update
dispatch_async(GET_QUEUE, ^{
temporaryAlbumArt = nil; // In case the data hasn't been obtained yet on the next iteration???
temporaryAlbumArt = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:nextAlbumArtURL]]];
// This works ok then? Can you make sure this is completing correctly before the next iteration/method call?
});
很抱歉,我无法提供更多帮助。此库满足您的需要: 循环浏览URL,通过JMImageCache下载它们,当您需要显示图像时,如果下载完成,库将获取存储的图像
//You can do this when you get the array of urls to download the images in the background
for(NSURL *url in urls) {
[[JMImageCache sharedCache] imageForURL:url];
}
//and then when you need an image:
[imageView setImageWithURL:url placeholder:[UIImage imageNamed:@"placeholder.png"]];
您可以使用此“必备”工具。它支持你所需要的一切 我编写了这段代码,从服务器下载数据并将数据保存到文档目录中,这样下次如果有人点击相同的url,就可以从文档目录中获取数据,而不需要点击任何服务器
-(void)downloadImageForProductsFromArray:(NSArray *)inventoryArr {
BOOL isAllDataDownloaded = YES;
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.labelText = @"Data Sync...";
[[NSOperationQueue mainQueue] addObserver:self forKeyPath:@"operations" options:0 context:nil];
for (int i = 0; i < inventoryArr.count; i++) {
NSString *productUrlStr = [inventoryArr objectAtIndex:i];
NSData *dirData = [CommonUtils fetchImageDataFromDirectoryWithImageName: productUrlStr];/*****Check whether Image data is already downloaded and saved in document directory*****/
if (!dirData) {
isAllDataDownloaded = NO;
NSBlockOperation *downloadImgOpr = [[NSBlockOperation alloc] init];
downloadImgOpr.queuePriority = NSOperationQueuePriorityVeryHigh;
downloadImgOpr.qualityOfService = NSQualityOfServiceUserInitiated;
[downloadImgOpr addExecutionBlock:^{
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString: productUrlStr]];
if (imageData) {
/*****Save Image Data in Document Directory*****/
}
}];
}
}
if (isAllDataDownloaded) {
[MBProgressHUD hideAllHUDsForView:self.view animated:YES];
}}
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context{
if (object == [NSOperationQueue mainQueue] && [keyPath isEqualToString:@"operations"]) {
if ([[NSOperationQueue mainQueue].operations count] == 0) {
// Do something here when your queue has completed
[MBProgressHUD hideAllHUDsForView:self.view animated:YES];
NSLog(@"queue has completed");
}
}
else {
[super observeValueForKeyPath:keyPath ofObject:object
change:change context:context];
}
-(void)下载产品的图像Romarray:(NSArray*)清单Arr{
BOOL isAllDataDownloaded=是;
MBProgressHUD*hud=[MBProgressHUD showhuddeto:self.view动画:YES];
hud.labelText=@“数据同步…”;
[[NSOperationQueue mainQueue]addObserver:self forKeyPath:@“操作”选项:0上下文:nil];
for(int i=0;i
}
在这段代码中,我拥有清单数组中的所有url字符串。在for循环中,我进行了一些操作,并将这些操作添加到队列中(我使用了主队列来保存UI和同步数据。适当地选择您的队列。)。此外,我还将KVO添加到了关键路径值“操作”的队列中因此,如果操作计数为0,我们可以执行有用的操作。更具体一些。你试过什么不起作用的?我同意,你具体在努力解决哪一部分?算法?密码?一些澄清将帮助我们帮助您!;)我做了一些更新,但我不确定它们是否有用:(这正是我一直试图做的,但我想知道在背景中加载图像,然后在调用下一个曲目时使用同一图像的最佳方法是什么。当我这样做时:
UIImage*image=[UIImage imageWithData:[NSData DATA WITHCONTENTSOFURL:[NSURL URLWithString:MyURL]]
然后在下一首歌中使用相同的UIImage,它似乎不起作用。它会继续运行并重新加载图像。嗯,我想我们需要更多的代码来查看…听起来好像你在调用该方法,而你不应该这样做。我会用更多的信息更新我的答案,但之后我就要去睡觉了!祝你好运!谢谢,不我在我的问题中添加了一些我尝试过的细节。这正是我一直在尝试的