iOS - 从设备中获取所有照片并将它们保存到应用程序

Posted

技术标签:

【中文标题】iOS - 从设备中获取所有照片并将它们保存到应用程序【英文标题】:iOS - Fetch all photos from device and save them to app 【发布时间】:2016-04-27 14:11:49 【问题描述】:

我想获取保存在设备中的所有照片并将它们保存到我的应用程序中,然后最终(如果用户允许)删除原件。

这是我为此任务创建的整个班级:

class ImageAssetsManager: NSObject 
  let imageManager = PHCachingImageManager()

  func fetchAllImages() 
    let options = PHFetchOptions()
    options.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.Image.rawValue)
    options.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)]
    if #available(ios 9.0, *) 
      options.fetchLimit = 5
     else 
      // Fallback on earlier versions
    

    let imageAssets = PHAsset.fetchAssetsWithOptions(options)
    print(imageAssets.count)
    self.getAssets(imageAssets)
  

  func getAssets(assets: PHFetchResult) 
    var assetsToDelete: [PHAsset] = []

    assets.enumerateObjectsUsingBlock  (object, count, stop) in
      if object is PHAsset 
        let asset = object as! PHAsset
        let imageSize = CGSize(width: asset.pixelWidth,height: asset.pixelHeight)

        let options = PHImageRequestOptions()
        options.deliveryMode = .FastFormat
        options.synchronous = true

        self.imageManager.requestImageForAsset(asset, targetSize: imageSize, contentMode: .AspectFill, options: options, resultHandler:  [weak self]
          image, info in

          self.addAssetToSync(image, info: info)
          assetsToDelete.append(asset)
          )
      
    
    self.deleteAssets(assetsToDelete)
  

  func addAssetToSync(image: UIImage?, info: [NSObject : AnyObject]?) 
    guard let image = image else 
      return
    

    guard let info = info else 
      return
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), 
      let imageData = UIImageJPEGRepresentation(image, 0.95)!
      let fileUrl = info["PHImageFileURLKey"] as! NSURL

      dispatch_async(dispatch_get_main_queue(), 
        let photoRootItem = DatabaseManager.sharedInstance.getPhotosRootItem()
        let ssid = DatabaseManager.sharedInstance.getSsidInfoByName(ContentManager.sharedInstance.ssid)
        let item = StorageManager.sharedInstance.createFile(imageData, name: fileUrl.absoluteString.fileNameWithoutPath(), parentFolder: photoRootItem!, ssid: ssid!)
      )
    )
  

  func deleteAssets(assetsToDelete: [PHAsset])
    phphotoLibrary.sharedPhotoLibrary().performChanges(
      PHAssetChangeRequest.deleteAssets(assetsToDelete)
      , completionHandler:  success, error in
        guard let error = error else return
    )
  

它有效,但我的问题是它仅适用于有限数量的照片。当我尝试使用所有内容时,我会收到内存警告,然后应用程序崩溃了。我知道为什么会这样。我知道我的问题是我把所有照片都记下来了,而且太多了。我可以使用该获取限制获取图像并使其循环,但我不确定它是否是最佳解决方案。

我希望通过一些解决方案处理几张照片,然后一次又一次地释放内存直到结束。但这种变化将在 enumerateObjectsUsingBlock 中的某个地方。我不确定它是否有帮助,但我什至不需要获取图像。我只需要将图像文件从设备路径复制到我的应用沙箱路径。

什么是最好的解决方案?如何避免内存警告和泄漏?谢谢

【问题讨论】:

您收到任何解决方案了吗?我也面临同样的问题。 【参考方案1】:

将您的 dispatch_async 调用更改为 dispatch_sync。然后,您将在遍历 enumerateObjectsUsingBlock 时一次处理一张照片,而不是尝试同时处理所有照片。

【讨论】:

以上是关于iOS - 从设备中获取所有照片并将它们保存到应用程序的主要内容,如果未能解决你的问题,请参考以下文章

如何获取存储在设备中的所有图像并将它们显示为 iPhone sdk 中的图库

在我的 iOS 应用程序中访问设备的所有照片

解析数组图像保存和获取

如何以编程方式从照片应用程序中检索所有照片/视频并将其复制到我的应用程序?

拍摄照片时正确设置正确的照片方向

如何仅获取保存在iphone应用程序文档文件夹中的所有照片名称