Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/96.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从iOS中的URL数组预加载图像?_Ios_Objective C - Fatal编程技术网

如何从iOS中的URL数组预加载图像?

如何从iOS中的URL数组预加载图像?,ios,objective-c,Ios,Objective C,我有一个音乐应用程序,我想预装专辑艺术。现在,当你点击下一首歌曲时,它会从一个URL加载相册艺术,但如果它已经预装并存储在内存中,那就太好了。我试过一些方法,但似乎都不管用。有人知道一种技术吗?我可以在iOS中预加载图像,然后稍后查找该图像,如果没有,则下载该图像 编辑更多细节… 当我在我的应用程序上播放“电台”时,我会向服务器发出请求,该服务器会返回播放列表的JSON。在这个JSON里面是每首歌以及包括专辑艺术URL在内的数据。当用户去播放“电台”时,我希望为堆栈中的下一个唱片集艺术URL或整

我有一个音乐应用程序,我想预装专辑艺术。现在,当你点击下一首歌曲时,它会从一个URL加载相册艺术,但如果它已经预装并存储在内存中,那就太好了。我试过一些方法,但似乎都不管用。有人知道一种技术吗?我可以在iOS中预加载图像,然后稍后查找该图像,如果没有,则下载该图像

编辑更多细节…

当我在我的应用程序上播放“电台”时,我会向服务器发出请求,该服务器会返回播放列表的JSON。在这个JSON里面是每首歌以及包括专辑艺术URL在内的数据。当用户去播放“电台”时,我希望为堆栈中的下一个唱片集艺术URL或整个播放列表中的所有唱片集艺术URL预加载图像

无论如何,我已经尝试过在背景中的UIImage中加载下一张专辑艺术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加载到内存中
  • 以后使用这些图像时不会出现任何延迟

我不确定你在问什么,但如果你知道下一首歌会是什么,你就不能在后台线程中下载它,然后在下一首歌开始时准备好显示它吗

如果你想让应用程序在本地存储所有下载的图像,你最终可能会遇到空间问题,但它确实可以。您可以使用下载的图像,然后将其存储在caches目录中(而不是documentdir,否则苹果会发疯的!)。当一首歌出现时,只需快速检查图像,如果不是本地的,就可以下载它。歌曲需要几分钟,所以应该有时间在后台完成所有这些

#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,它似乎不起作用。它会继续运行并重新加载图像。嗯,我想我们需要更多的代码来查看…听起来好像你在调用该方法,而你不应该这样做。我会用更多的信息更新我的答案,但之后我就要去睡觉了!祝你好运!谢谢,不我在我的问题中添加了一些我尝试过的细节。这正是我一直在尝试的