diff --git a/CHANGELOG.md b/CHANGELOG.md index aff677d..abf72c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +## [2.6.0] + +### Changed + +* 🚨 Bumped iOS deployment target to 13.0. +* [video_editor_sdk] Raised minimum VideoEditor SDK for iOS version to 11.1.0. See the [changelog](https://github.com/imgly/vesdk-ios-build/blob/master/CHANGELOG.md) for more information. +* [photo_editor_sdk] Raised minimum PhotoEditor SDK for iOS version to 11.1.0. See the [changelog](https://github.com/imgly/pesdk-ios-build/blob/master/CHANGELOG.md) for more information. + +### Added + +* [imgly_sdk] Added implementation and documentation for background removal. + ## [2.5.0] ### Added diff --git a/README.md b/README.md index e1b710b..dc31ea8 100644 --- a/README.md +++ b/README.md @@ -17,13 +17,20 @@ # Flutter plugin for PhotoEditor SDK +## System requirements + +- Flutter: 1.20.0 +- Dart: 2.12.0 +- iOS: 13 +- Android: 5 (SDK 21) + ## Getting started Add the plugin package to the `pubspec.yaml` file in your project: ```yaml dependencies: - photo_editor_sdk: ^2.5.0 + photo_editor_sdk: ^2.6.0 ``` Install the new dependency: @@ -180,6 +187,7 @@ Run with --stacktrace option to get the stack trace. Run with --info or --debug include 'assets:sticker-emoticons' include 'backend:sticker-smart' + include 'backend:background-removal' } } ``` diff --git a/example/ios/Flutter/AppFrameworkInfo.plist b/example/ios/Flutter/AppFrameworkInfo.plist index f2872cf..c5ff5d3 100644 --- a/example/ios/Flutter/AppFrameworkInfo.plist +++ b/example/ios/Flutter/AppFrameworkInfo.plist @@ -2,25 +2,25 @@ - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - App - CFBundleIdentifier - io.flutter.flutter.app - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - App - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1.0 - MinimumOSVersion - 9.0 + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 13.0 diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index ec2a270..1ce33cc 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -1,12 +1,12 @@ PODS: - Flutter (1.0.0) - - imgly_sdk (2.5.0): + - imgly_sdk (2.6.0): - Flutter - - imglyKit (~> 10.30) - - imglyKit (10.30.1) - - photo_editor_sdk (2.5.0): + - imglyKit (~> 11.1) + - imglyKit (11.2.0) + - photo_editor_sdk (2.6.0): - Flutter - - imgly_sdk + - imgly_sdk (= 2.6.0) DEPENDENCIES: - Flutter (from `Flutter`) @@ -27,9 +27,9 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a - imgly_sdk: d8f93e1cbb33f6c27d0ab8f88ccceeeb819ca60d - imglyKit: bb83829ba5d1af548772d61660556473f0391d1c - photo_editor_sdk: c77802987740ac84d84663162c311cae42b9b746 + imgly_sdk: bb252939cfbf53a0199a40d565ab675db859a041 + imglyKit: 505785f0467867523cdee38ebb7d60c5189faedf + photo_editor_sdk: 6f5cffbb6bff0ac2a5aac6b35320ab9e85faab60 PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 110a1ed..264cb36 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 51; objects = { /* Begin PBXBuildFile section */ @@ -68,7 +68,6 @@ 6540F4EA578D4F2F0FC3C7F7 /* Pods-Runner.release.xcconfig */, 4A899B02CDAABDD5638FDD09 /* Pods-Runner.profile.xcconfig */, ); - name = Pods; path = Pods; sourceTree = ""; }; @@ -362,7 +361,11 @@ "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", @@ -494,7 +497,11 @@ "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", @@ -521,7 +528,11 @@ "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", diff --git a/ios/Classes/FlutterPESDK.swift b/ios/Classes/FlutterPESDK.swift index f335cb6..a01f84a 100644 --- a/ios/Classes/FlutterPESDK.swift +++ b/ios/Classes/FlutterPESDK.swift @@ -4,7 +4,7 @@ import CoreServices import ImglyKit import imgly_sdk -@available(iOS 9.0, *) +@available(iOS 13.0, *) public class FlutterPESDK: FlutterIMGLY, FlutterPlugin, PhotoEditViewControllerDelegate { // MARK: - Typealias @@ -75,9 +75,9 @@ public class FlutterPESDK: FlutterIMGLY, FlutterPlugin, PhotoEditViewControllerD if let finalData = serializationData { var deserializationResult: Deserializer.DeserializationResult? if let photo_ = photo { - deserializationResult = Deserializer.deserialize(data: finalData, imageDimensions: photo_.size, assetCatalog: configurationData?.assetCatalog ?? .shared) + deserializationResult = Deserializer.deserialize(data: finalData, imageDimensions: photo_.size, assetCatalog: configurationData?.assetCatalog ?? .defaultItems) } else { - deserializationResult = Deserializer._objCDeserialize(data: finalData, assetCatalog: configurationData?.assetCatalog ?? .shared) + deserializationResult = Deserializer._objCDeserialize(data: finalData, assetCatalog: configurationData?.assetCatalog ?? .defaultItems) if let serializationPhoto = deserializationResult?.photo { finalPhotoAsset = Photo.from(photoRepresentation: serializationPhoto) } else { @@ -125,56 +125,53 @@ public class FlutterPESDK: FlutterIMGLY, FlutterPlugin, PhotoEditViewControllerD } } } + + private func handleError(_ photoEditViewController: PhotoEditViewController, code: String, message: String?, details: Any?) { + self.dismiss(mediaEditViewController: photoEditViewController, animated: true) { + self.result?(FlutterError(code: code, message: message, details: details)) + self.result = nil + } + } } // MARK: - Delegate /// The delegate for the `PhotoEditViewController`. -@available(iOS 9.0, *) +@available(iOS 13.0, *) extension FlutterPESDK { - /// Delegate function called when the `PhotoEditViewController` has successfully exported the image. /// - Parameter photoEditViewController: The editor who has finished exporting. - /// - Parameter image: The exported image. - /// - Parameter data: The image data. - public func photoEditViewController(_ photoEditViewController: PhotoEditViewController, didSave image: UIImage, and data: Data) { - let options = photoEditViewController.configuration.photoEditViewControllerOptions - var imageData: Data? = data - - if imageData != nil { - switch options.outputImageFileFormat { - case .png: - imageData = image.pngData() - break - case .jpeg: - imageData = image.jpegData(compressionQuality: options.compressionQuality) - break - default: - break - } + /// - Parameter result: The `PhotoEditorResult` from the editor. + public func photoEditViewControllerDidFinish(_ photoEditViewController: PhotoEditViewController, result: PhotoEditorResult) { + guard let uti = result.output.uti else { + self.handleError(photoEditViewController, code: "Image could not be saved.", message: nil, details: nil) + return } - var imageString: NSString? + let imageData = result.output.data + var imageString: String? var serialization: Any? - if imageData?.isEmpty == false { + if imageData.isEmpty == false { if self.exportType == IMGLYConstants.kExportTypeFileURL { guard let fileURL = self.exportFile else { - self.result?(FlutterError(code: "Export type must not be nil.", message: "No valid export type has been specified.", details: self.exportFile)) - self.result = nil + self.handleError(photoEditViewController, code: "Export type must not be nil.", message: "No valid export type has been specified.", details: self.exportFile) return } do { - try imageData?.IMGLYwriteToUrl(fileURL, andCreateDirectoryIfNeeded: true) - imageString = (self.exportFile?.absoluteString ?? "nil") as NSString + try imageData.IMGLYwriteToUrl(fileURL, andCreateDirectoryIfNeeded: true) + imageString = fileURL.absoluteString } catch let error { - self.result?(FlutterError(code: "Image could not be saved.", message: "Error message: \(error.localizedDescription)", details: error)) - self.result = nil + self.handleError(photoEditViewController, code: "Image could not be saved.", message: "Error message: \(error.localizedDescription)", details: error) return } } else if self.exportType == IMGLYConstants.kExportTypeDataURL { - let mediaType: NSString? = UTTypeCopyPreferredTagWithClass(options.outputImageFileFormatUTI, kUTTagClassMIMEType)?.takeRetainedValue() - imageString = String(format: "data:%@;base64,%@", mediaType!, imageData!.base64EncodedString()) as NSString + if let mediaType = UTTypeCopyPreferredTagWithClass(uti as CFString, kUTTagClassMIMEType)?.takeRetainedValue() as? NSString { + imageString = String(format: "data:%@;base64,%@", mediaType, imageData.base64EncodedString()) + } else { + self.handleError(photoEditViewController, code: "Image could not be saved.", message: "The output UTI could not be read.", details: nil) + return + } } } @@ -184,29 +181,28 @@ extension FlutterPESDK { } if self.serializationType == IMGLYConstants.kExportTypeFileURL { guard let exportURL = self.serializationFile else { - self.result?(FlutterError(code: "Serialization failed.", message: "The URL must not be nil.", details: nil)) - self.result = nil + self.handleError(photoEditViewController, code: "Serialization failed.", message: "The URL must not be nil.", details: nil) return } do { try serializationData.IMGLYwriteToUrl(exportURL, andCreateDirectoryIfNeeded: true) serialization = self.serializationFile?.absoluteString } catch let error { - self.result?(FlutterError(code: "Serialization failed.", message: error.localizedDescription, details: error)) - self.result = nil + self.handleError(photoEditViewController, code: "Serialization failed.", message: error.localizedDescription, details: error) + return } } else if self.serializationType == IMGLYConstants.kExportTypeObject { do { serialization = try JSONSerialization.jsonObject(with: serializationData, options: .init(rawValue: 0)) } catch let error { - self.result?(FlutterError(code: "Serialization failed.", message: error.localizedDescription, details: error)) - self.result = nil + self.handleError(photoEditViewController, code: "Serialization failed.", message: error.localizedDescription, details: error) + return } } } self.dismiss(mediaEditViewController: photoEditViewController, animated: true) { - let res: [String: Any?] = ["image": imageString ?? "no image exported", "hasChanges": photoEditViewController.hasChanges, "serialization": serialization] + let res: [String: Any?] = ["image": imageString ?? "no image exported", "hasChanges": result.status == .renderedWithChanges, "serialization": serialization] self.result?(res) self.result = nil } @@ -216,11 +212,9 @@ extension FlutterPESDK { /// to export the image. /// /// - Parameter photoEditViewController: The editor that failed to export. - public func photoEditViewControllerDidFailToGeneratePhoto(_ photoEditViewController: PhotoEditViewController) { - self.dismiss(mediaEditViewController: photoEditViewController, animated: true) { - self.result?(FlutterError(code: "editor_failed", message: "The editor did fail to generate the image.", details: nil)) - self.result = nil - } + /// - Parameter error: The `PhotoEditorError` that caused the failure. + public func photoEditViewControllerDidFail(_ photoEditViewController: PhotoEditViewController, error: PhotoEditorError) { + self.handleError(photoEditViewController, code: "Editor failed", message: "The editor did fail to generate the image.", details: error) } /// Delegate function that is called if the `PhotoEditViewController` has diff --git a/ios/photo_editor_sdk.podspec b/ios/photo_editor_sdk.podspec index 92b5404..359369a 100644 --- a/ios/photo_editor_sdk.podspec +++ b/ios/photo_editor_sdk.podspec @@ -20,10 +20,10 @@ The official Flutter plugin for PhotoEditor SDK. Integrate the photo editor into s.source = { :path => '.' } s.source_files = 'Classes/**/*' s.dependency 'Flutter' - s.platform = :ios, '9.0' - s.dependency 'imgly_sdk' + s.platform = :ios, '13.0' + s.dependency 'imgly_sdk', s.version.to_s # Flutter.framework does not contain a i386 slice. s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } - s.swift_version = '5.0' + s.swift_version = '5.6' end diff --git a/pubspec.yaml b/pubspec.yaml index 35079c5..fbf09df 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: photo_editor_sdk description: The official Flutter plugin for PhotoEditor SDK. Integrate the photo editor into your own iOS or Android app - in minutes! -version: 2.5.0 +version: 2.6.0 homepage: https://www.photoeditorsdk.com repository: https://github.com/imgly/pesdk-flutter @@ -11,7 +11,7 @@ environment: dependencies: flutter: sdk: flutter - imgly_sdk: 2.5.0 + imgly_sdk: 2.6.0 dev_dependencies: flutter_test: