@imgly/editor-react-native 1.81.1-rc.0 → 1.82.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/IMGLYEditorModule.podspec +3 -1
- package/README.md +17 -0
- package/android/build.gradle +1 -1
- package/android/src/main/kotlin/ly/img/editor/configuration/video/callback/OnCreate.kt +1 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/video/component/Dock.kt +2 -0
- package/android/src/main/kotlin/ly/img/editor/configuration/video/component/InspectorBar.kt +4 -0
- package/ios/IMGLYEditorModuleImplementation.swift +62 -0
- package/ios/Model/EditorPreset.swift +2 -0
- package/ios/Model/EditorResult.swift +2 -0
- package/ios/Model/EditorSettings.swift +2 -0
- package/ios/Model/Source.swift +2 -0
- package/ios/Package.swift +114 -0
- package/ios/StarterKits/Apparel/callbacks/OnCreate+Apparel.swift +6 -4
- package/ios/StarterKits/Design/callbacks/OnCreate+Design.swift +6 -4
- package/ios/StarterKits/Photo/callbacks/OnCreate+Photo.swift +6 -1
- package/ios/StarterKits/Postcard/callbacks/OnCreate+Postcard.swift +6 -4
- package/ios/StarterKits/Video/callbacks/OnCreate+Video.swift +6 -1
- package/ios/{Constants → bridge}/IMGLYConstants.m +3 -0
- package/ios/{IMGLYEditorModule.mm → bridge/IMGLYEditorModule.mm} +5 -24
- package/ios/bridge/IMGLYEditorModuleSupport.m +23 -0
- package/ios/{Constants → bridge/include}/IMGLYConstants.h +2 -0
- package/ios/bridge/include/IMGLYEditorModuleSupport.h +46 -0
- package/package.json +1 -1
- package/src/NativeIMGLYEditor.ts +1 -1
- package/ios/IMGLYEditorModule-Bridging-Header.h +0 -3
- /package/ios/{IMGLYEditorModule.h → bridge/include/IMGLYEditorModule.h} +0 -0
|
@@ -14,7 +14,9 @@ Pod::Spec.new do |s|
|
|
|
14
14
|
s.source = { path: './ios' }
|
|
15
15
|
|
|
16
16
|
s.source_files = 'ios/**/*.{h,m,mm,swift}'
|
|
17
|
-
|
|
17
|
+
# ios/Package.swift is the manifest for React Native's experimental Swift
|
|
18
|
+
# Package Manager mode, not a source file.
|
|
19
|
+
s.exclude_files = ['ios/StarterKits/**/*StarterKit.swift', 'ios/Package.swift']
|
|
18
20
|
s.resources = 'ios/StarterKits/*.{scene,png}'
|
|
19
21
|
|
|
20
22
|
s.dependency 'IMGLYUI', s.version.to_s
|
package/README.md
CHANGED
|
@@ -29,3 +29,20 @@ const result = await IMGLYEditor.openEditor(settings);
|
|
|
29
29
|
## Changelog
|
|
30
30
|
|
|
31
31
|
To keep up-to-date with the latest changes, visit [CHANGELOG](https://img.ly/docs/cesdk/changelog/).
|
|
32
|
+
|
|
33
|
+
## Swift Package Manager (experimental)
|
|
34
|
+
|
|
35
|
+
React Native 0.87 introduced an experimental Swift Package Manager mode (`npx react-native spm`) — see the [React Native 0.87 announcement](https://reactnative.dev/blog/2026/08/11/react-native-0.87) and the [0.87.0 release notes](https://github.com/react/react-native/releases/tag/v0.87.0). This module dual-ships a SwiftPM manifest (`ios/Package.swift`) next to its podspec, so React Native's SPM autolinking resolves it out of the box. CocoaPods currently remains the default integration path; the React Native team does not recommend the SPM mode for production yet.
|
|
36
|
+
|
|
37
|
+
The notes below describe React Native **0.87.0**. That is the version this
|
|
38
|
+
support was built and verified against. We have not verified newer React Native
|
|
39
|
+
versions, so we do not know whether these workarounds still apply there. React
|
|
40
|
+
Native calls this mode experimental and can change its commands, flags, and
|
|
41
|
+
generated layout in any release. Check the release notes of the React Native
|
|
42
|
+
version you use.
|
|
43
|
+
|
|
44
|
+
Note: React Native 0.87 pins its generated autolinking package to iOS 15 while this module requires iOS 16. Until the floor is derived from the linked libraries upstream, raise the `platforms:` entries in `react-native/scripts/spm/generate-spm-autolinking.js` to `.iOS(.v16)` (for example with `patch-package`).
|
|
45
|
+
|
|
46
|
+
Note: The app target itself must also build with an iOS 16 deployment target. The React Native template scaffolds a lower one, which works until your app code imports this module directly — for example for native customization — and then fails with a minimum-deployment-target error. Raise the **iOS Deployment Target** of the app target in Xcode to 16.0.
|
|
47
|
+
|
|
48
|
+
Note: React Native 0.87.0 ships `hermes-compiler` for bytecode version 98 while its prebuilt SwiftPM Hermes runtime expects 99, so any build with an embedded JS bundle crashes at startup. Install `hermes-compiler@^260318099` until a React Native release aligns the two.
|
package/android/build.gradle
CHANGED
|
@@ -12,6 +12,7 @@ import ly.img.editor.core.component.Dock
|
|
|
12
12
|
import ly.img.editor.core.component.EditorTrigger
|
|
13
13
|
import ly.img.editor.core.component.remember
|
|
14
14
|
import ly.img.editor.core.component.rememberAudiosLibrary
|
|
15
|
+
import ly.img.editor.core.component.rememberCaptions
|
|
15
16
|
import ly.img.editor.core.component.rememberOverlaysLibrary
|
|
16
17
|
import ly.img.editor.core.component.rememberResizeAll
|
|
17
18
|
import ly.img.editor.core.component.rememberStickersAndShapesLibrary
|
|
@@ -60,6 +61,7 @@ fun VideoConfigurationBuilder.rememberDock() = Dock.remember {
|
|
|
60
61
|
add { Dock.Button.rememberOverlaysLibrary() }
|
|
61
62
|
add { Dock.Button.rememberTextLibrary() }
|
|
62
63
|
add { Dock.Button.rememberStickersAndShapesLibrary() }
|
|
64
|
+
add { Dock.Button.rememberCaptions() }
|
|
63
65
|
add { Dock.Button.rememberAudiosLibrary() }
|
|
64
66
|
add { Dock.Button.rememberVoiceoverRecord() }
|
|
65
67
|
add { Dock.Button.rememberResizeAll() }
|
|
@@ -9,10 +9,12 @@ import ly.img.editor.core.component.remember
|
|
|
9
9
|
import ly.img.editor.core.component.rememberAdjustments
|
|
10
10
|
import ly.img.editor.core.component.rememberAnimations
|
|
11
11
|
import ly.img.editor.core.component.rememberBlur
|
|
12
|
+
import ly.img.editor.core.component.rememberCaptionStyle
|
|
12
13
|
import ly.img.editor.core.component.rememberClipSpeed
|
|
13
14
|
import ly.img.editor.core.component.rememberCrop
|
|
14
15
|
import ly.img.editor.core.component.rememberDelete
|
|
15
16
|
import ly.img.editor.core.component.rememberDuplicate
|
|
17
|
+
import ly.img.editor.core.component.rememberEditCaptions
|
|
16
18
|
import ly.img.editor.core.component.rememberEditText
|
|
17
19
|
import ly.img.editor.core.component.rememberEffect
|
|
18
20
|
import ly.img.editor.core.component.rememberEnterGroup
|
|
@@ -41,6 +43,8 @@ fun VideoConfigurationBuilder.rememberInspectorBar() = InspectorBar.remember {
|
|
|
41
43
|
InspectorBar.ListBuilder.remember {
|
|
42
44
|
add { InspectorBar.Button.rememberVoiceover() } // Voiceover Audio
|
|
43
45
|
add { InspectorBar.Button.rememberReplace() } // Video, Image, Sticker, Audio
|
|
46
|
+
add { InspectorBar.Button.rememberEditCaptions() } // Caption
|
|
47
|
+
add { InspectorBar.Button.rememberCaptionStyle() } // Caption
|
|
44
48
|
add { InspectorBar.Button.rememberEditText() } // Text
|
|
45
49
|
add { InspectorBar.Button.rememberTextPresets() } // Text
|
|
46
50
|
add { InspectorBar.Button.rememberFormatText() } // Text
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
#if canImport(IMGLYEditorModuleObjC)
|
|
3
|
+
// Swift Package Manager builds the Objective-C++ bridge as a separate target.
|
|
4
|
+
// Under CocoaPods both languages share one module, so no import is needed.
|
|
5
|
+
import IMGLYEditorModuleObjC
|
|
6
|
+
#endif
|
|
7
|
+
|
|
8
|
+
/// The Swift implementation behind the Objective-C++ React Native bridge.
|
|
9
|
+
///
|
|
10
|
+
/// The bridge resolves this class at runtime by its stable Objective-C name
|
|
11
|
+
/// (see `IMGLYEditorModuleImplementationProvider`), so no static
|
|
12
|
+
/// Objective-C → Swift reference exists. This is what allows building the
|
|
13
|
+
/// module with Swift Package Manager, which cannot compile mixed
|
|
14
|
+
/// Swift/Objective-C++ targets (SE-0403).
|
|
15
|
+
@objc(IMGLYEditorModuleDefaultImplementation)
|
|
16
|
+
final class IMGLYEditorModuleDefaultImplementation: NSObject, IMGLYEditorModuleImplementation {
|
|
17
|
+
func openEditor(
|
|
18
|
+
withSettings settings: [AnyHashable: Any],
|
|
19
|
+
preset: String?,
|
|
20
|
+
metadata: [AnyHashable: Any]?,
|
|
21
|
+
resolve: @escaping IMGLYEditorResolveBlock,
|
|
22
|
+
reject: @escaping IMGLYEditorRejectBlock,
|
|
23
|
+
) {
|
|
24
|
+
guard let settings = settings as? [String: Any],
|
|
25
|
+
let convertedSettings = EditorSettings.fromDictionary(settings) else {
|
|
26
|
+
reject(IMGLYErrorParsing, IMGLYErrorParsingMessage, nil)
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
// Unknown and missing presets both fall back to the design editor,
|
|
30
|
+
// matching `EditorPreset.fromString`.
|
|
31
|
+
let convertedPreset = EditorPresetParser.fromString((preset ?? "design") as NSString)
|
|
32
|
+
let metadata = metadata as? [String: Any]
|
|
33
|
+
|
|
34
|
+
DispatchQueue.main.async {
|
|
35
|
+
MainActor.assumeIsolated {
|
|
36
|
+
IMGLYEditorModuleSwiftAdapter.shared.openEditor(
|
|
37
|
+
convertedPreset,
|
|
38
|
+
settings: convertedSettings,
|
|
39
|
+
metadata: metadata,
|
|
40
|
+
) { result, error in
|
|
41
|
+
if let result {
|
|
42
|
+
// Missing fields resolve as null, matching the Android module.
|
|
43
|
+
// The annotated binding keeps the heterogeneous literal out of the
|
|
44
|
+
// surrounding closure expression, which overwhelms the type checker
|
|
45
|
+
// ("failed to produce diagnostic" on the Xcode 26.6 toolchain).
|
|
46
|
+
let payload: [String: Any] = [
|
|
47
|
+
"artifact": result.artifact ?? NSNull(),
|
|
48
|
+
"scene": result.scene ?? NSNull(),
|
|
49
|
+
"thumbnail": result.thumbnail ?? NSNull(),
|
|
50
|
+
"metadata": result.metadata,
|
|
51
|
+
]
|
|
52
|
+
resolve(payload)
|
|
53
|
+
} else if let error {
|
|
54
|
+
reject(IMGLYErrorExportFailed, IMGLYErrorExportFailedMessage, error)
|
|
55
|
+
} else {
|
|
56
|
+
resolve(NSNull())
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
package/ios/Model/Source.swift
CHANGED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// swift-tools-version: 6.1
|
|
2
|
+
// 6.1 is the parse floor for the trailing-comma syntax SwiftFormat enforces (SE-0439). The
|
|
3
|
+
// toolchain floor comes from the IMGLYUI-swift dependency (tools 6.3.1) — do not lower this.
|
|
4
|
+
|
|
5
|
+
// Hand-authored manifest for React Native's experimental Swift Package Manager
|
|
6
|
+
// mode (React Native >= 0.87, `npx react-native spm`). CocoaPods
|
|
7
|
+
// (IMGLYEditorModule.podspec) remains the supported default integration.
|
|
8
|
+
//
|
|
9
|
+
// React Native's SPM autolinking consumes this manifest through a symlink at
|
|
10
|
+
// <app>/ios/build/generated/autolinking/libs/EditorReactNative -> this
|
|
11
|
+
// directory, so the relative package references below resolve against that
|
|
12
|
+
// location. This is React Native's documented contract for libraries that ship
|
|
13
|
+
// their own manifest (react-native/scripts/spm/__doc__/spm-header-paths-contract.md);
|
|
14
|
+
// the package and product must be named after the npm package
|
|
15
|
+
// (@imgly/editor-react-native -> EditorReactNative).
|
|
16
|
+
//
|
|
17
|
+
// The Objective-C++ bridge and the Swift implementation are separate targets
|
|
18
|
+
// because SwiftPM cannot compile mixed-language targets (SE-0403). The bridge
|
|
19
|
+
// resolves the Swift implementation at runtime (IMGLYEditorModuleSupport.h),
|
|
20
|
+
// so no Objective-C -> Swift compile-time dependency exists.
|
|
21
|
+
//
|
|
22
|
+
// The StarterKits directory holds tooling-provided sources and resources; do not
|
|
23
|
+
// hand-edit it. Its entry files are excluded from the target below because they
|
|
24
|
+
// reference app-side symbols that do not exist in the module.
|
|
25
|
+
|
|
26
|
+
import Foundation
|
|
27
|
+
import PackageDescription
|
|
28
|
+
|
|
29
|
+
// Single-source the version from package.json, like the podspec does, so
|
|
30
|
+
// release automation bumps the IMG.LY dependency pin together with the
|
|
31
|
+
// package version. React Native's autolinking references this manifest
|
|
32
|
+
// through a symlink, so resolve it before walking up to the package root.
|
|
33
|
+
let version: Version = {
|
|
34
|
+
let packageJSON = URL(fileURLWithPath: #filePath)
|
|
35
|
+
.resolvingSymlinksInPath()
|
|
36
|
+
.deletingLastPathComponent()
|
|
37
|
+
.deletingLastPathComponent()
|
|
38
|
+
.appendingPathComponent("package.json")
|
|
39
|
+
guard let data = try? Data(contentsOf: packageJSON),
|
|
40
|
+
let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
|
|
41
|
+
let versionString = json["version"] as? String,
|
|
42
|
+
let version = Version(versionString) else {
|
|
43
|
+
fatalError("Unable to read the package version from \(packageJSON.path).")
|
|
44
|
+
}
|
|
45
|
+
return version
|
|
46
|
+
}()
|
|
47
|
+
|
|
48
|
+
let package = Package(
|
|
49
|
+
name: "EditorReactNative",
|
|
50
|
+
platforms: [
|
|
51
|
+
.iOS(.v16),
|
|
52
|
+
],
|
|
53
|
+
products: [
|
|
54
|
+
.library(name: "EditorReactNative", targets: ["IMGLYEditorModule", "IMGLYEditorModuleObjC"]),
|
|
55
|
+
],
|
|
56
|
+
dependencies: [
|
|
57
|
+
.package(name: "ReactNative", path: "../../../../xcframeworks"),
|
|
58
|
+
.package(name: "React-GeneratedCode", path: "../../../ios"),
|
|
59
|
+
// Pinned exactly: the module and IMGLYUI are versioned in lockstep, matching the podspec.
|
|
60
|
+
.package(url: "https://github.com/imgly/IMGLYUI-swift.git", exact: version),
|
|
61
|
+
],
|
|
62
|
+
targets: [
|
|
63
|
+
.target(
|
|
64
|
+
name: "IMGLYEditorModuleObjC",
|
|
65
|
+
dependencies: [
|
|
66
|
+
.product(name: "ReactHeaders", package: "ReactNative"),
|
|
67
|
+
.product(name: "ReactNativeHeaders", package: "ReactNative"),
|
|
68
|
+
.product(name: "ReactNativeDependenciesHeaders", package: "ReactNative"),
|
|
69
|
+
.product(name: "ReactAppHeaders", package: "React-GeneratedCode"),
|
|
70
|
+
],
|
|
71
|
+
path: "bridge",
|
|
72
|
+
publicHeadersPath: "include",
|
|
73
|
+
cxxSettings: [
|
|
74
|
+
// React Native's SwiftPM autolinking defines this for no target, while
|
|
75
|
+
// CocoaPods defines it for every one. Without it this module would
|
|
76
|
+
// compile its legacy bridge branch and run behind the TurboModule
|
|
77
|
+
// interop layer, so the integration path would decide the dispatch
|
|
78
|
+
// mechanism. The codegen'd spec headers the branch needs come from the
|
|
79
|
+
// ReactAppHeaders product above.
|
|
80
|
+
.define("RCT_NEW_ARCH_ENABLED", to: "1"),
|
|
81
|
+
.define("DEBUG", .when(configuration: .debug)),
|
|
82
|
+
.define("NDEBUG", .when(configuration: .release)),
|
|
83
|
+
],
|
|
84
|
+
linkerSettings: [.linkedFramework("Foundation")],
|
|
85
|
+
),
|
|
86
|
+
.target(
|
|
87
|
+
name: "IMGLYEditorModule",
|
|
88
|
+
dependencies: [
|
|
89
|
+
"IMGLYEditorModuleObjC",
|
|
90
|
+
// The umbrella product is the only product that vends the IMGLYEditor module.
|
|
91
|
+
.product(name: "IMGLYUI", package: "IMGLYUI-swift"),
|
|
92
|
+
],
|
|
93
|
+
path: ".",
|
|
94
|
+
exclude: [
|
|
95
|
+
"bridge",
|
|
96
|
+
"StarterKits/Apparel/ApparelEditorStarterKit.swift",
|
|
97
|
+
"StarterKits/Design/DesignEditorStarterKit.swift",
|
|
98
|
+
"StarterKits/Photo/PhotoEditorStarterKit.swift",
|
|
99
|
+
"StarterKits/Postcard/PostcardEditorStarterKit.swift",
|
|
100
|
+
"StarterKits/Video/VideoEditorStarterKit.swift",
|
|
101
|
+
],
|
|
102
|
+
resources: [
|
|
103
|
+
.copy("StarterKits/apparel-ui-b-empty.scene"),
|
|
104
|
+
.copy("StarterKits/design-ui-empty.scene"),
|
|
105
|
+
.copy("StarterKits/photo-ui-empty.png"),
|
|
106
|
+
.copy("StarterKits/postcard-empty.scene"),
|
|
107
|
+
.copy("StarterKits/video-empty.scene"),
|
|
108
|
+
],
|
|
109
|
+
),
|
|
110
|
+
],
|
|
111
|
+
// The module sources are written for the Swift 5 language mode.
|
|
112
|
+
swiftLanguageModes: [.v5],
|
|
113
|
+
cxxLanguageStandard: .cxx20,
|
|
114
|
+
)
|
|
@@ -71,10 +71,12 @@ public extension ApparelEditorConfiguration {
|
|
|
71
71
|
/// Loads the built-in empty apparel scene.
|
|
72
72
|
static let defaultCreateScene: OnCreate.Callback = { engine in
|
|
73
73
|
// highlight-starter-kit-on-create-scene
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
#if SWIFT_PACKAGE
|
|
75
|
+
let bundle = Bundle.module
|
|
76
|
+
#else
|
|
77
|
+
let bundle = Bundle(for: ApparelEditorConfiguration.self)
|
|
78
|
+
#endif
|
|
79
|
+
let sceneURL = bundle.url(forResource: "apparel-ui-b-empty", withExtension: "scene")!
|
|
78
80
|
try await engine.scene.load(from: sceneURL)
|
|
79
81
|
// highlight-starter-kit-on-create-scene
|
|
80
82
|
}
|
|
@@ -70,10 +70,12 @@ public extension DesignEditorConfiguration {
|
|
|
70
70
|
/// Loads the built-in empty design scene.
|
|
71
71
|
static let defaultCreateScene: OnCreate.Callback = { engine in
|
|
72
72
|
// highlight-starter-kit-on-create-scene
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
#if SWIFT_PACKAGE
|
|
74
|
+
let bundle = Bundle.module
|
|
75
|
+
#else
|
|
76
|
+
let bundle = Bundle(for: DesignEditorConfiguration.self)
|
|
77
|
+
#endif
|
|
78
|
+
let sceneURL = bundle.url(forResource: "design-ui-empty", withExtension: "scene")!
|
|
77
79
|
try await engine.scene.load(from: sceneURL)
|
|
78
80
|
// highlight-starter-kit-on-create-scene
|
|
79
81
|
}
|
|
@@ -70,7 +70,12 @@ public extension PhotoEditorConfiguration {
|
|
|
70
70
|
/// Creates a scene from the default photo image.
|
|
71
71
|
static let defaultCreateScene: OnCreate.Callback = { engine in
|
|
72
72
|
// highlight-starter-kit-on-create-scene
|
|
73
|
-
|
|
73
|
+
#if SWIFT_PACKAGE
|
|
74
|
+
let bundle = Bundle.module
|
|
75
|
+
#else
|
|
76
|
+
let bundle = Bundle(for: PhotoEditorConfiguration.self)
|
|
77
|
+
#endif
|
|
78
|
+
let imageURL = bundle.url(forResource: "photo-ui-empty", withExtension: "png")!
|
|
74
79
|
try await engine.scene.create(fromImage: imageURL)
|
|
75
80
|
// highlight-starter-kit-on-create-scene
|
|
76
81
|
}
|
|
@@ -70,10 +70,12 @@ public extension PostcardEditorConfiguration {
|
|
|
70
70
|
/// Loads the built-in empty postcard scene.
|
|
71
71
|
static let defaultCreateScene: OnCreate.Callback = { engine in
|
|
72
72
|
// highlight-starter-kit-on-create-scene
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
#if SWIFT_PACKAGE
|
|
74
|
+
let bundle = Bundle.module
|
|
75
|
+
#else
|
|
76
|
+
let bundle = Bundle(for: PostcardEditorConfiguration.self)
|
|
77
|
+
#endif
|
|
78
|
+
let sceneURL = bundle.url(forResource: "postcard-empty", withExtension: "scene")!
|
|
77
79
|
try await engine.scene.load(from: sceneURL)
|
|
78
80
|
// highlight-starter-kit-on-create-scene
|
|
79
81
|
}
|
|
@@ -79,7 +79,12 @@ public extension VideoEditorConfiguration {
|
|
|
79
79
|
/// Loads the built-in empty video scene.
|
|
80
80
|
static let defaultCreateScene: OnCreate.Callback = { engine in
|
|
81
81
|
// highlight-starter-kit-on-create-scene
|
|
82
|
-
|
|
82
|
+
#if SWIFT_PACKAGE
|
|
83
|
+
let bundle = Bundle.module
|
|
84
|
+
#else
|
|
85
|
+
let bundle = Bundle(for: VideoEditorConfiguration.self)
|
|
86
|
+
#endif
|
|
87
|
+
let sceneURL = bundle.url(forResource: "video-empty", withExtension: "scene")!
|
|
83
88
|
try await engine.scene.load(from: sceneURL)
|
|
84
89
|
// highlight-starter-kit-on-create-scene
|
|
85
90
|
}
|
|
@@ -5,9 +5,12 @@
|
|
|
5
5
|
// Error codes
|
|
6
6
|
NSString* const IMGLYErrorExportFailed = @"E_EXPORT_FAILED";
|
|
7
7
|
NSString* const IMGLYErrorParsing = @"E_PARSING";
|
|
8
|
+
NSString* const IMGLYErrorImplementationMissing = @"E_IMPLEMENTATION_MISSING";
|
|
8
9
|
|
|
9
10
|
// Error messages
|
|
10
11
|
NSString* const IMGLYErrorExportFailedMessage = @"The export of the asset failed due to: ";
|
|
11
12
|
NSString* const IMGLYErrorParsingMessage = @"Unable to parse the argument(s): ";
|
|
13
|
+
NSString* const IMGLYErrorImplementationMissingMessage =
|
|
14
|
+
@"The Swift implementation of the IMGLYEditor module was not linked into the app.";
|
|
12
15
|
|
|
13
16
|
@end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#import "IMGLYEditorModule.h"
|
|
2
|
-
#import "IMGLYEditorModule/IMGLYEditorModule-Swift.h"
|
|
3
2
|
#import "IMGLYConstants.h"
|
|
3
|
+
#import "IMGLYEditorModuleSupport.h"
|
|
4
4
|
|
|
5
5
|
@implementation IMGLYEditorModule
|
|
6
6
|
|
|
@@ -52,31 +52,12 @@ RCT_EXPORT_METHOD(openEditor : (nonnull NSDictionary*)settings source : (nullabl
|
|
|
52
52
|
metadata:(NSDictionary*)metadata
|
|
53
53
|
resolve:(RCTPromiseResolveBlock)resolve
|
|
54
54
|
reject:(RCTPromiseRejectBlock)reject {
|
|
55
|
-
|
|
56
|
-
if (
|
|
57
|
-
reject(
|
|
55
|
+
id<IMGLYEditorModuleImplementation> implementation = IMGLYEditorModuleImplementationProvider.implementation;
|
|
56
|
+
if (implementation == nil) {
|
|
57
|
+
reject(IMGLYErrorImplementationMissing, IMGLYErrorImplementationMissingMessage, nil);
|
|
58
58
|
return;
|
|
59
59
|
}
|
|
60
|
-
|
|
61
|
-
dispatch_async(dispatch_get_main_queue(), ^{
|
|
62
|
-
[[IMGLYEditorModuleSwiftAdapter shared] openEditor:convertedPreset
|
|
63
|
-
settings:convertedSettings
|
|
64
|
-
metadata:metadata
|
|
65
|
-
completion:^(EditorResult* _Nullable result, NSError* _Nullable error) {
|
|
66
|
-
if (result != nil) {
|
|
67
|
-
resolve(@ {
|
|
68
|
-
@"artifact" : result.artifact,
|
|
69
|
-
@"scene" : result.scene,
|
|
70
|
-
@"thumbnail" : result.thumbnail,
|
|
71
|
-
@"metadata" : result.metadata
|
|
72
|
-
});
|
|
73
|
-
} else if (error != nil) {
|
|
74
|
-
reject(IMGLYErrorExportFailed, IMGLYErrorExportFailedMessage, error);
|
|
75
|
-
} else {
|
|
76
|
-
resolve([NSNull null]);
|
|
77
|
-
}
|
|
78
|
-
}];
|
|
79
|
-
});
|
|
60
|
+
[implementation openEditorWithSettings:settings preset:preset metadata:metadata resolve:resolve reject:reject];
|
|
80
61
|
}
|
|
81
62
|
|
|
82
63
|
@end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#import "IMGLYEditorModuleSupport.h"
|
|
2
|
+
|
|
3
|
+
@implementation IMGLYEditorModuleImplementationProvider
|
|
4
|
+
|
|
5
|
+
+ (nullable id<IMGLYEditorModuleImplementation>)implementation {
|
|
6
|
+
static id<IMGLYEditorModuleImplementation> implementation;
|
|
7
|
+
static dispatch_once_t onceToken;
|
|
8
|
+
dispatch_once(&onceToken, ^{
|
|
9
|
+
// The Swift class is looked up by its stable Objective-C runtime name
|
|
10
|
+
// (`IMGLYEditorModuleImplementation.swift`) because this target must not
|
|
11
|
+
// reference Swift at compile time. React Native apps link with `-ObjC` on
|
|
12
|
+
// both the CocoaPods and the Swift Package Manager path, which keeps the
|
|
13
|
+
// class alive in Release and Archive builds despite the missing static
|
|
14
|
+
// reference.
|
|
15
|
+
Class implementationClass = NSClassFromString(@"IMGLYEditorModuleDefaultImplementation");
|
|
16
|
+
if ([implementationClass conformsToProtocol:@protocol(IMGLYEditorModuleImplementation)]) {
|
|
17
|
+
implementation = [[implementationClass alloc] init];
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
return implementation;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@end
|
|
@@ -5,9 +5,11 @@
|
|
|
5
5
|
// Error codes
|
|
6
6
|
extern NSString* const IMGLYErrorExportFailed;
|
|
7
7
|
extern NSString* const IMGLYErrorParsing;
|
|
8
|
+
extern NSString* const IMGLYErrorImplementationMissing;
|
|
8
9
|
|
|
9
10
|
// Error messages
|
|
10
11
|
extern NSString* const IMGLYErrorExportFailedMessage;
|
|
11
12
|
extern NSString* const IMGLYErrorParsingMessage;
|
|
13
|
+
extern NSString* const IMGLYErrorImplementationMissingMessage;
|
|
12
14
|
|
|
13
15
|
@end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#import <Foundation/Foundation.h>
|
|
2
|
+
|
|
3
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
4
|
+
|
|
5
|
+
/// Resolves a fulfilled result. Mirrors React Native's `RCTPromiseResolveBlock`
|
|
6
|
+
/// without importing React, so the Swift implementation stays React-free.
|
|
7
|
+
typedef void (^IMGLYEditorResolveBlock)(id _Nullable result);
|
|
8
|
+
|
|
9
|
+
/// Rejects with an error. Mirrors React Native's `RCTPromiseRejectBlock`.
|
|
10
|
+
typedef void (^IMGLYEditorRejectBlock)(NSString* code, NSString* message, NSError* _Nullable error);
|
|
11
|
+
|
|
12
|
+
/// The seam between the Objective-C++ React Native bridge and the Swift
|
|
13
|
+
/// implementation of the editor module.
|
|
14
|
+
///
|
|
15
|
+
/// The bridge resolves the implementation at runtime through
|
|
16
|
+
/// `IMGLYEditorModuleImplementationProvider` instead of importing the generated
|
|
17
|
+
/// `-Swift.h` header. Swift Package Manager cannot compile mixed
|
|
18
|
+
/// Swift/Objective-C++ targets (SE-0403) and never emits that header, so the
|
|
19
|
+
/// Objective-C target must not depend on Swift at compile time.
|
|
20
|
+
@protocol IMGLYEditorModuleImplementation <NSObject>
|
|
21
|
+
|
|
22
|
+
/// Opens the creative editor.
|
|
23
|
+
/// - Parameters:
|
|
24
|
+
/// - settings: The raw editor settings as received from JavaScript.
|
|
25
|
+
/// - preset: The raw editor preset identifier as received from JavaScript.
|
|
26
|
+
/// - metadata: Any custom metadata as received from JavaScript.
|
|
27
|
+
/// - resolve: The block to invoke with the export result, or `NSNull` on cancellation.
|
|
28
|
+
/// - reject: The block to invoke when parsing or the export fails.
|
|
29
|
+
- (void)openEditorWithSettings:(NSDictionary*)settings
|
|
30
|
+
preset:(nullable NSString*)preset
|
|
31
|
+
metadata:(nullable NSDictionary*)metadata
|
|
32
|
+
resolve:(IMGLYEditorResolveBlock)resolve
|
|
33
|
+
reject:(IMGLYEditorRejectBlock)reject;
|
|
34
|
+
|
|
35
|
+
@end
|
|
36
|
+
|
|
37
|
+
/// Resolves the Swift implementation of the editor module at runtime.
|
|
38
|
+
@interface IMGLYEditorModuleImplementationProvider : NSObject
|
|
39
|
+
|
|
40
|
+
/// The resolved implementation, or `nil` when the Swift part of this module
|
|
41
|
+
/// was not linked into the app.
|
|
42
|
+
+ (nullable id<IMGLYEditorModuleImplementation>)implementation;
|
|
43
|
+
|
|
44
|
+
@end
|
|
45
|
+
|
|
46
|
+
NS_ASSUME_NONNULL_END
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@imgly/editor-react-native",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.82.0-rc.0",
|
|
4
4
|
"description": "CreativeEditor SDK for React Native - enable photo, video and design editing for your users on iOS and Android.",
|
|
5
5
|
"react-native": "index.js",
|
|
6
6
|
"source": "index.js",
|
package/src/NativeIMGLYEditor.ts
CHANGED
|
@@ -96,7 +96,7 @@ export class EditorSettingsModel implements EditorSettings {
|
|
|
96
96
|
* sources (stickers, filters, and more).
|
|
97
97
|
*/
|
|
98
98
|
baseUri: string =
|
|
99
|
-
'https://cdn.img.ly/packages/imgly/cesdk-react-native/1.
|
|
99
|
+
'https://cdn.img.ly/packages/imgly/cesdk-react-native/1.82.0-rc.0/assets';
|
|
100
100
|
|
|
101
101
|
/**
|
|
102
102
|
* Unique ID tied to your application's user.
|
|
File without changes
|