2016-04-27 38 views
1

デバイスに保存されているすべての写真を取得し、自分のアプリに保存してから、最終的に(ユーザーが許可した場合)オリジナルを削除します。iOS - デバイスからすべての写真を取得してアプリに保存

これは私がこの仕事のために作成された私の全体のクラスです。

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のどこかにあります。私はそれが助けるかどうかわからないが、私はイメージを取得する必要はありません。私はちょうどデバイスのパスから私のアプリのサンドボックスのパスに画像ファイルをコピーする必要があります。

これに最適な解決策は何ですか?メモリの警告と漏れを避けるには?ありがとう

+0

解決策はありますか?私は同じ問題に直面しています。 –

答えて

0

dispatch_syncのdispatch_sync呼び出しを変更します。次に、同時にすべてを処理するのではなく、enumerateObjectsUsingBlockを通過するときに、一度に1つずつ写真を処理します。

関連する問題