Fixed iOS share extension
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -5,9 +5,11 @@
|
|||||||
*.swp
|
*.swp
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.atom/
|
.atom/
|
||||||
|
.build/
|
||||||
.buildlog/
|
.buildlog/
|
||||||
.history
|
.history
|
||||||
.svn/
|
.svn/
|
||||||
|
.swiftpm/
|
||||||
migrate_working_dir/
|
migrate_working_dir/
|
||||||
|
|
||||||
# IntelliJ related
|
# IntelliJ related
|
||||||
|
|||||||
@@ -35,6 +35,10 @@ target 'Runner' do
|
|||||||
target 'RunnerTests' do
|
target 'RunnerTests' do
|
||||||
inherit! :search_paths
|
inherit! :search_paths
|
||||||
end
|
end
|
||||||
|
|
||||||
|
target 'Share Extension' do
|
||||||
|
inherit! :search_paths
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
post_install do |installer|
|
post_install do |installer|
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ PODS:
|
|||||||
- device_info_plus (0.0.1):
|
- device_info_plus (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- Flutter (1.0.0)
|
- Flutter (1.0.0)
|
||||||
- flutter_custom_tabs_ios (2.0.0):
|
- flutter_custom_tabs_ios (2.2.0):
|
||||||
- Flutter
|
- Flutter
|
||||||
- flutter_native_splash (0.0.1):
|
- flutter_native_splash (2.4.3):
|
||||||
- Flutter
|
- Flutter
|
||||||
- irondash_engine_context (0.0.1):
|
- irondash_engine_context (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
@@ -13,13 +13,13 @@ PODS:
|
|||||||
- path_provider_foundation (0.0.1):
|
- path_provider_foundation (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- receive_sharing_intent_plus (1.0.1):
|
- receive_sharing_intent (1.8.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- Sentry/HybridSDK (8.30.1)
|
- Sentry/HybridSDK (8.46.0)
|
||||||
- sentry_flutter (8.4.0):
|
- sentry_flutter (8.14.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- Sentry/HybridSDK (= 8.30.1)
|
- Sentry/HybridSDK (= 8.46.0)
|
||||||
- share_plus (0.0.1):
|
- share_plus (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- shared_preferences_foundation (0.0.1):
|
- shared_preferences_foundation (0.0.1):
|
||||||
@@ -31,6 +31,7 @@ PODS:
|
|||||||
- Flutter
|
- Flutter
|
||||||
- webview_flutter_wkwebview (0.0.1):
|
- webview_flutter_wkwebview (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
|
- FlutterMacOS
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
||||||
@@ -40,13 +41,13 @@ DEPENDENCIES:
|
|||||||
- irondash_engine_context (from `.symlinks/plugins/irondash_engine_context/ios`)
|
- irondash_engine_context (from `.symlinks/plugins/irondash_engine_context/ios`)
|
||||||
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
||||||
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
|
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
|
||||||
- receive_sharing_intent_plus (from `.symlinks/plugins/receive_sharing_intent_plus/ios`)
|
- receive_sharing_intent (from `.symlinks/plugins/receive_sharing_intent/ios`)
|
||||||
- sentry_flutter (from `.symlinks/plugins/sentry_flutter/ios`)
|
- sentry_flutter (from `.symlinks/plugins/sentry_flutter/ios`)
|
||||||
- share_plus (from `.symlinks/plugins/share_plus/ios`)
|
- share_plus (from `.symlinks/plugins/share_plus/ios`)
|
||||||
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
||||||
- super_native_extensions (from `.symlinks/plugins/super_native_extensions/ios`)
|
- super_native_extensions (from `.symlinks/plugins/super_native_extensions/ios`)
|
||||||
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
||||||
- webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`)
|
- webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/darwin`)
|
||||||
|
|
||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
trunk:
|
trunk:
|
||||||
@@ -67,8 +68,8 @@ EXTERNAL SOURCES:
|
|||||||
:path: ".symlinks/plugins/package_info_plus/ios"
|
:path: ".symlinks/plugins/package_info_plus/ios"
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
:path: ".symlinks/plugins/path_provider_foundation/darwin"
|
:path: ".symlinks/plugins/path_provider_foundation/darwin"
|
||||||
receive_sharing_intent_plus:
|
receive_sharing_intent:
|
||||||
:path: ".symlinks/plugins/receive_sharing_intent_plus/ios"
|
:path: ".symlinks/plugins/receive_sharing_intent/ios"
|
||||||
sentry_flutter:
|
sentry_flutter:
|
||||||
:path: ".symlinks/plugins/sentry_flutter/ios"
|
:path: ".symlinks/plugins/sentry_flutter/ios"
|
||||||
share_plus:
|
share_plus:
|
||||||
@@ -80,25 +81,25 @@ EXTERNAL SOURCES:
|
|||||||
url_launcher_ios:
|
url_launcher_ios:
|
||||||
:path: ".symlinks/plugins/url_launcher_ios/ios"
|
:path: ".symlinks/plugins/url_launcher_ios/ios"
|
||||||
webview_flutter_wkwebview:
|
webview_flutter_wkwebview:
|
||||||
:path: ".symlinks/plugins/webview_flutter_wkwebview/ios"
|
:path: ".symlinks/plugins/webview_flutter_wkwebview/darwin"
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d
|
device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d
|
||||||
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
|
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
|
||||||
flutter_custom_tabs_ios: a651b18786388923b62de8c0537607de87c2eccf
|
flutter_custom_tabs_ios: 194897f423eb72b086009d34136ada2fa321cda2
|
||||||
flutter_native_splash: edf599c81f74d093a4daf8e17bd7a018854bc778
|
flutter_native_splash: df59bb2e1421aa0282cb2e95618af4dcb0c56c29
|
||||||
irondash_engine_context: 3458bf979b90d616ffb8ae03a150bafe2e860cc9
|
irondash_engine_context: 3458bf979b90d616ffb8ae03a150bafe2e860cc9
|
||||||
package_info_plus: 58f0028419748fad15bf008b270aaa8e54380b1c
|
package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4
|
||||||
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
|
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
|
||||||
receive_sharing_intent_plus: f02db0a23c17f7aeef8de465cb2d8705a46143a6
|
receive_sharing_intent: 79c848f5b045674ad60b9fea3bafea59962ad2c1
|
||||||
Sentry: 514a3ea653886e9a48c6287d8b7bf05ec24bf3be
|
Sentry: da60d980b197a46db0b35ea12cb8f39af48d8854
|
||||||
sentry_flutter: edc037f7af0dc1512d6c33a5c2c7c838bd0d6806
|
sentry_flutter: 6a134f9d381e49f22ea25a67736cf0cf4d02ec9c
|
||||||
share_plus: 8875f4f2500512ea181eef553c3e27dba5135aad
|
share_plus: 8875f4f2500512ea181eef553c3e27dba5135aad
|
||||||
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
|
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
|
||||||
super_native_extensions: 4916b3c627a9c7fffdc48a23a9eca0b1ac228fa7
|
super_native_extensions: 4916b3c627a9c7fffdc48a23a9eca0b1ac228fa7
|
||||||
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
|
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
|
||||||
webview_flutter_wkwebview: 2a23822e9039b7b1bc52e5add778e5d89ad488d1
|
webview_flutter_wkwebview: a4af96a051138e28e29f60101d094683b9f82188
|
||||||
|
|
||||||
PODFILE CHECKSUM: 819463e6a0290f5a72f145ba7cde16e8b6ef0796
|
PODFILE CHECKSUM: 34ecb9fa7bc683e441dba3fa6c29261a8d697f71
|
||||||
|
|
||||||
COCOAPODS: 1.15.2
|
COCOAPODS: 1.16.2
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
0DD98D4F2BAE797F00804BE7 /* Base in Resources */ = {isa = PBXBuildFile; fileRef = 0DD98D4E2BAE797F00804BE7 /* Base */; };
|
0DD98D4F2BAE797F00804BE7 /* Base in Resources */ = {isa = PBXBuildFile; fileRef = 0DD98D4E2BAE797F00804BE7 /* Base */; };
|
||||||
0DD98D532BAE797F00804BE7 /* Share Extension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 0DD98D492BAE797F00804BE7 /* Share Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
0DD98D532BAE797F00804BE7 /* Share Extension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 0DD98D492BAE797F00804BE7 /* Share Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
||||||
|
1E57812B8C12FEC8D79AD975 /* Pods_Share_Extension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D82812D4EFCC75C7B0FDB517 /* Pods_Share_Extension.framework */; };
|
||||||
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
|
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
|
||||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
||||||
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
|
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
|
||||||
@@ -67,6 +68,7 @@
|
|||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
028E6C730A588E1E84511D36 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
028E6C730A588E1E84511D36 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
033AEC9585A60167C7A7CE55 /* Pods-Share Extension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Share Extension.release.xcconfig"; path = "Target Support Files/Pods-Share Extension/Pods-Share Extension.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
0D88524F2BB0F36E0049FE7A /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
|
0D88524F2BB0F36E0049FE7A /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
|
||||||
0DD98D492BAE797F00804BE7 /* Share Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "Share Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
|
0DD98D492BAE797F00804BE7 /* Share Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "Share Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
0DD98D4B2BAE797F00804BE7 /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = "<group>"; };
|
0DD98D4B2BAE797F00804BE7 /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = "<group>"; };
|
||||||
@@ -79,6 +81,7 @@
|
|||||||
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
|
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
|
||||||
331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
||||||
|
67C02B529825EA1C87E41529 /* Pods-Share Extension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Share Extension.debug.xcconfig"; path = "Target Support Files/Pods-Share Extension/Pods-Share Extension.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
|
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||||
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
|
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
|
||||||
@@ -92,9 +95,11 @@
|
|||||||
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
ABB81CF75DD6CCAA2824780A /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
ABB81CF75DD6CCAA2824780A /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
D7D2E01FF2421427934DCB2A /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
|
D7D2E01FF2421427934DCB2A /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
D82812D4EFCC75C7B0FDB517 /* Pods_Share_Extension.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Share_Extension.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
E4533A4D5154C6705434104C /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
E4533A4D5154C6705434104C /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
F0C2D0B1825F8EE28A1E5C13 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
|
F0C2D0B1825F8EE28A1E5C13 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
F7EBE0A0B68411B7E3F62A40 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
|
F7EBE0A0B68411B7E3F62A40 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
FAF7552BBEA34A8D0259E3C6 /* Pods-Share Extension.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Share Extension.profile.xcconfig"; path = "Target Support Files/Pods-Share Extension/Pods-Share Extension.profile.xcconfig"; sourceTree = "<group>"; };
|
||||||
FE730FDF3A8382D8C7AE8CCB /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
|
FE730FDF3A8382D8C7AE8CCB /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
@@ -103,6 +108,7 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
1E57812B8C12FEC8D79AD975 /* Pods_Share_Extension.framework in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -149,6 +155,7 @@
|
|||||||
children = (
|
children = (
|
||||||
E4533A4D5154C6705434104C /* Pods_Runner.framework */,
|
E4533A4D5154C6705434104C /* Pods_Runner.framework */,
|
||||||
ABB81CF75DD6CCAA2824780A /* Pods_RunnerTests.framework */,
|
ABB81CF75DD6CCAA2824780A /* Pods_RunnerTests.framework */,
|
||||||
|
D82812D4EFCC75C7B0FDB517 /* Pods_Share_Extension.framework */,
|
||||||
);
|
);
|
||||||
name = Frameworks;
|
name = Frameworks;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -162,6 +169,9 @@
|
|||||||
D7D2E01FF2421427934DCB2A /* Pods-RunnerTests.debug.xcconfig */,
|
D7D2E01FF2421427934DCB2A /* Pods-RunnerTests.debug.xcconfig */,
|
||||||
FE730FDF3A8382D8C7AE8CCB /* Pods-RunnerTests.release.xcconfig */,
|
FE730FDF3A8382D8C7AE8CCB /* Pods-RunnerTests.release.xcconfig */,
|
||||||
8E8607A85826990422E9A93E /* Pods-RunnerTests.profile.xcconfig */,
|
8E8607A85826990422E9A93E /* Pods-RunnerTests.profile.xcconfig */,
|
||||||
|
67C02B529825EA1C87E41529 /* Pods-Share Extension.debug.xcconfig */,
|
||||||
|
033AEC9585A60167C7A7CE55 /* Pods-Share Extension.release.xcconfig */,
|
||||||
|
FAF7552BBEA34A8D0259E3C6 /* Pods-Share Extension.profile.xcconfig */,
|
||||||
);
|
);
|
||||||
path = Pods;
|
path = Pods;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -224,6 +234,7 @@
|
|||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 0DD98D582BAE797F00804BE7 /* Build configuration list for PBXNativeTarget "Share Extension" */;
|
buildConfigurationList = 0DD98D582BAE797F00804BE7 /* Build configuration list for PBXNativeTarget "Share Extension" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
|
1CD2B5D70FA0C78B9CD70358 /* [CP] Check Pods Manifest.lock */,
|
||||||
0DD98D452BAE797F00804BE7 /* Sources */,
|
0DD98D452BAE797F00804BE7 /* Sources */,
|
||||||
0DD98D462BAE797F00804BE7 /* Frameworks */,
|
0DD98D462BAE797F00804BE7 /* Frameworks */,
|
||||||
0DD98D472BAE797F00804BE7 /* Resources */,
|
0DD98D472BAE797F00804BE7 /* Resources */,
|
||||||
@@ -357,6 +368,28 @@
|
|||||||
/* End PBXResourcesBuildPhase section */
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXShellScriptBuildPhase section */
|
/* Begin PBXShellScriptBuildPhase section */
|
||||||
|
1CD2B5D70FA0C78B9CD70358 /* [CP] Check Pods Manifest.lock */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||||
|
"${PODS_ROOT}/Manifest.lock",
|
||||||
|
);
|
||||||
|
name = "[CP] Check Pods Manifest.lock";
|
||||||
|
outputFileListPaths = (
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
"$(DERIVED_FILE_DIR)/Pods-Share Extension-checkManifestLockResult.txt",
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
3A41E757C007027010B2D4CC /* [CP] Check Pods Manifest.lock */ = {
|
3A41E757C007027010B2D4CC /* [CP] Check Pods Manifest.lock */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
@@ -522,6 +555,7 @@
|
|||||||
/* Begin XCBuildConfiguration section */
|
/* Begin XCBuildConfiguration section */
|
||||||
0DD98D552BAE797F00804BE7 /* Debug */ = {
|
0DD98D552BAE797F00804BE7 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = 67C02B529825EA1C87E41529 /* Pods-Share Extension.debug.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
@@ -564,6 +598,7 @@
|
|||||||
};
|
};
|
||||||
0DD98D562BAE797F00804BE7 /* Release */ = {
|
0DD98D562BAE797F00804BE7 /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = 033AEC9585A60167C7A7CE55 /* Pods-Share Extension.release.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
@@ -603,6 +638,7 @@
|
|||||||
};
|
};
|
||||||
0DD98D572BAE797F00804BE7 /* Profile */ = {
|
0DD98D572BAE797F00804BE7 /* Profile */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = FAF7552BBEA34A8D0259E3C6 /* Pods-Share Extension.profile.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
|||||||
@@ -59,6 +59,7 @@
|
|||||||
ignoresPersistentStateOnLaunch = "NO"
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
debugDocumentVersioning = "YES"
|
debugDocumentVersioning = "YES"
|
||||||
debugServiceExtension = "internal"
|
debugServiceExtension = "internal"
|
||||||
|
enableGPUValidationMode = "1"
|
||||||
allowLocationSimulation = "YES">
|
allowLocationSimulation = "YES">
|
||||||
<BuildableProductRunnable
|
<BuildableProductRunnable
|
||||||
runnableDebuggingMode = "0">
|
runnableDebuggingMode = "0">
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
import Flutter
|
import Flutter
|
||||||
|
|
||||||
@UIApplicationMain
|
@main
|
||||||
@objc class AppDelegate: FlutterAppDelegate {
|
@objc class AppDelegate: FlutterAppDelegate {
|
||||||
override func application(
|
override func application(
|
||||||
_ application: UIApplication,
|
_ application: UIApplication,
|
||||||
|
|||||||
@@ -1,351 +1,14 @@
|
|||||||
import UIKit
|
// If you get no such module 'receive_sharing_intent' error.
|
||||||
import Social
|
// Go to Build Phases of your Runner target and
|
||||||
import MobileCoreServices
|
// move `Embed Foundation Extension` to the top of `Thin Binary`.
|
||||||
import Photos
|
import receive_sharing_intent
|
||||||
|
|
||||||
class ShareViewController: SLComposeServiceViewController {
|
class ShareViewController: RSIShareViewController {
|
||||||
var hostAppBundleIdentifier = "com.jgeek00.linkdy"
|
|
||||||
var appGroupId = "group.com.jgeek00.linkdy"
|
|
||||||
let sharedKey = "ShareKey"
|
|
||||||
var sharedMedia: [SharedMediaFile] = []
|
|
||||||
var sharedText: [String] = []
|
|
||||||
let imageContentType = kUTTypeImage as String
|
|
||||||
let videoContentType = kUTTypeMovie as String
|
|
||||||
let textContentType = kUTTypeText as String
|
|
||||||
let urlContentType = kUTTypeURL as String
|
|
||||||
let fileURLType = kUTTypeFileURL as String
|
|
||||||
|
|
||||||
override func isContentValid() -> Bool {
|
// Use this method to return false if you don't want to redirect to host app automatically.
|
||||||
return true
|
// Default is true
|
||||||
}
|
override func shouldAutoRedirect() -> Bool {
|
||||||
|
|
||||||
private func loadIds() {
|
|
||||||
// loading Share extension App Id
|
|
||||||
let shareExtensionAppBundleIdentifier = Bundle.main.bundleIdentifier!
|
|
||||||
|
|
||||||
// convert ShareExtension id to host app id
|
|
||||||
// By default it is removed the last part of id after the last point
|
|
||||||
// For example: com.test.ShareExtension -> com.test
|
|
||||||
if let lastIndexOfPoint = shareExtensionAppBundleIdentifier.lastIndex(of: ".") {
|
|
||||||
hostAppBundleIdentifier = String(shareExtensionAppBundleIdentifier[..<lastIndexOfPoint])
|
|
||||||
}
|
|
||||||
|
|
||||||
// loading custom AppGroupId from Build Settings or use group.<hostAppBundleIdentifier>
|
|
||||||
appGroupId = (Bundle.main.object(forInfoDictionaryKey: "AppGroupId") as? String) ?? "group.\(hostAppBundleIdentifier)"
|
|
||||||
}
|
|
||||||
|
|
||||||
override func viewDidLoad() {
|
|
||||||
super.viewDidLoad()
|
|
||||||
|
|
||||||
// load group and app id from build info
|
|
||||||
loadIds()
|
|
||||||
}
|
|
||||||
|
|
||||||
override func viewDidAppear(_ animated: Bool) {
|
|
||||||
super.viewDidAppear(animated)
|
|
||||||
|
|
||||||
// This is called after the user selects Post. Do the upload of contentText and/or NSExtensionContext attachments.
|
|
||||||
if let content = extensionContext?.inputItems[0] as? NSExtensionItem {
|
|
||||||
if let contents = content.attachments {
|
|
||||||
for (index, attachment) in contents.enumerated() {
|
|
||||||
if attachment.hasItemConformingToTypeIdentifier(imageContentType) {
|
|
||||||
handleImages(content: content, attachment: attachment, index: index)
|
|
||||||
} else if attachment.hasItemConformingToTypeIdentifier(textContentType) {
|
|
||||||
handleText(content: content, attachment: attachment, index: index)
|
|
||||||
} else if attachment.hasItemConformingToTypeIdentifier(fileURLType) {
|
|
||||||
handleFiles(content: content, attachment: attachment, index: index)
|
|
||||||
} else if attachment.hasItemConformingToTypeIdentifier(urlContentType) {
|
|
||||||
handleUrl(content: content, attachment: attachment, index: index)
|
|
||||||
} else if attachment.hasItemConformingToTypeIdentifier(videoContentType) {
|
|
||||||
handleVideos(content: content, attachment: attachment, index: index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override func didSelectPost() {
|
|
||||||
print("didSelectPost")
|
|
||||||
}
|
|
||||||
|
|
||||||
override func configurationItems() -> [Any]! {
|
|
||||||
// To add configuration options via table cells at the bottom of the sheet, return an array of SLComposeSheetConfigurationItem here.
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
|
|
||||||
private func handleText(content: NSExtensionItem, attachment: NSItemProvider, index: Int) {
|
|
||||||
attachment.loadItem(forTypeIdentifier: textContentType, options: nil) { [weak self] data, error in
|
|
||||||
|
|
||||||
if error == nil, let item = data as? String, let this = self {
|
|
||||||
|
|
||||||
this.sharedText.append(item)
|
|
||||||
|
|
||||||
// If this is the last item, save imagesData in userDefaults and redirect to the host app
|
|
||||||
if index == (content.attachments?.count)! - 1 {
|
|
||||||
let userDefaults = UserDefaults(suiteName: this.appGroupId)
|
|
||||||
userDefaults?.set(this.sharedText, forKey: this.sharedKey)
|
|
||||||
userDefaults?.synchronize()
|
|
||||||
this.redirectToHostApp(type: .text)
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
self?.dismissWithError()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func handleUrl(content: NSExtensionItem, attachment: NSItemProvider, index: Int) {
|
|
||||||
attachment.loadItem(forTypeIdentifier: urlContentType, options: nil) { [weak self] data, error in
|
|
||||||
|
|
||||||
if error == nil, let item = data as? URL, let this = self {
|
|
||||||
|
|
||||||
this.sharedText.append(item.absoluteString)
|
|
||||||
|
|
||||||
// If this is the last item, save imagesData in userDefaults and redirect to the host app
|
|
||||||
if index == (content.attachments?.count)! - 1 {
|
|
||||||
let userDefaults = UserDefaults(suiteName: this.appGroupId)
|
|
||||||
userDefaults?.set(this.sharedText, forKey: this.sharedKey)
|
|
||||||
userDefaults?.synchronize()
|
|
||||||
this.redirectToHostApp(type: .text)
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
self?.dismissWithError()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func handleImages(content: NSExtensionItem, attachment: NSItemProvider, index: Int) {
|
|
||||||
attachment.loadItem(forTypeIdentifier: imageContentType, options: nil) { [weak self] data, error in
|
|
||||||
|
|
||||||
if error == nil, let url = data as? URL, let this = self {
|
|
||||||
|
|
||||||
// Always copy
|
|
||||||
let fileName = this.getFileName(from: url, type: .image)
|
|
||||||
let newPath = FileManager.default
|
|
||||||
.containerURL(forSecurityApplicationGroupIdentifier: this.appGroupId)!
|
|
||||||
.appendingPathComponent(fileName)
|
|
||||||
let copied = this.copyFile(at: url, to: newPath)
|
|
||||||
if copied {
|
|
||||||
this.sharedMedia.append(SharedMediaFile(path: newPath.absoluteString, thumbnail: nil, duration: nil, type: .image))
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this is the last item, save imagesData in userDefaults and redirect to the host app
|
|
||||||
if index == (content.attachments?.count)! - 1 {
|
|
||||||
let userDefaults = UserDefaults(suiteName: this.appGroupId)
|
|
||||||
userDefaults?.set(this.toData(data: this.sharedMedia), forKey: this.sharedKey)
|
|
||||||
userDefaults?.synchronize()
|
|
||||||
this.redirectToHostApp(type: .media)
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
self?.dismissWithError()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func handleVideos(content: NSExtensionItem, attachment: NSItemProvider, index: Int) {
|
|
||||||
attachment.loadItem(forTypeIdentifier: videoContentType, options: nil) { [weak self] data, error in
|
|
||||||
|
|
||||||
if error == nil, let url = data as? URL, let this = self {
|
|
||||||
|
|
||||||
// Always copy
|
|
||||||
let fileName = this.getFileName(from: url, type: .video)
|
|
||||||
let newPath = FileManager.default
|
|
||||||
.containerURL(forSecurityApplicationGroupIdentifier: this.appGroupId)!
|
|
||||||
.appendingPathComponent(fileName)
|
|
||||||
let copied = this.copyFile(at: url, to: newPath)
|
|
||||||
if copied {
|
|
||||||
guard let sharedFile = this.getSharedMediaFile(forVideo: newPath) else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.sharedMedia.append(sharedFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this is the last item, save imagesData in userDefaults and redirect to the host app
|
|
||||||
if index == (content.attachments?.count)! - 1 {
|
|
||||||
let userDefaults = UserDefaults(suiteName: this.appGroupId)
|
|
||||||
userDefaults?.set(this.toData(data: this.sharedMedia), forKey: this.sharedKey)
|
|
||||||
userDefaults?.synchronize()
|
|
||||||
this.redirectToHostApp(type: .media)
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
self?.dismissWithError()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func handleFiles(content: NSExtensionItem, attachment: NSItemProvider, index: Int) {
|
|
||||||
attachment.loadItem(forTypeIdentifier: fileURLType, options: nil) { [weak self] data, error in
|
|
||||||
|
|
||||||
if error == nil, let url = data as? URL, let this = self {
|
|
||||||
|
|
||||||
// Always copy
|
|
||||||
let fileName = this.getFileName(from: url, type: .file)
|
|
||||||
let newPath = FileManager.default
|
|
||||||
.containerURL(forSecurityApplicationGroupIdentifier: this.appGroupId)!
|
|
||||||
.appendingPathComponent(fileName)
|
|
||||||
let copied = this.copyFile(at: url, to: newPath)
|
|
||||||
if copied {
|
|
||||||
this.sharedMedia.append(SharedMediaFile(path: newPath.absoluteString, thumbnail: nil, duration: nil, type: .file))
|
|
||||||
}
|
|
||||||
|
|
||||||
if index == (content.attachments?.count)! - 1 {
|
|
||||||
let userDefaults = UserDefaults(suiteName: this.appGroupId)
|
|
||||||
userDefaults?.set(this.toData(data: this.sharedMedia), forKey: this.sharedKey)
|
|
||||||
userDefaults?.synchronize()
|
|
||||||
this.redirectToHostApp(type: .file)
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
self?.dismissWithError()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func dismissWithError() {
|
|
||||||
print("[ERROR] Error loading data!")
|
|
||||||
let alert = UIAlertController(title: "Error", message: "Error loading data", preferredStyle: .alert)
|
|
||||||
|
|
||||||
let action = UIAlertAction(title: "Error", style: .cancel) { _ in
|
|
||||||
self.dismiss(animated: true, completion: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
alert.addAction(action)
|
|
||||||
present(alert, animated: true, completion: nil)
|
|
||||||
extensionContext?.completeRequest(returningItems: [], completionHandler: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func redirectToHostApp(type: RedirectType) {
|
|
||||||
// ids may not be loaded yet so we need loadIds here too
|
|
||||||
loadIds()
|
|
||||||
let url = URL(string: "ShareMedia-\(hostAppBundleIdentifier)://dataUrl=\(sharedKey)#\(type)")
|
|
||||||
var responder = self as UIResponder?
|
|
||||||
let selectorOpenURL = sel_registerName("openURL:")
|
|
||||||
|
|
||||||
while (responder != nil) {
|
|
||||||
if (responder?.responds(to: selectorOpenURL))! {
|
|
||||||
let _ = responder?.perform(selectorOpenURL, with: url)
|
|
||||||
}
|
|
||||||
responder = responder?.next
|
|
||||||
}
|
|
||||||
extensionContext?.completeRequest(returningItems: [], completionHandler: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
enum RedirectType {
|
|
||||||
case media
|
|
||||||
case text
|
|
||||||
case file
|
|
||||||
}
|
|
||||||
|
|
||||||
func getExtension(from url: URL, type: SharedMediaType) -> String {
|
|
||||||
let parts = url.lastPathComponent.components(separatedBy: ".")
|
|
||||||
var ex: String? = nil
|
|
||||||
if (parts.count > 1) {
|
|
||||||
ex = parts.last
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ex == nil) {
|
|
||||||
switch type {
|
|
||||||
case .image:
|
|
||||||
ex = "PNG"
|
|
||||||
case .video:
|
|
||||||
ex = "MP4"
|
|
||||||
case .file:
|
|
||||||
ex = "TXT"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ex ?? "Unknown"
|
|
||||||
}
|
|
||||||
|
|
||||||
func getFileName(from url: URL, type: SharedMediaType) -> String {
|
|
||||||
var name = url.lastPathComponent
|
|
||||||
|
|
||||||
if (name.isEmpty) {
|
|
||||||
name = UUID().uuidString + "." + getExtension(from: url, type: type)
|
|
||||||
}
|
|
||||||
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
|
|
||||||
func copyFile(at srcURL: URL, to dstURL: URL) -> Bool {
|
|
||||||
do {
|
|
||||||
if FileManager.default.fileExists(atPath: dstURL.path) {
|
|
||||||
try FileManager.default.removeItem(at: dstURL)
|
|
||||||
}
|
|
||||||
try FileManager.default.copyItem(at: srcURL, to: dstURL)
|
|
||||||
} catch (let error) {
|
|
||||||
print("Cannot copy item at \(srcURL) to \(dstURL): \(error)")
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
private func getSharedMediaFile(forVideo: URL) -> SharedMediaFile? {
|
|
||||||
let asset = AVAsset(url: forVideo)
|
|
||||||
let duration = (CMTimeGetSeconds(asset.duration) * 1000).rounded()
|
|
||||||
let thumbnailPath = getThumbnailPath(for: forVideo)
|
|
||||||
|
|
||||||
if FileManager.default.fileExists(atPath: thumbnailPath.path) {
|
|
||||||
return SharedMediaFile(path: forVideo.absoluteString, thumbnail: thumbnailPath.absoluteString, duration: duration, type: .video)
|
|
||||||
}
|
|
||||||
|
|
||||||
var saved = false
|
|
||||||
let assetImgGenerate = AVAssetImageGenerator(asset: asset)
|
|
||||||
assetImgGenerate.appliesPreferredTrackTransform = true
|
|
||||||
assetImgGenerate.maximumSize = CGSize(width: 360, height: 360)
|
|
||||||
do {
|
|
||||||
let img = try assetImgGenerate.copyCGImage(at: CMTimeMakeWithSeconds(600, preferredTimescale: Int32(1.0)), actualTime: nil)
|
|
||||||
try UIImage.pngData(UIImage(cgImage: img))()?.write(to: thumbnailPath)
|
|
||||||
saved = true
|
|
||||||
} catch {
|
|
||||||
saved = false
|
|
||||||
}
|
|
||||||
|
|
||||||
return saved ? SharedMediaFile(path: forVideo.absoluteString, thumbnail: thumbnailPath.absoluteString, duration: duration, type: .video) : nil
|
|
||||||
}
|
|
||||||
|
|
||||||
private func getThumbnailPath(for url: URL) -> URL {
|
|
||||||
let fileName = Data(url.lastPathComponent.utf8).base64EncodedString().replacingOccurrences(of: "==", with: "")
|
|
||||||
let path = FileManager.default
|
|
||||||
.containerURL(forSecurityApplicationGroupIdentifier: appGroupId)!
|
|
||||||
.appendingPathComponent("\(fileName).jpg")
|
|
||||||
return path
|
|
||||||
}
|
|
||||||
|
|
||||||
class SharedMediaFile: Codable {
|
|
||||||
var path: String
|
|
||||||
var thumbnail: String?
|
|
||||||
var duration: Double?
|
|
||||||
var type: SharedMediaType
|
|
||||||
|
|
||||||
init(path: String, thumbnail: String?, duration: Double?, type: SharedMediaType) {
|
|
||||||
self.path = path
|
|
||||||
self.thumbnail = thumbnail
|
|
||||||
self.duration = duration
|
|
||||||
self.type = type
|
|
||||||
}
|
|
||||||
|
|
||||||
func toString() {
|
|
||||||
print("[SharedMediaFile] \n\tpath: \(self.path)\n\tthumbnail: \(self.thumbnail)\n\tduration: \(self.duration)\n\ttype: \(self.type)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum SharedMediaType: Int, Codable {
|
|
||||||
case image
|
|
||||||
case video
|
|
||||||
case file
|
|
||||||
}
|
|
||||||
|
|
||||||
func toData(data: [SharedMediaFile]) -> Data {
|
|
||||||
let encodedData = try? JSONEncoder().encode(data)
|
|
||||||
return encodedData ?? Data()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Array {
|
|
||||||
subscript (safe index: UInt) -> Element? {
|
|
||||||
return Int(index) < count ? self[Int(index)] : nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user