shakebug-react-native 1.0.14
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/DeviceInfo/index.js.flow +177 -0
- package/DeviceInfo/index.ts +1034 -0
- package/DeviceInfo/internal/asyncHookWrappers.ts +59 -0
- package/DeviceInfo/internal/devicesWithDynamicIsland.ts +30 -0
- package/DeviceInfo/internal/devicesWithNotch.ts +374 -0
- package/DeviceInfo/internal/nativeInterface.ts +28 -0
- package/DeviceInfo/internal/privateTypes.ts +231 -0
- package/DeviceInfo/internal/supported-platform-info.ts +97 -0
- package/DeviceInfo/internal/types.ts +19 -0
- package/DeviceInfo/web/index.js +223 -0
- package/GetLocals/src/NativeRNLocalize.ts +18 -0
- package/GetLocals/src/constants.ts +269 -0
- package/GetLocals/src/index.ts +56 -0
- package/GetLocals/src/module.ts +51 -0
- package/GetLocals/src/module.web.ts +148 -0
- package/GetLocals/src/types.ts +31 -0
- package/GetLocation/LocationError.ts +20 -0
- package/GetLocation/index.ts +46 -0
- package/GetLocation/utils.ts +89 -0
- package/ImageOrVedioPicker/src/index.ts +28 -0
- package/ImageOrVedioPicker/src/platforms/NativeImagePicker.ts +10 -0
- package/ImageOrVedioPicker/src/platforms/native.ts +61 -0
- package/ImageOrVedioPicker/src/platforms/web.ts +159 -0
- package/ImageOrVedioPicker/src/types.ts +74 -0
- package/NetInfo/src/__tests__/eventListenerCallbacks.spec.ts +332 -0
- package/NetInfo/src/__tests__/fetch.spec.ts +479 -0
- package/NetInfo/src/index.ts +186 -0
- package/NetInfo/src/internal/__mocks__/nativeModule.ts +13 -0
- package/NetInfo/src/internal/defaultConfiguration.ts +17 -0
- package/NetInfo/src/internal/defaultConfiguration.web.ts +17 -0
- package/NetInfo/src/internal/internetReachability.ts +180 -0
- package/NetInfo/src/internal/nativeInterface.ts +43 -0
- package/NetInfo/src/internal/nativeInterface.web.ts +27 -0
- package/NetInfo/src/internal/nativeModule.ts +15 -0
- package/NetInfo/src/internal/nativeModule.web.ts +306 -0
- package/NetInfo/src/internal/privateTypes.ts +41 -0
- package/NetInfo/src/internal/state.ts +137 -0
- package/NetInfo/src/internal/types.ts +128 -0
- package/README.md +246 -0
- package/RecordScreen/src/index.tsx +75 -0
- package/ScreenShot/src/RNViewShot.js +3 -0
- package/ScreenShot/src/RNViewShot.web.js +42 -0
- package/ScreenShot/src/index.js +308 -0
- package/Sensor/src/index.js +14 -0
- package/Sensor/src/rnsensors.js +57 -0
- package/Sensor/src/sensors.js +97 -0
- package/VideoPlayer/PlayVideo.tsx +51 -0
- package/VideoPlayer/index.js +69 -0
- package/android/README.md +14 -0
- package/android/build/generated/source/buildConfig/debug/com/shakebug/BuildConfig.java +10 -0
- package/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/AndroidManifest.xml +42 -0
- package/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/output-metadata.json +18 -0
- package/android/build/intermediates/aar_metadata/debug/aar-metadata.properties +6 -0
- package/android/build/intermediates/annotation_processor_list/debug/annotationProcessors.json +1 -0
- package/android/build/intermediates/compile_library_classes_jar/debug/classes.jar +0 -0
- package/android/build/intermediates/compile_r_class_jar/debug/R.jar +0 -0
- package/android/build/intermediates/compile_symbol_list/debug/R.txt +47 -0
- package/android/build/intermediates/compiled_local_resources/debug/out/xml_imagepicker_provider_paths.xml.flat +0 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +12 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml +2 -0
- package/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +2 -0
- package/android/build/intermediates/incremental/mergeDebugShaders/merger.xml +2 -0
- package/android/build/intermediates/incremental/packageDebugAssets/merger.xml +2 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/BuildConfig.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/CustomMediaMetadataRetriever.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/ImageMetadata.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/ImagePickerProvider.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/Metadata.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/Options.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/RecordScreenModule$1.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/RecordScreenModule.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/Shakebug.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/ShakebugPackage.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/Utility.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/Utils.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/VideoMetadata.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/ViewShot$1.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/ViewShot$2.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/ViewShot$Formats.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/ViewShot$Results.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/ViewShot$ReusableByteArrayOutputStream.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/shakebug/ViewShot.class +0 -0
- package/android/build/intermediates/local_only_symbol_list/debug/R-def.txt +49 -0
- package/android/build/intermediates/manifest_merge_blame_file/debug/manifest-merger-blame-debug-report.txt +82 -0
- package/android/build/intermediates/merged_manifest/debug/AndroidManifest.xml +42 -0
- package/android/build/intermediates/navigation_json/debug/navigation.json +1 -0
- package/android/build/intermediates/packaged_res/debug/values/values.xml +25 -0
- package/android/build/intermediates/packaged_res/debug/xml/imagepicker_provider_paths.xml +4 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/BuildConfig.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/CustomMediaMetadataRetriever.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/ImageMetadata.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/ImagePickerProvider.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/Metadata.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/Options.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/RecordScreenModule$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/RecordScreenModule.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/Shakebug.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/ShakebugPackage.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/Utility.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/Utils.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/VideoMetadata.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/ViewShot$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/ViewShot$2.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/ViewShot$Formats.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/ViewShot$Results.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/ViewShot$ReusableByteArrayOutputStream.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/com/shakebug/ViewShot.class +0 -0
- package/android/build/intermediates/symbol_list_with_package_name/debug/package-aware-r.txt +48 -0
- package/android/build/outputs/logs/manifest-merger-debug-report.txt +97 -0
- package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
- package/android/build.gradle +235 -0
- package/android/src/main/AndroidManifest.xml +40 -0
- package/android/src/main/java/com/shakebug/AmazonFireDeviceConnectivityPoller.java +170 -0
- package/android/src/main/java/com/shakebug/BaseUtils.java +33 -0
- package/android/src/main/java/com/shakebug/BroadcastReceiverConnectivityReceiver.java +131 -0
- package/android/src/main/java/com/shakebug/ConnectivityReceiver.java +318 -0
- package/android/src/main/java/com/shakebug/CrashLoggerModule.java +48 -0
- package/android/src/main/java/com/shakebug/DateUtil.java +64 -0
- package/android/src/main/java/com/shakebug/DeviceType.java +18 -0
- package/android/src/main/java/com/shakebug/DeviceUtil.java +46 -0
- package/android/src/main/java/com/shakebug/DrawingView.java +90 -0
- package/android/src/main/java/com/shakebug/DrawingViewManager.java +38 -0
- package/android/src/main/java/com/shakebug/GetLocation.java +147 -0
- package/android/src/main/java/com/shakebug/ImageMetadata.java +42 -0
- package/android/src/main/java/com/shakebug/ImagePickerProvider.java +8 -0
- package/android/src/main/java/com/shakebug/Metadata.java +46 -0
- package/android/src/main/java/com/shakebug/NetInfoModule.java +79 -0
- package/android/src/main/java/com/shakebug/NetInfoUtils.java +50 -0
- package/android/src/main/java/com/shakebug/NetworkCallbackConnectivityReceiver.java +209 -0
- package/android/src/main/java/com/shakebug/Options.java +42 -0
- package/android/src/main/java/com/shakebug/RNDeviceModule.java +1036 -0
- package/android/src/main/java/com/shakebug/RNInstallReferrerClient.java +124 -0
- package/android/src/main/java/com/shakebug/RNLocalizeModule.java +79 -0
- package/android/src/main/java/com/shakebug/RNLocalizeModuleImpl.java +258 -0
- package/android/src/main/java/com/shakebug/ReactNativeGetLocationModule.java +95 -0
- package/android/src/main/java/com/shakebug/RecordScreenModule.java +202 -0
- package/android/src/main/java/com/shakebug/ScreenshotDetectorModule.java +63 -0
- package/android/src/main/java/com/shakebug/SettingsUtil.java +44 -0
- package/android/src/main/java/com/shakebug/Shakebug.java +181 -0
- package/android/src/main/java/com/shakebug/ShakebugPackage.java +75 -0
- package/android/src/main/java/com/shakebug/ShakebugSDKImagePickerModule.java +56 -0
- package/android/src/main/java/com/shakebug/ShakebugSDKImagePickerModuleImpl.java +230 -0
- package/android/src/main/java/com/shakebug/ShakebugSDKScreenShotModule.java +196 -0
- package/android/src/main/java/com/shakebug/SharedPreferencesModule.java +39 -0
- package/android/src/main/java/com/shakebug/UnitConverter.java +48 -0
- package/android/src/main/java/com/shakebug/Utility.java +29 -0
- package/android/src/main/java/com/shakebug/Utils.java +593 -0
- package/android/src/main/java/com/shakebug/VideoMetadata.java +91 -0
- package/android/src/main/java/com/shakebug/VideoPlayerModule.java +199 -0
- package/android/src/main/java/com/shakebug/VideoThumbnailModule.java +215 -0
- package/android/src/main/java/com/shakebug/VideoTrimModule.java +372 -0
- package/android/src/main/java/com/shakebug/ViewShot.java +627 -0
- package/android/src/main/java/com/shakebug/adapters/VideoTrimmerAdapter.java +54 -0
- package/android/src/main/java/com/shakebug/callback/SingleCallback.java +11 -0
- package/android/src/main/java/com/shakebug/interfaces/IVideoTrimmerView.java +5 -0
- package/android/src/main/java/com/shakebug/interfaces/VideoPlayerListner.java +5 -0
- package/android/src/main/java/com/shakebug/interfaces/VideoTrimListener.java +10 -0
- package/android/src/main/java/com/shakebug/resolver/DeviceIdResolver.java +87 -0
- package/android/src/main/java/com/shakebug/resolver/DeviceTypeResolver.java +94 -0
- package/android/src/main/java/com/shakebug/thread/BackgroundExecutor.java +246 -0
- package/android/src/main/java/com/shakebug/thread/UiThreadExecutor.java +120 -0
- package/android/src/main/java/com/shakebug/types/CellularGeneration.java +60 -0
- package/android/src/main/java/com/shakebug/types/ConnectionType.java +26 -0
- package/android/src/main/java/com/shakebug/utils/StorageUtil.java +139 -0
- package/android/src/main/java/com/shakebug/utils/VideoTrimmerUtil.java +89 -0
- package/android/src/main/java/com/shakebug/widgets/RangeSeekBarView.java +534 -0
- package/android/src/main/java/com/shakebug/widgets/SpacesItemDecoration2.java +32 -0
- package/android/src/main/java/com/shakebug/widgets/VideoPlayerView.java +429 -0
- package/android/src/main/java/com/shakebug/widgets/VideoTrimmerView.java +477 -0
- package/android/src/main/java/com/shakebug/widgets/ZVideoView.java +48 -0
- package/android/src/main/res/drawable/custom_progress.xml +16 -0
- package/android/src/main/res/drawable/custom_thumb.xml +4 -0
- package/android/src/main/res/drawable/ic_close_button.xml +10 -0
- package/android/src/main/res/drawable/ic_video_pause_black.png +0 -0
- package/android/src/main/res/drawable/ic_video_play_black.png +0 -0
- package/android/src/main/res/drawable/ic_video_thumb_handle.png +0 -0
- package/android/src/main/res/drawable/icon_seek_bar.png +0 -0
- package/android/src/main/res/layout/video_player_view.xml +121 -0
- package/android/src/main/res/layout/video_thumb_item_layout.xml +16 -0
- package/android/src/main/res/layout/video_trimmer_view.xml +148 -0
- package/android/src/main/res/values/colors.xml +17 -0
- package/android/src/main/res/values/strings.xml +14 -0
- package/android/src/main/res/xml/imagepicker_provider_paths.xml +4 -0
- package/ios/CammeraPermission/RNCameraPermission.h +16 -0
- package/ios/CammeraPermission/RNCameraPermission.m +46 -0
- package/ios/DeviceInfo/DeviceUID.h +14 -0
- package/ios/DeviceInfo/DeviceUID.m +202 -0
- package/ios/DeviceInfo/EnvironmentUtil.h +41 -0
- package/ios/DeviceInfo/EnvironmentUtil.m +56 -0
- package/ios/DeviceInfo/RNDeviceInfo.h +22 -0
- package/ios/DeviceInfo/RNDeviceInfo.m +918 -0
- package/ios/GetLocals/ShakebugSDKRNLocalize.h +21 -0
- package/ios/GetLocals/ShakebugSDKRNLocalize.m +296 -0
- package/ios/GetLocation/SettingsUtil.h +16 -0
- package/ios/GetLocation/SettingsUtil.m +21 -0
- package/ios/GetLocation/ShakebugSDKLocationModule.h +17 -0
- package/ios/GetLocation/ShakebugSDKLocationModule.m +218 -0
- package/ios/ImageOrVideoPicker/ShakebugSDKImagePickerManager.h +40 -0
- package/ios/ImageOrVideoPicker/ShakebugSDKImagePickerManager.m +588 -0
- package/ios/ImageOrVideoPicker/ShakebugSDKImagePickerUtils.h +26 -0
- package/ios/ImageOrVideoPicker/ShakebugSDKImagePickerUtils.m +194 -0
- package/ios/MicrophonePermissionManager.h +14 -0
- package/ios/MicrophonePermissionManager.m +35 -0
- package/ios/NetInfo/RNCConnectionState.h +42 -0
- package/ios/NetInfo/RNCConnectionState.m +119 -0
- package/ios/NetInfo/RNCConnectionStateWatcher.h +31 -0
- package/ios/NetInfo/RNCConnectionStateWatcher.m +136 -0
- package/ios/NetInfo/RNCNetInfo.h +13 -0
- package/ios/NetInfo/RNCNetInfo.m +269 -0
- package/ios/RecordScreen/ShakebugSDKRecordScreen.h +31 -0
- package/ios/RecordScreen/ShakebugSDKRecordScreen.m +309 -0
- package/ios/ScreenShot/ShakebugSDKRNViewShot.h +6 -0
- package/ios/ScreenShot/ShakebugSDKRNViewShot.m +186 -0
- package/ios/ScreenshotDetector/ScreenShotDetector.h +12 -0
- package/ios/ScreenshotDetector/ScreenShotDetector.m +37 -0
- package/ios/Senors/RNSensorsAccelerometer.h +22 -0
- package/ios/Senors/RNSensorsAccelerometer.m +162 -0
- package/ios/Senors/RNSensorsBarometer.h +22 -0
- package/ios/Senors/RNSensorsBarometer.m +141 -0
- package/ios/Senors/RNSensorsGravity.h +22 -0
- package/ios/Senors/RNSensorsGravity.m +165 -0
- package/ios/Senors/RNSensorsGyroscope.h +22 -0
- package/ios/Senors/RNSensorsGyroscope.m +160 -0
- package/ios/Senors/RNSensorsMagnetometer.h +22 -0
- package/ios/Senors/RNSensorsMagnetometer.m +163 -0
- package/ios/Senors/RNSensorsOrientation.h +22 -0
- package/ios/Senors/RNSensorsOrientation.m +189 -0
- package/ios/Senors/RNSensorsUtils.h +7 -0
- package/ios/Senors/RNSensorsUtils.m +9 -0
- package/ios/Shakebug.h +7 -0
- package/ios/Shakebug.m +16 -0
- package/ios/Shakebug.xcodeproj/project.pbxproj +872 -0
- package/ios/Shakebug.xcodeproj/xcshareddata/xcschemes/Shakebug.xcscheme +66 -0
- package/ios/Shakebug.xcworkspace/contents.xcworkspacedata +10 -0
- package/ios/Shakebug.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/ios/SketchCanvas/DrawingView.h +18 -0
- package/ios/SketchCanvas/DrawingView.m +96 -0
- package/ios/SketchCanvas/DrawingViewManager.h +12 -0
- package/ios/SketchCanvas/DrawingViewManager.m +35 -0
- package/ios/Storage/SharedPreferencesModule.h +13 -0
- package/ios/Storage/SharedPreferencesModule.m +35 -0
- package/ios/Thumbnaill/VideoThumbnailManager.h +12 -0
- package/ios/Thumbnaill/VideoThumbnailManager.m +73 -0
- package/ios/TrimVideo/ShakebugSDKVideoTrim.swift +372 -0
- package/ios/TrimVideo/VideoTrim-Bridging-Header.h +10 -0
- package/ios/TrimVideo/VideoTrim.m +23 -0
- package/ios/TrimVideo/VideoTrimmer.swift +810 -0
- package/ios/TrimVideo/VideoTrimmerThumb.swift +119 -0
- package/ios/TrimVideo/VideoTrimmerViewController.swift +301 -0
- package/ios/VideoPlayer/VideoPlayerModule.h +14 -0
- package/ios/VideoPlayer/VideoPlayerModule.m +29 -0
- package/ios/VideoPlayer/VideoPlayerViewController.h +18 -0
- package/ios/VideoPlayer/VideoPlayerViewController.m +29 -0
- package/package.json +45 -0
- package/shakebug-react-native.podspec +50 -0
- package/src/APIs/AddIssue.js +70 -0
- package/src/APIs/EndSession.js +32 -0
- package/src/APIs/Event.js +39 -0
- package/src/APIs/MatchKey.js +40 -0
- package/src/APIs/StartSession.js +84 -0
- package/src/Assets/images/OpenSketch.png +0 -0
- package/src/Assets/images/Push.png +0 -0
- package/src/Assets/images/RemoveTextView.png +0 -0
- package/src/Assets/images/black.png +0 -0
- package/src/Assets/images/blue.png +0 -0
- package/src/Assets/images/borderdBlack.png +0 -0
- package/src/Assets/images/borderdBlue.png +0 -0
- package/src/Assets/images/borderdGreen.png +0 -0
- package/src/Assets/images/borderdRed.png +0 -0
- package/src/Assets/images/borderdYellow.png +0 -0
- package/src/Assets/images/clear.png +0 -0
- package/src/Assets/images/close.png +0 -0
- package/src/Assets/images/green.png +0 -0
- package/src/Assets/images/next.png +0 -0
- package/src/Assets/images/play.png +0 -0
- package/src/Assets/images/red.png +0 -0
- package/src/Assets/images/shake.png +0 -0
- package/src/Assets/images/shakebugLogo.png +0 -0
- package/src/Assets/images/stopButton.png +0 -0
- package/src/Assets/images/text_icon.png +0 -0
- package/src/Assets/images/yellow.png +0 -0
- package/src/Componanats/CustomAlert.js +80 -0
- package/src/Componanats/ErrorHandler.js +80 -0
- package/src/Componanats/GlobalStateContext.js +22 -0
- package/src/Componanats/KeyboardAvoidingWrapper.js +43 -0
- package/src/Componanats/NavigationContext.js +42 -0
- package/src/Componanats/ShakeFunction.js +562 -0
- package/src/Componanats/localization.js +482 -0
- package/src/Screens/AddDetailsScreen.js +462 -0
- package/src/Screens/FirstScreen.js +629 -0
- package/src/Screens/Shakebug.js +487 -0
- package/src/Screens/StrockView.js +20 -0
- package/src/Screens/TrimVideoScreen.js +81 -0
- package/src/Screens/TutorialScreen.js +36 -0
- package/src/index.tsx +117 -0
- package/trimVideo/src/index.tsx +141 -0
|
@@ -0,0 +1,588 @@
|
|
|
1
|
+
#import "ShakebugSDKImagePickerManager.h"
|
|
2
|
+
#import "ShakebugSDKImagePickerUtils.h"
|
|
3
|
+
#import <React/RCTConvert.h>
|
|
4
|
+
#import <AVFoundation/AVFoundation.h>
|
|
5
|
+
#import <Photos/Photos.h>
|
|
6
|
+
#import <PhotosUI/PhotosUI.h>
|
|
7
|
+
#import <MobileCoreServices/MobileCoreServices.h>
|
|
8
|
+
|
|
9
|
+
@interface ShakebugSDKImagePickerManager ()
|
|
10
|
+
|
|
11
|
+
@property (nonatomic, strong) RCTResponseSenderBlock callback;
|
|
12
|
+
@property (nonatomic, copy) NSDictionary *options;
|
|
13
|
+
|
|
14
|
+
@end
|
|
15
|
+
|
|
16
|
+
@interface ShakebugSDKImagePickerManager (UIImagePickerControllerDelegate) <UINavigationControllerDelegate, UIImagePickerControllerDelegate>
|
|
17
|
+
@end
|
|
18
|
+
|
|
19
|
+
@interface ShakebugSDKImagePickerManager (UIAdaptivePresentationControllerDelegate) <UIAdaptivePresentationControllerDelegate>
|
|
20
|
+
@end
|
|
21
|
+
|
|
22
|
+
#if __has_include(<PhotosUI/PHPicker.h>)
|
|
23
|
+
@interface ShakebugSDKImagePickerManager (PHPickerViewControllerDelegate) <PHPickerViewControllerDelegate>
|
|
24
|
+
@end
|
|
25
|
+
#endif
|
|
26
|
+
|
|
27
|
+
@implementation ShakebugSDKImagePickerManager
|
|
28
|
+
|
|
29
|
+
NSString *ShakebugSDKerrCameraUnavailable = @"camera_unavailable";
|
|
30
|
+
NSString *ShakebugSDKerrPermission = @"permission";
|
|
31
|
+
NSString *ShakebugSDKerrOthers = @"others";
|
|
32
|
+
RNImagePickerTarget ShakebugSDKtarget;
|
|
33
|
+
|
|
34
|
+
BOOL ShakebugSDKphotoSelected = NO;
|
|
35
|
+
|
|
36
|
+
RCT_EXPORT_MODULE(ShakebugSDKImagePicker)
|
|
37
|
+
|
|
38
|
+
RCT_EXPORT_METHOD(launchCamera:(NSDictionary *)options callback:(RCTResponseSenderBlock)callback)
|
|
39
|
+
{
|
|
40
|
+
ShakebugSDKtarget = camera;
|
|
41
|
+
ShakebugSDKphotoSelected = NO;
|
|
42
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
43
|
+
[self launchImagePicker:options callback:callback];
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
RCT_EXPORT_METHOD(launchImageLibrary:(NSDictionary *)options callback:(RCTResponseSenderBlock)callback)
|
|
48
|
+
{
|
|
49
|
+
ShakebugSDKtarget = library;
|
|
50
|
+
ShakebugSDKphotoSelected = NO;
|
|
51
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
52
|
+
[self launchImagePicker:options callback:callback];
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// We won't compile this code when we build for the old architecture.
|
|
57
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
58
|
+
|
|
59
|
+
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
|
60
|
+
(const facebook::react::ObjCTurboModule::InitParams &)params
|
|
61
|
+
{
|
|
62
|
+
return std::make_shared<facebook::react::NativeImagePickerSpecJSI>(params);
|
|
63
|
+
}
|
|
64
|
+
#endif
|
|
65
|
+
|
|
66
|
+
- (void)launchImagePicker:(NSDictionary *)options callback:(RCTResponseSenderBlock)callback
|
|
67
|
+
{
|
|
68
|
+
self.callback = callback;
|
|
69
|
+
|
|
70
|
+
if (ShakebugSDKtarget == camera && [ShakebugSDKImagePickerUtils isSimulator]) {
|
|
71
|
+
self.callback(@[@{@"errorCode": ShakebugSDKerrCameraUnavailable}]);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
self.options = options;
|
|
76
|
+
|
|
77
|
+
#if __has_include(<PhotosUI/PHPicker.h>)
|
|
78
|
+
if (@available(iOS 14, *)) {
|
|
79
|
+
if (ShakebugSDKtarget == library) {
|
|
80
|
+
PHPickerConfiguration *configuration = [ShakebugSDKImagePickerUtils makeConfigurationFromOptions:options target:ShakebugSDKtarget];
|
|
81
|
+
PHPickerViewController *picker = [[PHPickerViewController alloc] initWithConfiguration:configuration];
|
|
82
|
+
picker.delegate = self;
|
|
83
|
+
picker.modalPresentationStyle = [RCTConvert UIModalPresentationStyle:options[@"presentationStyle"]];
|
|
84
|
+
picker.presentationController.delegate = self;
|
|
85
|
+
|
|
86
|
+
if([self.options[@"includeExtra"] boolValue]) {
|
|
87
|
+
|
|
88
|
+
[self checkPhotosPermissions:^(BOOL granted) {
|
|
89
|
+
if (!granted) {
|
|
90
|
+
self.callback(@[@{@"errorCode": ShakebugSDKerrPermission}]);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
[self showPickerViewController:picker];
|
|
94
|
+
}];
|
|
95
|
+
} else {
|
|
96
|
+
[self showPickerViewController:picker];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
#endif
|
|
103
|
+
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
|
|
104
|
+
[ShakebugSDKImagePickerUtils setupPickerFromOptions:picker options:self.options target:ShakebugSDKtarget];
|
|
105
|
+
picker.delegate = self;
|
|
106
|
+
picker.presentationController.delegate = self;
|
|
107
|
+
|
|
108
|
+
if([self.options[@"includeExtra"] boolValue]) {
|
|
109
|
+
[self checkPhotosPermissions:^(BOOL granted) {
|
|
110
|
+
if (!granted) {
|
|
111
|
+
self.callback(@[@{@"errorCode": ShakebugSDKerrPermission}]);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
[self showPickerViewController:picker];
|
|
115
|
+
}];
|
|
116
|
+
} else {
|
|
117
|
+
[self showPickerViewController:picker];
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
- (void) showPickerViewController:(UIViewController *)picker
|
|
122
|
+
{
|
|
123
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
124
|
+
UIViewController *root = RCTPresentedViewController();
|
|
125
|
+
[root presentViewController:picker animated:YES completion:nil];
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
#pragma mark - Helpers
|
|
130
|
+
|
|
131
|
+
NSData* extractImageData(UIImage* image){
|
|
132
|
+
CFMutableDataRef imageData = CFDataCreateMutable(NULL, 0);
|
|
133
|
+
CGImageDestinationRef destination = CGImageDestinationCreateWithData(imageData, kUTTypeJPEG, 1, NULL);
|
|
134
|
+
|
|
135
|
+
CFStringRef orientationKey[1];
|
|
136
|
+
CFTypeRef orientationValue[1];
|
|
137
|
+
CGImagePropertyOrientation CGOrientation = CGImagePropertyOrientationForUIImageOrientation(image.imageOrientation);
|
|
138
|
+
|
|
139
|
+
orientationKey[0] = kCGImagePropertyOrientation;
|
|
140
|
+
orientationValue[0] = CFNumberCreate(NULL, kCFNumberIntType, &CGOrientation);
|
|
141
|
+
|
|
142
|
+
CFDictionaryRef imageProps = CFDictionaryCreate( NULL, (const void **)orientationKey, (const void **)orientationValue, 1,
|
|
143
|
+
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
|
|
144
|
+
|
|
145
|
+
CGImageDestinationAddImage(destination, image.CGImage, imageProps);
|
|
146
|
+
|
|
147
|
+
CGImageDestinationFinalize(destination);
|
|
148
|
+
|
|
149
|
+
CFRelease(destination);
|
|
150
|
+
CFRelease(orientationValue[0]);
|
|
151
|
+
CFRelease(imageProps);
|
|
152
|
+
return (__bridge NSData *)imageData;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
-(NSMutableDictionary *)mapImageToAsset:(UIImage *)image data:(NSData *)data phAsset:(PHAsset * _Nullable)phAsset {
|
|
158
|
+
NSString *fileType = [ShakebugSDKImagePickerUtils getFileType:data];
|
|
159
|
+
if (ShakebugSDKtarget == camera) {
|
|
160
|
+
if ([self.options[@"saveToPhotos"] boolValue]) {
|
|
161
|
+
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
|
|
162
|
+
}
|
|
163
|
+
data = extractImageData(image);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
UIImage* newImage = image;
|
|
167
|
+
if (![fileType isEqualToString:@"gif"]) {
|
|
168
|
+
newImage = [ShakebugSDKImagePickerUtils resizeImage:image
|
|
169
|
+
maxWidth:[self.options[@"maxWidth"] floatValue]
|
|
170
|
+
maxHeight:[self.options[@"maxHeight"] floatValue]];
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
float quality = [self.options[@"quality"] floatValue];
|
|
174
|
+
if (![image isEqual:newImage] || (quality >= 0 && quality < 1)) {
|
|
175
|
+
if ([fileType isEqualToString:@"jpg"]) {
|
|
176
|
+
data = UIImageJPEGRepresentation(newImage, quality);
|
|
177
|
+
} else if ([fileType isEqualToString:@"png"]) {
|
|
178
|
+
data = UIImagePNGRepresentation(newImage);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
NSMutableDictionary *asset = [[NSMutableDictionary alloc] init];
|
|
183
|
+
asset[@"type"] = [@"image/" stringByAppendingString:fileType];
|
|
184
|
+
|
|
185
|
+
NSString *fileName = [self getImageFileName:fileType];
|
|
186
|
+
NSString *path = [[NSTemporaryDirectory() stringByStandardizingPath] stringByAppendingPathComponent:fileName];
|
|
187
|
+
[data writeToFile:path atomically:YES];
|
|
188
|
+
|
|
189
|
+
if ([self.options[@"includeBase64"] boolValue]) {
|
|
190
|
+
asset[@"base64"] = [data base64EncodedStringWithOptions:0];
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
NSURL *fileURL = [NSURL fileURLWithPath:path];
|
|
194
|
+
asset[@"uri"] = [fileURL absoluteString];
|
|
195
|
+
|
|
196
|
+
NSNumber *fileSizeValue = nil;
|
|
197
|
+
NSError *fileSizeError = nil;
|
|
198
|
+
[fileURL getResourceValue:&fileSizeValue forKey:NSURLFileSizeKey error:&fileSizeError];
|
|
199
|
+
if (fileSizeValue){
|
|
200
|
+
asset[@"fileSize"] = fileSizeValue;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
asset[@"fileName"] = fileName;
|
|
204
|
+
asset[@"width"] = @(newImage.size.width);
|
|
205
|
+
asset[@"height"] = @(newImage.size.height);
|
|
206
|
+
|
|
207
|
+
if(phAsset){
|
|
208
|
+
asset[@"timestamp"] = [self getDateTimeInUTC:phAsset.creationDate];
|
|
209
|
+
asset[@"id"] = phAsset.localIdentifier;
|
|
210
|
+
// Add more extra data here ...
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return asset;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
CGImagePropertyOrientation CGImagePropertyOrientationForUIImageOrientation(UIImageOrientation uiOrientation) {
|
|
217
|
+
//code from here: https://developer.apple.com/documentation/imageio/cgimagepropertyorientation?language=objc
|
|
218
|
+
switch (uiOrientation) {
|
|
219
|
+
case UIImageOrientationUp: return kCGImagePropertyOrientationUp;
|
|
220
|
+
case UIImageOrientationDown: return kCGImagePropertyOrientationDown;
|
|
221
|
+
case UIImageOrientationLeft: return kCGImagePropertyOrientationLeft;
|
|
222
|
+
case UIImageOrientationRight: return kCGImagePropertyOrientationRight;
|
|
223
|
+
case UIImageOrientationUpMirrored: return kCGImagePropertyOrientationUpMirrored;
|
|
224
|
+
case UIImageOrientationDownMirrored: return kCGImagePropertyOrientationDownMirrored;
|
|
225
|
+
case UIImageOrientationLeftMirrored: return kCGImagePropertyOrientationLeftMirrored;
|
|
226
|
+
case UIImageOrientationRightMirrored: return kCGImagePropertyOrientationRightMirrored;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
-(NSMutableDictionary *)mapVideoToAsset:(NSURL *)url phAsset:(PHAsset * _Nullable)phAsset error:(NSError **)error {
|
|
231
|
+
NSString *fileName = [url lastPathComponent];
|
|
232
|
+
NSString *path = [[NSTemporaryDirectory() stringByStandardizingPath] stringByAppendingPathComponent:fileName];
|
|
233
|
+
NSURL *videoDestinationURL = [NSURL fileURLWithPath:path];
|
|
234
|
+
NSString *fileExtension = [fileName pathExtension];
|
|
235
|
+
|
|
236
|
+
if ((ShakebugSDKtarget == camera) && [self.options[@"saveToPhotos"] boolValue]) {
|
|
237
|
+
UISaveVideoAtPathToSavedPhotosAlbum(url.path, nil, nil, nil);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (![url.URLByResolvingSymlinksInPath.path isEqualToString:videoDestinationURL.URLByResolvingSymlinksInPath.path]) {
|
|
241
|
+
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
242
|
+
|
|
243
|
+
// Delete file if it already exists
|
|
244
|
+
if ([fileManager fileExistsAtPath:videoDestinationURL.path]) {
|
|
245
|
+
[fileManager removeItemAtURL:videoDestinationURL error:nil];
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (url) { // Protect against reported crash
|
|
249
|
+
|
|
250
|
+
// If we have write access to the source file, move it. Otherwise use copy.
|
|
251
|
+
if ([fileManager isWritableFileAtPath:[url path]]) {
|
|
252
|
+
[fileManager moveItemAtURL:url toURL:videoDestinationURL error:error];
|
|
253
|
+
} else {
|
|
254
|
+
[fileManager copyItemAtURL:url toURL:videoDestinationURL error:error];
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (error && *error) {
|
|
258
|
+
return nil;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
NSMutableDictionary *response = [[NSMutableDictionary alloc] init];
|
|
264
|
+
|
|
265
|
+
if([self.options[@"formatAsMp4"] boolValue] && ![fileExtension isEqualToString:@"mp4"]) {
|
|
266
|
+
NSURL *parentURL = [videoDestinationURL URLByDeletingLastPathComponent];
|
|
267
|
+
NSString *path = [[parentURL.path stringByAppendingString:@"/"] stringByAppendingString:[[NSUUID UUID] UUIDString]];
|
|
268
|
+
path = [path stringByAppendingString:@".mp4"];
|
|
269
|
+
NSURL *outputURL = [NSURL fileURLWithPath:path];
|
|
270
|
+
|
|
271
|
+
[[NSFileManager defaultManager] removeItemAtURL:outputURL error:nil];
|
|
272
|
+
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:videoDestinationURL options:nil];
|
|
273
|
+
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetPassthrough];
|
|
274
|
+
|
|
275
|
+
exportSession.outputURL = outputURL;
|
|
276
|
+
exportSession.outputFileType = AVFileTypeMPEG4;
|
|
277
|
+
exportSession.shouldOptimizeForNetworkUse = YES;
|
|
278
|
+
|
|
279
|
+
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
|
|
280
|
+
|
|
281
|
+
[exportSession exportAsynchronouslyWithCompletionHandler:^(void) {
|
|
282
|
+
if (exportSession.status == AVAssetExportSessionStatusCompleted) {
|
|
283
|
+
CGSize dimentions = [ShakebugSDKImagePickerUtils getVideoDimensionsFromUrl:outputURL];
|
|
284
|
+
response[@"fileName"] = [outputURL lastPathComponent];
|
|
285
|
+
response[@"duration"] = [NSNumber numberWithDouble:CMTimeGetSeconds([AVAsset assetWithURL:outputURL].duration)];
|
|
286
|
+
response[@"uri"] = outputURL.absoluteString;
|
|
287
|
+
response[@"type"] = [ShakebugSDKImagePickerUtils getFileTypeFromUrl:outputURL];
|
|
288
|
+
response[@"fileSize"] = [ShakebugSDKImagePickerUtils getFileSizeFromUrl:outputURL];
|
|
289
|
+
response[@"width"] = @(dimentions.width);
|
|
290
|
+
response[@"height"] = @(dimentions.height);
|
|
291
|
+
|
|
292
|
+
dispatch_semaphore_signal(sem);
|
|
293
|
+
} else if (exportSession.status == AVAssetExportSessionStatusFailed || exportSession.status == AVAssetExportSessionStatusCancelled) {
|
|
294
|
+
dispatch_semaphore_signal(sem);
|
|
295
|
+
}
|
|
296
|
+
}];
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
|
|
300
|
+
} else {
|
|
301
|
+
CGSize dimentions = [ShakebugSDKImagePickerUtils getVideoDimensionsFromUrl:videoDestinationURL];
|
|
302
|
+
response[@"fileName"] = fileName;
|
|
303
|
+
response[@"duration"] = [NSNumber numberWithDouble:CMTimeGetSeconds([AVAsset assetWithURL:videoDestinationURL].duration)];
|
|
304
|
+
response[@"uri"] = videoDestinationURL.absoluteString;
|
|
305
|
+
response[@"type"] = [ShakebugSDKImagePickerUtils getFileTypeFromUrl:videoDestinationURL];
|
|
306
|
+
response[@"fileSize"] = [ShakebugSDKImagePickerUtils getFileSizeFromUrl:videoDestinationURL];
|
|
307
|
+
response[@"width"] = @(dimentions.width);
|
|
308
|
+
response[@"height"] = @(dimentions.height);
|
|
309
|
+
|
|
310
|
+
if(phAsset){
|
|
311
|
+
response[@"timestamp"] = [self getDateTimeInUTC:phAsset.creationDate];
|
|
312
|
+
response[@"id"] = phAsset.localIdentifier;
|
|
313
|
+
// Add more extra data here ...
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
return response;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
- (NSString *) getDateTimeInUTC:(NSDate *)date {
|
|
321
|
+
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
|
|
322
|
+
[formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZ"];
|
|
323
|
+
return [formatter stringFromDate:date];
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
- (void)checkCameraPermissions:(void(^)(BOOL granted))callback
|
|
327
|
+
{
|
|
328
|
+
AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
|
|
329
|
+
if (status == AVAuthorizationStatusAuthorized) {
|
|
330
|
+
callback(YES);
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
else if (status == AVAuthorizationStatusNotDetermined){
|
|
334
|
+
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
|
|
335
|
+
callback(granted);
|
|
336
|
+
return;
|
|
337
|
+
}];
|
|
338
|
+
}
|
|
339
|
+
else {
|
|
340
|
+
callback(NO);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
- (void)checkPhotosPermissions:(void(^)(BOOL granted))callback
|
|
345
|
+
{
|
|
346
|
+
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
|
|
347
|
+
if (status == PHAuthorizationStatusAuthorized) {
|
|
348
|
+
callback(YES);
|
|
349
|
+
return;
|
|
350
|
+
} else if (status == PHAuthorizationStatusNotDetermined) {
|
|
351
|
+
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
|
|
352
|
+
if (status == PHAuthorizationStatusAuthorized) {
|
|
353
|
+
callback(YES);
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
else {
|
|
357
|
+
callback(NO);
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
}];
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
callback(NO);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// Both camera and photo write permission is required to take picture/video and store it to public photos
|
|
368
|
+
- (void)checkCameraAndPhotoPermission:(void(^)(BOOL granted))callback
|
|
369
|
+
{
|
|
370
|
+
[self checkCameraPermissions:^(BOOL cameraGranted) {
|
|
371
|
+
if (!cameraGranted) {
|
|
372
|
+
callback(NO);
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
[self checkPhotosPermissions:^(BOOL photoGranted) {
|
|
377
|
+
if (!photoGranted) {
|
|
378
|
+
callback(NO);
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
callback(YES);
|
|
382
|
+
}];
|
|
383
|
+
}];
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
- (void)checkPermission:(void(^)(BOOL granted)) callback
|
|
387
|
+
{
|
|
388
|
+
void (^permissionBlock)(BOOL) = ^(BOOL permissionGranted) {
|
|
389
|
+
if (!permissionGranted) {
|
|
390
|
+
callback(NO);
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
callback(YES);
|
|
394
|
+
};
|
|
395
|
+
|
|
396
|
+
if (ShakebugSDKtarget == camera && [self.options[@"saveToPhotos"] boolValue]) {
|
|
397
|
+
[self checkCameraAndPhotoPermission:permissionBlock];
|
|
398
|
+
}
|
|
399
|
+
else if (ShakebugSDKtarget == camera) {
|
|
400
|
+
[self checkCameraPermissions:permissionBlock];
|
|
401
|
+
}
|
|
402
|
+
else {
|
|
403
|
+
if (@available(iOS 11.0, *)) {
|
|
404
|
+
callback(YES);
|
|
405
|
+
}
|
|
406
|
+
else {
|
|
407
|
+
[self checkPhotosPermissions:permissionBlock];
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
- (NSString *)getImageFileName:(NSString *)fileType
|
|
413
|
+
{
|
|
414
|
+
NSString *fileName = [[NSUUID UUID] UUIDString];
|
|
415
|
+
fileName = [fileName stringByAppendingString:@"."];
|
|
416
|
+
return [fileName stringByAppendingString:fileType];
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
+ (UIImage *)getUIImageFromInfo:(NSDictionary *)info
|
|
420
|
+
{
|
|
421
|
+
UIImage *image = info[UIImagePickerControllerEditedImage];
|
|
422
|
+
if (!image) {
|
|
423
|
+
image = info[UIImagePickerControllerOriginalImage];
|
|
424
|
+
}
|
|
425
|
+
return image;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
+ (NSURL *)getNSURLFromInfo:(NSDictionary *)info {
|
|
429
|
+
if (@available(iOS 11.0, *)) {
|
|
430
|
+
return info[UIImagePickerControllerImageURL];
|
|
431
|
+
}
|
|
432
|
+
else {
|
|
433
|
+
return info[UIImagePickerControllerReferenceURL];
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
@end
|
|
438
|
+
|
|
439
|
+
@implementation ShakebugSDKImagePickerManager (UIImagePickerControllerDelegate)
|
|
440
|
+
|
|
441
|
+
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
|
|
442
|
+
{
|
|
443
|
+
dispatch_block_t dismissCompletionBlock = ^{
|
|
444
|
+
NSMutableArray<NSDictionary *> *assets = [[NSMutableArray alloc] initWithCapacity:1];
|
|
445
|
+
PHAsset *asset = nil;
|
|
446
|
+
|
|
447
|
+
if (ShakebugSDKphotoSelected == YES) {
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
ShakebugSDKphotoSelected = YES;
|
|
451
|
+
|
|
452
|
+
// If include extra, we fetch the PHAsset, this required library permissions
|
|
453
|
+
if([self.options[@"includeExtra"] boolValue]) {
|
|
454
|
+
asset = [ShakebugSDKImagePickerUtils fetchPHAssetOnIOS13:info];
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
if ([info[UIImagePickerControllerMediaType] isEqualToString:(NSString *) kUTTypeImage]) {
|
|
458
|
+
UIImage *image = [ShakebugSDKImagePickerManager getUIImageFromInfo:info];
|
|
459
|
+
|
|
460
|
+
[assets addObject:[self mapImageToAsset:image data:[NSData dataWithContentsOfURL:[ShakebugSDKImagePickerManager getNSURLFromInfo:info]] phAsset:asset]];
|
|
461
|
+
} else {
|
|
462
|
+
NSError *error;
|
|
463
|
+
NSDictionary *videoAsset = [self mapVideoToAsset:info[UIImagePickerControllerMediaURL] phAsset:asset error:&error];
|
|
464
|
+
|
|
465
|
+
if (videoAsset == nil) {
|
|
466
|
+
NSString *errorMessage = error.localizedFailureReason;
|
|
467
|
+
if (errorMessage == nil) errorMessage = @"Video asset not found";
|
|
468
|
+
self.callback(@[@{@"errorCode": ShakebugSDKerrOthers, @"errorMessage": errorMessage}]);
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
[assets addObject:videoAsset];
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
NSMutableDictionary *response = [[NSMutableDictionary alloc] init];
|
|
475
|
+
response[@"assets"] = assets;
|
|
476
|
+
self.callback(@[response]);
|
|
477
|
+
};
|
|
478
|
+
|
|
479
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
480
|
+
[picker dismissViewControllerAnimated:YES completion:dismissCompletionBlock];
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
|
|
485
|
+
{
|
|
486
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
487
|
+
[picker dismissViewControllerAnimated:YES completion:^{
|
|
488
|
+
self.callback(@[@{@"didCancel": @YES}]);
|
|
489
|
+
}];
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
@end
|
|
494
|
+
|
|
495
|
+
@implementation ShakebugSDKImagePickerManager (presentationControllerDidDismiss)
|
|
496
|
+
|
|
497
|
+
- (void)presentationControllerDidDismiss:(UIPresentationController *)presentationController
|
|
498
|
+
{
|
|
499
|
+
self.callback(@[@{@"didCancel": @YES}]);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
@end
|
|
503
|
+
|
|
504
|
+
#if __has_include(<PhotosUI/PHPicker.h>)
|
|
505
|
+
@implementation ShakebugSDKImagePickerManager (PHPickerViewControllerDelegate)
|
|
506
|
+
|
|
507
|
+
- (void)picker:(PHPickerViewController *)picker didFinishPicking:(NSArray<PHPickerResult *> *)results API_AVAILABLE(ios(14))
|
|
508
|
+
{
|
|
509
|
+
[picker dismissViewControllerAnimated:YES completion:nil];
|
|
510
|
+
|
|
511
|
+
if (ShakebugSDKphotoSelected == YES) {
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
ShakebugSDKphotoSelected = YES;
|
|
515
|
+
|
|
516
|
+
if (results.count == 0) {
|
|
517
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
518
|
+
self.callback(@[@{@"didCancel": @YES}]);
|
|
519
|
+
});
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
dispatch_group_t completionGroup = dispatch_group_create();
|
|
524
|
+
NSMutableArray<NSDictionary *> *assets = [[NSMutableArray alloc] initWithCapacity:results.count];
|
|
525
|
+
for (int i = 0; i < results.count; i++) {
|
|
526
|
+
[assets addObject:(NSDictionary *)[NSNull null]];
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
[results enumerateObjectsUsingBlock:^(PHPickerResult *result, NSUInteger index, BOOL *stop) {
|
|
530
|
+
PHAsset *asset = nil;
|
|
531
|
+
NSItemProvider *provider = result.itemProvider;
|
|
532
|
+
|
|
533
|
+
// If include extra, we fetch the PHAsset, this required library permissions
|
|
534
|
+
if([self.options[@"includeExtra"] boolValue] && result.assetIdentifier != nil) {
|
|
535
|
+
PHFetchResult* fetchResult = [PHAsset fetchAssetsWithLocalIdentifiers:@[result.assetIdentifier] options:nil];
|
|
536
|
+
asset = fetchResult.firstObject;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
dispatch_group_enter(completionGroup);
|
|
540
|
+
|
|
541
|
+
if ([provider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeImage]) {
|
|
542
|
+
NSString *identifier = provider.registeredTypeIdentifiers.firstObject;
|
|
543
|
+
// Matches both com.apple.live-photo-bundle and com.apple.private.live-photo-bundle
|
|
544
|
+
if ([identifier containsString:@"live-photo-bundle"]) {
|
|
545
|
+
// Handle live photos
|
|
546
|
+
identifier = @"public.jpeg";
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
[provider loadFileRepresentationForTypeIdentifier:identifier completionHandler:^(NSURL * _Nullable url, NSError * _Nullable error) {
|
|
550
|
+
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
|
|
551
|
+
UIImage *image = [[UIImage alloc] initWithData:data];
|
|
552
|
+
|
|
553
|
+
assets[index] = [self mapImageToAsset:image data:data phAsset:asset];
|
|
554
|
+
dispatch_group_leave(completionGroup);
|
|
555
|
+
}];
|
|
556
|
+
} else if ([provider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeMovie]) {
|
|
557
|
+
[provider loadFileRepresentationForTypeIdentifier:(NSString *)kUTTypeMovie completionHandler:^(NSURL * _Nullable url, NSError * _Nullable error) {
|
|
558
|
+
NSDictionary *mappedAsset = [self mapVideoToAsset:url phAsset:asset error:nil];
|
|
559
|
+
if (nil != mappedAsset) {
|
|
560
|
+
assets[index] = mappedAsset;
|
|
561
|
+
}
|
|
562
|
+
dispatch_group_leave(completionGroup);
|
|
563
|
+
}];
|
|
564
|
+
} else {
|
|
565
|
+
// The provider didn't have an item matching photo or video (fails on M1 Mac Simulator)
|
|
566
|
+
dispatch_group_leave(completionGroup);
|
|
567
|
+
}
|
|
568
|
+
}];
|
|
569
|
+
|
|
570
|
+
dispatch_group_notify(completionGroup, dispatch_get_main_queue(), ^{
|
|
571
|
+
// mapVideoToAsset can fail and return nil, leaving asset NSNull.
|
|
572
|
+
for (NSDictionary *asset in assets) {
|
|
573
|
+
if ([asset isEqual:[NSNull null]]) {
|
|
574
|
+
self.callback(@[@{@"errorCode": ShakebugSDKerrOthers}]);
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
NSMutableDictionary *response = [[NSMutableDictionary alloc] init];
|
|
580
|
+
[response setObject:assets forKey:@"assets"];
|
|
581
|
+
|
|
582
|
+
self.callback(@[response]);
|
|
583
|
+
});
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
@end
|
|
587
|
+
|
|
588
|
+
#endif
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#import "ShakebugSDKImagePickerManager.h"
|
|
2
|
+
#import <Photos/Photos.h>
|
|
3
|
+
|
|
4
|
+
@class PHPickerConfiguration;
|
|
5
|
+
|
|
6
|
+
@interface ShakebugSDKImagePickerUtils : NSObject
|
|
7
|
+
|
|
8
|
+
+ (BOOL)isSimulator;
|
|
9
|
+
|
|
10
|
+
+ (void)setupPickerFromOptions:(UIImagePickerController *)picker options:(NSDictionary *)options target:(RNImagePickerTarget)target;
|
|
11
|
+
|
|
12
|
+
+ (PHPickerConfiguration *)makeConfigurationFromOptions:(NSDictionary *)options target:(RNImagePickerTarget)target API_AVAILABLE(ios(14));
|
|
13
|
+
|
|
14
|
+
+ (NSString*)getFileType:(NSData*)imageData;
|
|
15
|
+
|
|
16
|
+
+ (UIImage*)resizeImage:(UIImage*)image maxWidth:(float)maxWidth maxHeight:(float)maxHeight;
|
|
17
|
+
|
|
18
|
+
+ (CGSize)getVideoDimensionsFromUrl:(NSURL *)url;
|
|
19
|
+
|
|
20
|
+
+ (NSString *) getFileTypeFromUrl:(NSURL *)url;
|
|
21
|
+
|
|
22
|
+
+ (NSString *) getFileSizeFromUrl:(NSURL *)url;
|
|
23
|
+
|
|
24
|
+
+ (PHAsset *)fetchPHAssetOnIOS13:(NSDictionary<NSString *,id> *)info;
|
|
25
|
+
|
|
26
|
+
@end
|