From 9fc637fa5092d3ea16467de1d9ca14d59e34eb32 Mon Sep 17 00:00:00 2001 From: Kwanwoo Kim Date: Sun, 25 Jun 2023 17:29:58 -0700 Subject: [PATCH 1/2] Delete Medium for iOS --- ios/Classes/SwiftPhotoGalleryPlugin.swift | 35 +++++++++++++++++++++++ lib/photo_gallery.dart | 19 +++++++++++- 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/ios/Classes/SwiftPhotoGalleryPlugin.swift b/ios/Classes/SwiftPhotoGalleryPlugin.swift index fc474f6..2bd4b5f 100644 --- a/ios/Classes/SwiftPhotoGalleryPlugin.swift +++ b/ios/Classes/SwiftPhotoGalleryPlugin.swift @@ -37,6 +37,16 @@ public class SwiftPhotoGalleryPlugin: NSObject, FlutterPlugin { } ) } + else if(call.method == "deleteMedium") { + let arguments = call.arguments as! Dictionary + let mediumId = arguments["mediumId"] as! String + deleteMedium( + mediumId: mediumId, + completion: { (success: Bool, error: Error?) -> Void in + result(success) + } + ) + } else if(call.method == "getThumbnail") { let arguments = call.arguments as! Dictionary let mediumId = arguments["mediumId"] as! String @@ -221,6 +231,30 @@ public class SwiftPhotoGalleryPlugin: NSObject, FlutterPlugin { ) } } + + private func deleteMedium(mediumId: String, completion: @escaping (Bool, Error?) -> Void) { + let fetchOptions = PHFetchOptions() + if #available(iOS 9, *) { + fetchOptions.fetchLimit = 1 + } + let assets: PHFetchResult = PHAsset.fetchAssets(withLocalIdentifiers: [mediumId], options: fetchOptions) + + if assets.count <= 0 { + completion(false, NSError(domain: "photo_gallery", code: 404, userInfo: nil)) + } else { + let asset: PHAsset = assets[0] + deleteAssets(assets: [asset]) { success, error in + completion(success, error) + } + } + } + + private func deleteAssets(assets: [PHAsset], completion: @escaping (Bool, Error?) -> Void) { + PHPhotoLibrary.shared().performChanges({ + PHAssetChangeRequest.deleteAssets(assets as NSFastEnumeration) + }, completionHandler: completion) + } + private func getThumbnail( mediumId: String, @@ -586,6 +620,7 @@ public class SwiftPhotoGalleryPlugin: NSObject, FlutterPlugin { } return nil } + private func cachePath() -> URL { let paths = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask) diff --git a/lib/photo_gallery.dart b/lib/photo_gallery.dart index 17db430..fdeb75d 100644 --- a/lib/photo_gallery.dart +++ b/lib/photo_gallery.dart @@ -31,7 +31,9 @@ class PhotoGallery { 'newest': newest, 'hideIfEmpty': hideIfEmpty, }); - return json.map((album) => Album.fromJson(album, mediumType, newest)).toList(); + return json + .map((album) => Album.fromJson(album, mediumType, newest)) + .toList(); } /// List all available media in a specific album, support pagination of media @@ -62,6 +64,21 @@ class PhotoGallery { return Medium.fromJson(json); } + /// Delete medium by medium id + static Future deleteMedium({ + required String mediumId, + }) async { + if (!Platform.isIOS) { + throw UnsupportedError('This function is only available on iOS'); + } + + final result = await _channel.invokeMethod('deleteMedium', { + 'mediumId': mediumId, + }); + + return result as bool; + } + /// Get medium thumbnail by medium id static Future> getThumbnail({ required String mediumId, From cbe3150ef037e238553c6bf8f2053eaf53080613 Mon Sep 17 00:00:00 2001 From: Kwanwoo Kim Date: Sun, 25 Jun 2023 22:41:36 -0700 Subject: [PATCH 2/2] LightWeight option for iOS --- ios/Classes/SwiftPhotoGalleryPlugin.swift | 24 ++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/ios/Classes/SwiftPhotoGalleryPlugin.swift b/ios/Classes/SwiftPhotoGalleryPlugin.swift index 2bd4b5f..54733b4 100644 --- a/ios/Classes/SwiftPhotoGalleryPlugin.swift +++ b/ios/Classes/SwiftPhotoGalleryPlugin.swift @@ -25,7 +25,8 @@ public class SwiftPhotoGalleryPlugin: NSObject, FlutterPlugin { let newest = arguments["newest"] as! Bool let skip = arguments["skip"] as? NSNumber let take = arguments["take"] as? NSNumber - result(listMedia(albumId: albumId, mediumType: mediumType, newest: newest, skip: skip, take: take)) + let lightWeight = arguments["lightWeight"] as? Bool + result(listMedia(albumId: albumId, mediumType: mediumType, newest: newest, skip: skip, take: take, lightWeight: lightWeight)) } else if(call.method == "getMedium") { let arguments = call.arguments as! Dictionary @@ -182,7 +183,7 @@ public class SwiftPhotoGalleryPlugin: NSObject, FlutterPlugin { return PHAsset.fetchAssets(in: collection ?? PHAssetCollection.init(), options: options).count } - private func listMedia(albumId: String, mediumType: String?, newest: Bool, skip: NSNumber?, take: NSNumber?) -> NSDictionary { + private func listMedia(albumId: String, mediumType: String?, newest: Bool, skip: NSNumber?, take: NSNumber?, lightWeight: Bool? = false) -> NSDictionary { let fetchOptions = PHFetchOptions() fetchOptions.predicate = predicateFromMediumType(mediumType: mediumType) fetchOptions.sortDescriptors = [ @@ -203,7 +204,11 @@ public class SwiftPhotoGalleryPlugin: NSObject, FlutterPlugin { var items = [[String: Any?]]() for index in start.. [String: Any?] { + return [ + "id": asset.localIdentifier, + "mediumType": toDartMediumType(value: asset.mediaType), + "height": asset.pixelHeight, + "width": asset.pixelWidth, + "duration": NSInteger(asset.duration * 1000), + "creationDate": (asset.creationDate != nil) ? NSInteger(asset.creationDate!.timeIntervalSince1970 * 1000) : nil, + "modifiedDate": (asset.modificationDate != nil) ? NSInteger(asset.modificationDate!.timeIntervalSince1970 * 1000) : nil + ] + } private func getMediumFromAssetAsync(asset: PHAsset, completion: @escaping ([String : Any?]?, Error?) -> Void) -> Void { let mimeType = self.extractMimeTypeFromAsset(asset: asset)