OPS: Use new Image Picker

This commit is contained in:
marcosrdz 2020-12-10 12:40:14 -05:00
parent fcd61c35b2
commit 5b30f2f3ea
12 changed files with 30 additions and 653 deletions

View File

@ -33,7 +33,7 @@ import * as NavigationService from './NavigationService';
import WalletGradient from './class/wallet-gradient';
import ToolTip from 'react-native-tooltip';
import { BlurView } from '@react-native-community/blur';
import ImagePicker from 'react-native-image-picker';
import { launchCamera, launchImageLibrary } from 'react-native-image-picker';
import showPopupMenu from 'react-native-popup-menu-android';
import NetworkTransactionFees, { NetworkTransactionFee, NetworkTransactionFeeType } from './models/networkTransactionFees';
import Biometric from './class/biometrics';
@ -1616,7 +1616,7 @@ export class BlueAddressInput extends Component {
};
choosePhoto = () => {
ImagePicker.launchImageLibrary(
launchImageLibrary(
{
title: null,
mediaType: 'photo',
@ -1638,7 +1638,7 @@ export class BlueAddressInput extends Component {
};
takePhoto = () => {
ImagePicker.launchCamera(
launchCamera(
{
title: null,
mediaType: 'photo',

View File

@ -265,8 +265,8 @@ PODS:
- React
- react-native-geolocation (2.0.2):
- React
- react-native-image-picker (2.3.4):
- React-Core
- react-native-image-picker (3.0.1):
- React
- react-native-is-catalyst (1.0.0):
- React
- react-native-randombytes (3.5.3):
@ -278,7 +278,7 @@ PODS:
- react-native-tcp-socket (3.7.1):
- CocoaAsyncSocket
- React
- react-native-webview (10.10.0):
- react-native-webview (11.0.0):
- React-Core
- react-native-widget-center (0.0.4):
- React
@ -359,7 +359,7 @@ PODS:
- React-Core
- RNDefaultPreference (1.4.3):
- React
- RNDeviceInfo (6.2.0):
- RNDeviceInfo (7.0.2):
- React-Core
- RNFS (2.16.6):
- React
@ -703,13 +703,13 @@ SPEC CHECKSUMS:
react-native-document-picker: c5752781fbc0c126c627c1549b037c139444a4cf
react-native-fingerprint-scanner: c68136ca57e3704d7bdf5faa554ea535ce15b1d0
react-native-geolocation: cbd9d6bd06bac411eed2671810f454d4908484a8
react-native-image-picker: 32d1ad2c0024ca36161ae0d5c2117e2d6c441f11
react-native-image-picker: 4efc5b7f3a780975bcc677335eb670e52d203424
react-native-is-catalyst: 52ee70e0123c82419dd4ce47dc4cc94b22467512
react-native-randombytes: 991545e6eaaf700b4ee384c291ef3d572e0b2ca8
react-native-safe-area-context: 01158a92c300895d79dee447e980672dc3fb85a6
react-native-slider: b733e17fdd31186707146debf1f04b5d94aa1a93
react-native-tcp-socket: 96a4f104cdcc9c6621aafe92937f163d88447c5b
react-native-webview: 2e330b109bfd610e9818bf7865d1979f898960a7
react-native-webview: f0da708d7e471b60ebdbf861c114d2c5d7f7af2d
react-native-widget-center: 0f81d17beb163e7fb5848b06754d7d277fe7d99a
React-RCTActionSheet: 53ea72699698b0b47a6421cb1c8b4ab215a774aa
React-RCTAnimation: 1befece0b5183c22ae01b966f5583f42e69a83c2
@ -729,7 +729,7 @@ SPEC CHECKSUMS:
RNCMaskedView: f5c7d14d6847b7b44853f7acb6284c1da30a3459
RNCPushNotificationIOS: eaf01f848a0b872b194d31bcad94bb864299e01e
RNDefaultPreference: 21816c0a6f61a2829ccc0cef034392e9b509ee5f
RNDeviceInfo: 980848feea8d74412b16f2e3e8758c8294d63ca2
RNDeviceInfo: a37a15a98822c31c3982cb28eba6d336ba4d0968
RNFS: 2bd9eb49dc82fa9676382f0585b992c424cd59df
RNGestureHandler: 7a5833d0f788dbd107fbb913e09aa0c1ff333c39
RNHandoff: d3b0754cca3a6bcd9b25f544f733f7f033ccf5fa

6
package-lock.json generated
View File

@ -18996,9 +18996,9 @@
"integrity": "sha512-KTIy7lExwMtB6pOpCARyUzFj5EzYTh+A1GN/FB5Eb0LrW5C6hbb1kdj9K2/RHyZC+wyAJD1M823ZaDCU6n6cLA=="
},
"react-native-image-picker": {
"version": "2.3.4",
"resolved": "https://registry.npmjs.org/react-native-image-picker/-/react-native-image-picker-2.3.4.tgz",
"integrity": "sha512-4UHu+zOyDT570r5mIbjH6h1iMrKIq/qfsKiAVUEZwncVegh0usJiEYNyJw4CEVwNeehmye/ia5sLDsa+kzIE4g=="
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/react-native-image-picker/-/react-native-image-picker-3.0.1.tgz",
"integrity": "sha512-jVWiKT24jxr7K8dAixlsfHURZd+eDA4WWYeZhhKeJDGITCtFPphcTuFomTMtaWYE/gJgNTEL8TiLedcfeqJ9qw=="
},
"react-native-inappbrowser-reborn": {
"version": "git+https://github.com/BlueWallet/react-native-inappbrowser.git#fa2d8e1763e46dd12a7e53081e97a0f908049103",

View File

@ -129,7 +129,7 @@
"react-native-gesture-handler": "1.8.0",
"react-native-handoff": "git+https://github.com/marcosrdz/react-native-handoff.git",
"react-native-haptic-feedback": "1.11.0",
"react-native-image-picker": "2.3.4",
"react-native-image-picker": "3.0.1",
"react-native-inappbrowser-reborn": "git+https://github.com/BlueWallet/react-native-inappbrowser.git#fa2d8e1763e46dd12a7e53081e97a0f908049103",
"react-native-is-catalyst": "git+https://github.com/BlueWallet/react-native-is-catalyst.git#v1.0.0",
"react-native-level-fs": "3.0.1",

View File

@ -3,7 +3,7 @@ import React, { useState } from 'react';
import { Image, View, TouchableOpacity, StatusBar, Platform, StyleSheet, TextInput } from 'react-native';
import { RNCamera } from 'react-native-camera';
import { Icon } from 'react-native-elements';
import ImagePicker from 'react-native-image-picker';
import { launchImageLibrary } from 'react-native-image-picker';
import { decodeUR, extractSingleWorkload } from 'bc-ur';
import { useNavigation, useRoute, useIsFocused, useTheme } from '@react-navigation/native';
import loc from '../../loc';
@ -192,7 +192,7 @@ const ScanQRCode = () => {
const showImagePicker = () => {
if (!isLoading) {
setIsLoading(true);
ImagePicker.launchImageLibrary(
launchImageLibrary(
{
title: null,
mediaType: 'photo',

View File

@ -6,7 +6,7 @@ import { DynamicQRCode } from '../../components/DynamicQRCode';
import { SquareButton } from '../../components/SquareButton';
import { getSystemName } from 'react-native-device-info';
import loc from '../../loc';
import ImagePicker from 'react-native-image-picker';
import { launchCamera } from 'react-native-image-picker';
import ScanQRCode from './ScanQRCode';
import { useNavigation, useRoute, useTheme } from '@react-navigation/native';
const bitcoin = require('bitcoinjs-lib');
@ -49,7 +49,7 @@ const PsbtMultisigQRCode = () => {
const openScanner = () => {
if (isDesktop) {
ImagePicker.launchCamera(
launchCamera(
{
title: null,
mediaType: 'photo',

View File

@ -17,7 +17,7 @@ import { useNavigation, useRoute, useTheme } from '@react-navigation/native';
import WalletImport from '../../class/wallet-import';
import Clipboard from '@react-native-community/clipboard';
import ActionSheet from '../ActionSheet';
import ImagePicker from 'react-native-image-picker';
import { launchCamera, launchImageLibrary } from 'react-native-image-picker';
import loc from '../../loc';
import { getSystemName } from 'react-native-device-info';
import RNFS from 'react-native-fs';
@ -115,7 +115,7 @@ const WalletsImport = () => {
};
const choosePhoto = () => {
ImagePicker.launchImageLibrary(
launchImageLibrary(
{
title: null,
mediaType: 'photo',
@ -137,7 +137,7 @@ const WalletsImport = () => {
};
const takePhoto = () => {
ImagePicker.launchCamera(
launchCamera(
{
title: null,
mediaType: 'photo',

View File

@ -21,7 +21,7 @@ import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import { PlaceholderWallet } from '../../class';
import WalletImport from '../../class/wallet-import';
import ActionSheet from '../ActionSheet';
import ImagePicker from 'react-native-image-picker';
import { launchImageLibrary, launchCamera } from 'react-native-image-picker';
import Clipboard from '@react-native-community/clipboard';
import loc from '../../loc';
import { FContainer, FButton } from '../../components/FloatButtons';
@ -363,7 +363,7 @@ const WalletsList = () => {
};
const choosePhoto = () => {
ImagePicker.launchImageLibrary(
launchImageLibrary(
{
title: null,
mediaType: 'photo',
@ -385,7 +385,7 @@ const WalletsList = () => {
};
const takePhoto = () => {
ImagePicker.launchCamera(
launchCamera(
{
title: null,
mediaType: 'photo',

View File

@ -18,7 +18,7 @@ import {
TouchableOpacity,
View,
} from 'react-native';
import ImagePicker from 'react-native-image-picker';
import { launchImageLibrary } from 'react-native-image-picker';
import Clipboard from '@react-native-community/clipboard';
import { Icon } from 'react-native-elements';
import Handoff from 'react-native-handoff';
@ -451,7 +451,7 @@ const WalletTransactions = () => {
};
const choosePhoto = () => {
ImagePicker.launchImageLibrary(
launchImageLibrary(
{
title: null,
mediaType: 'photo',

View File

@ -18,7 +18,7 @@ import { Icon } from 'react-native-elements';
import { useFocusEffect, useNavigation, useRoute, useTheme } from '@react-navigation/native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { getSystemName } from 'react-native-device-info';
import ImagePicker from 'react-native-image-picker';
import { launchCamera } from 'react-native-image-picker';
import {
BlueButton,
@ -382,7 +382,7 @@ const ViewEditMultisigCosigners = () => {
const scanOrOpenFile = () => {
setIsProvideMnemonicsModalVisible(false);
if (isDesktop) {
ImagePicker.launchCamera(
launchCamera(
{
title: null,
mediaType: 'photo',

View File

@ -1,619 +0,0 @@
--- ImagePickerManager.m 1985-10-26 04:15:00.000000000 -0400
+++ ImagePickerManager.m 2020-11-15 21:01:40.000000000 -0500
@@ -1,9 +1,11 @@
#import "ImagePickerManager.h"
#import <React/RCTConvert.h>
-#import <AssetsLibrary/AssetsLibrary.h>
#import <AVFoundation/AVFoundation.h>
#import <Photos/Photos.h>
#import <React/RCTUtils.h>
+#if !TARGET_OS_MACCATALYST
+#import <AssetsLibrary/AssetsLibrary.h>
+#endif
@import MobileCoreServices;
@@ -42,25 +44,25 @@
{
self.callback = callback; // Save the callback so we can use it from the delegate methods
self.options = options;
-
+
dispatch_async(dispatch_get_main_queue(), ^{
-
+
NSString *title = [self.options valueForKey:@"title"];
if ([title isEqual:[NSNull null]] || title.length == 0) {
title = nil; // A more visually appealing UIAlertControl is displayed with a nil title rather than title = @""
}
NSString *cancelTitle = [self.options valueForKey:@"cancelButtonTitle"];
NSString *takePhotoButtonTitle = [self.options valueForKey:@"takePhotoButtonTitle"];
- NSString *chooseFromLibraryButtonTitle = [self.options valueForKey:@"chooseFromLibraryButtonTitle"];
-
+ NSString *chooseFromLibraryButtonTitle = [self.options valueForKey:@"chooseFromLibraryButtonTitle"];
+
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:nil preferredStyle:UIAlertControllerStyleActionSheet];
alertController.view.tintColor = [RCTConvert UIColor:options[@"tintColor"]];
-
+
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:cancelTitle style:UIAlertActionStyleCancel handler:^(UIAlertAction * action) {
self.callback(@[@{@"didCancel": @YES}]); // Return callback for 'cancel' action (if is required)
}];
[alertController addAction:cancelAction];
-
+
if (![takePhotoButtonTitle isEqual:[NSNull null]] && takePhotoButtonTitle.length > 0) {
UIAlertAction *takePhotoAction = [UIAlertAction actionWithTitle:takePhotoButtonTitle style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
[self actionHandler:action];
@@ -73,7 +75,7 @@
}];
[alertController addAction:chooseFromLibraryAction];
}
-
+
// Add custom buttons to action sheet
if ([self.options objectForKey:@"customButtons"] && [[self.options objectForKey:@"customButtons"] isKindOfClass:[NSArray class]]) {
self.customButtons = [self.options objectForKey:@"customButtons"];
@@ -85,16 +87,16 @@
[alertController addAction:customAction];
}
}
-
+
UIViewController *root = RCTPresentedViewController();
-
+
/* On iPad, UIAlertController presents a popover view rather than an action sheet like on iPhone. We must provide the location
- of the location to show the popover in this case. For simplicity, we'll just display it on the bottom center of the screen
- to mimic an action sheet */
+ of the location to show the popover in this case. For simplicity, we'll just display it on the bottom center of the screen
+ to mimic an action sheet */
alertController.popoverPresentationController.sourceView = root.view;
alertController.popoverPresentationController.sourceRect = CGRectMake(root.view.bounds.size.width / 2.0, root.view.bounds.size.height, 1.0, 1.0);
-
- if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
+
+ if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
alertController.popoverPresentationController.permittedArrowDirections = 0;
for (id subview in alertController.view.subviews) {
if ([subview isMemberOfClass:[UIView class]]) {
@@ -102,7 +104,7 @@
}
}
}
-
+
[root presentViewController:alertController animated:YES completion:nil];
});
}
@@ -119,7 +121,7 @@
return;
}
}
-
+
if ([action.title isEqualToString:[self.options valueForKey:@"takePhotoButtonTitle"]]) { // Take photo
[self launchImagePicker:RNImagePickerTargetCamera];
}
@@ -137,7 +139,7 @@
- (void)launchImagePicker:(RNImagePickerTarget)target
{
self.picker = [[UIImagePickerController alloc] init];
-
+
if (target == RNImagePickerTargetCamera) {
#if TARGET_IPHONE_SIMULATOR
self.callback(@[@{@"error": @"Camera not available on simulator"}]);
@@ -155,10 +157,10 @@
else { // RNImagePickerTargetLibrarySingleImage
self.picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
-
+
if ([[self.options objectForKey:@"mediaType"] isEqualToString:@"video"]
|| [[self.options objectForKey:@"mediaType"] isEqualToString:@"mixed"]) {
-
+
if ([[self.options objectForKey:@"videoQuality"] isEqualToString:@"high"]) {
self.picker.videoQuality = UIImagePickerControllerQualityTypeHigh;
}
@@ -168,7 +170,7 @@
else {
self.picker.videoQuality = UIImagePickerControllerQualityTypeMedium;
}
-
+
id durationLimit = [self.options objectForKey:@"durationLimit"];
if (durationLimit) {
self.picker.videoMaximumDuration = [durationLimit doubleValue];
@@ -182,13 +184,13 @@
} else {
self.picker.mediaTypes = @[(NSString *)kUTTypeImage];
}
-
+
if ([[self.options objectForKey:@"allowsEditing"] boolValue]) {
self.picker.allowsEditing = true;
}
self.picker.modalPresentationStyle = UIModalPresentationCurrentContext;
self.picker.delegate = self;
-
+
// Check permissions
void (^showPickerViewController)() = ^void() {
dispatch_async(dispatch_get_main_queue(), ^{
@@ -196,57 +198,57 @@
[root presentViewController:self.picker animated:YES completion:nil];
});
};
-
+
if (target == RNImagePickerTargetCamera) {
[self checkCameraPermissions:^(BOOL granted) {
if (!granted) {
self.callback(@[@{@"error": @"Camera permissions not granted"}]);
return;
}
-
+
showPickerViewController();
}];
}
else { // RNImagePickerTargetLibrarySingleImage
- if (@available(iOS 11.0, *)) {
- showPickerViewController();
- } else {
- [self checkPhotosPermissions:^(BOOL granted) {
- if (!granted) {
- self.callback(@[@{@"error": @"Photo library permissions not granted"}]);
- return;
- }
-
- showPickerViewController();
- }];
- }
+ if (@available(iOS 11.0, *)) {
+ showPickerViewController();
+ } else {
+ [self checkPhotosPermissions:^(BOOL granted) {
+ if (!granted) {
+ self.callback(@[@{@"error": @"Photo library permissions not granted"}]);
+ return;
+ }
+
+ showPickerViewController();
+ }];
+ }
}
}
- (NSString * _Nullable)originalFilenameForAsset:(PHAsset * _Nullable)asset assetType:(PHAssetResourceType)type {
if (!asset) { return nil; }
-
+
PHAssetResource *originalResource;
// Get the underlying resources for the PHAsset (PhotoKit)
NSArray<PHAssetResource *> *pickedAssetResources = [PHAssetResource assetResourcesForAsset:asset];
-
+
// Find the original resource (underlying image) for the asset, which has the desired filename
for (PHAssetResource *resource in pickedAssetResources) {
if (resource.type == type) {
originalResource = resource;
}
}
-
+
return originalResource.originalFilename;
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
{
dispatch_block_t dismissCompletionBlock = ^{
-
- NSURL *imageURL = [info valueForKey:UIImagePickerControllerReferenceURL];
+
+ NSURL *imageURL = [info valueForKey:UIImagePickerControllerPHAsset];
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
-
+
NSString *fileName;
if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
NSString *tempFileName = [[NSUUID UUID] UUIDString];
@@ -264,18 +266,18 @@
NSURL *videoURL = info[UIImagePickerControllerMediaURL];
fileName = videoURL.lastPathComponent;
}
-
+
// We default to path to the temporary directory
NSString *path = [[NSTemporaryDirectory()stringByStandardizingPath] stringByAppendingPathComponent:fileName];
-
+
// If storage options are provided, we use the documents directory which is persisted
if ([self.options objectForKey:@"storageOptions"] && [[self.options objectForKey:@"storageOptions"] isKindOfClass:[NSDictionary class]]) {
NSDictionary *storageOptions = [self.options objectForKey:@"storageOptions"];
-
+
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
path = [documentsDirectory stringByAppendingPathComponent:fileName];
-
+
// Creates documents subdirectory, if provided
if ([storageOptions objectForKey:@"path"]) {
NSString *newPath = [documentsDirectory stringByAppendingPathComponent:[storageOptions objectForKey:@"path"]];
@@ -291,10 +293,10 @@
}
}
}
-
+
// Create the response object
self.response = [[NSMutableDictionary alloc] init];
-
+
if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) { // PHOTOS
UIImage *originalImage;
if ([[self.options objectForKey:@"allowsEditing"] boolValue]) {
@@ -303,13 +305,15 @@
else {
originalImage = [info objectForKey:UIImagePickerControllerOriginalImage];
}
-
+
if (imageURL) {
PHAsset *pickedAsset;
if (@available(iOS 11.0, *)) {
- pickedAsset = [info objectForKey: UIImagePickerControllerPHAsset];
+ pickedAsset = [info objectForKey: UIImagePickerControllerPHAsset];
} else {
- pickedAsset = [PHAsset fetchAssetsWithALAssetURLs:@[imageURL] options:nil].lastObject;
+#if !TARGET_OS_MACCATALYST
+ pickedAsset = [PHAsset fetchAssetsWithALAssetURLs:@[imageURL] options:nil].lastObject;
+#endif
}
NSString *originalFilename = [self originalFilenameForAsset:pickedAsset assetType:PHAssetResourceTypePhoto];
@@ -322,9 +326,10 @@
self.response[@"timestamp"] = [[ImagePickerManager ISO8601DateFormatter] stringFromDate:pickedAsset.creationDate];
}
}
-
+
// GIFs break when resized, so we handle them differently
if (imageURL && [[imageURL absoluteString] rangeOfString:@"ext=GIF"].location != NSNotFound) {
+#if !TARGET_OS_MACCATALYST
ALAssetsLibrary* assetsLibrary = [[ALAssetsLibrary alloc] init];
[assetsLibrary assetForURL:imageURL resultBlock:^(ALAsset *asset) {
ALAssetRepresentation *rep = [asset defaultRepresentation];
@@ -333,38 +338,39 @@
NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:repSize error:nil];
NSData *data = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];
[data writeToFile:path atomically:YES];
-
+
NSMutableDictionary *gifResponse = [[NSMutableDictionary alloc] init];
[gifResponse setObject:@(originalImage.size.width) forKey:@"width"];
[gifResponse setObject:@(originalImage.size.height) forKey:@"height"];
-
+
BOOL vertical = (originalImage.size.width < originalImage.size.height) ? YES : NO;
[gifResponse setObject:@(vertical) forKey:@"isVertical"];
-
+
if (![[self.options objectForKey:@"noData"] boolValue]) {
NSString *dataString = [data base64EncodedStringWithOptions:0];
[gifResponse setObject:dataString forKey:@"data"];
}
-
+
NSURL *fileURL = [NSURL fileURLWithPath:path];
[gifResponse setObject:[fileURL absoluteString] forKey:@"uri"];
-
+
NSNumber *fileSizeValue = nil;
NSError *fileSizeError = nil;
[fileURL getResourceValue:&fileSizeValue forKey:NSURLFileSizeKey error:&fileSizeError];
if (fileSizeValue){
[gifResponse setObject:fileSizeValue forKey:@"fileSize"];
}
-
+
self.callback(@[gifResponse]);
} failureBlock:^(NSError *error) {
self.callback(@[@{@"error": error.localizedFailureReason}]);
}];
+#endif
return;
}
-
+
UIImage *editedImage = [self fixOrientation:originalImage]; // Rotate the image for upload to web
-
+
// If needed, downscale image
float maxWidth = editedImage.size.width;
float maxHeight = editedImage.size.height;
@@ -375,7 +381,7 @@
maxHeight = [[self.options valueForKey:@"maxHeight"] floatValue];
}
editedImage = [self downscaleImageIfNecessary:editedImage maxWidth:maxWidth maxHeight:maxHeight];
-
+
NSData *data;
NSString *mimeType;
if ([[self.options objectForKey:@"imageFileType"] isEqualToString:@"png"]) {
@@ -388,36 +394,37 @@
}
[self.response setObject:mimeType forKey:@"type"];
[data writeToFile:path atomically:YES];
-
+
if (![[self.options objectForKey:@"noData"] boolValue]) {
NSString *dataString = [data base64EncodedStringWithOptions:0]; // base64 encoded image string
[self.response setObject:dataString forKey:@"data"];
}
-
+
BOOL vertical = (editedImage.size.width < editedImage.size.height) ? YES : NO;
[self.response setObject:@(vertical) forKey:@"isVertical"];
NSURL *fileURL = [NSURL fileURLWithPath:path];
NSString *filePath = [fileURL absoluteString];
[self.response setObject:filePath forKey:@"uri"];
-
+
// add ref to the original image
NSString *origURL = [imageURL absoluteString];
if (origURL) {
- [self.response setObject:origURL forKey:@"origURL"];
+ [self.response setObject:origURL forKey:@"origURL"];
}
-
+
NSNumber *fileSizeValue = nil;
NSError *fileSizeError = nil;
[fileURL getResourceValue:&fileSizeValue forKey:NSURLFileSizeKey error:&fileSizeError];
if (fileSizeValue){
[self.response setObject:fileSizeValue forKey:@"fileSize"];
}
-
+
[self.response setObject:@(editedImage.size.width) forKey:@"width"];
[self.response setObject:@(editedImage.size.height) forKey:@"height"];
-
+
NSDictionary *storageOptions = [self.options objectForKey:@"storageOptions"];
if (storageOptions && [[storageOptions objectForKey:@"cameraRoll"] boolValue] == YES && self.picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
+#if !TARGET_OS_MACCATALYST
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
if ([[storageOptions objectForKey:@"waitUntilSaved"] boolValue]) {
[library writeImageToSavedPhotosAlbum:originalImage.CGImage metadata:[info valueForKey:UIImagePickerControllerMediaMetadata] completionBlock:^(NSURL *assetURL, NSError *error) {
@@ -440,13 +447,15 @@
} else {
[library writeImageToSavedPhotosAlbum:originalImage.CGImage metadata:[info valueForKey:UIImagePickerControllerMediaMetadata] completionBlock:nil];
}
+#endif
}
}
else { // VIDEO
- NSURL *videoRefURL = info[UIImagePickerControllerReferenceURL];
+ NSURL *videoRefURL = info[UIImagePickerControllerPHAsset];
NSURL *videoURL = info[UIImagePickerControllerMediaURL];
NSURL *videoDestinationURL = [NSURL fileURLWithPath:path];
-
+
+#if !TARGET_OS_MACCATALYST
if (videoRefURL) {
PHAsset *pickedAsset = [PHAsset fetchAssetsWithALAssetURLs:@[videoRefURL] options:nil].lastObject;
NSString *originalFilename = [self originalFilenameForAsset:pickedAsset assetType:PHAssetResourceTypeVideo];
@@ -459,39 +468,41 @@
self.response[@"timestamp"] = [[ImagePickerManager ISO8601DateFormatter] stringFromDate:pickedAsset.creationDate];
}
}
-
+#endif
+
if ([videoURL.URLByResolvingSymlinksInPath.path isEqualToString:videoDestinationURL.URLByResolvingSymlinksInPath.path] == NO) {
NSFileManager *fileManager = [NSFileManager defaultManager];
-
+
// Delete file if it already exists
if ([fileManager fileExistsAtPath:videoDestinationURL.path]) {
[fileManager removeItemAtURL:videoDestinationURL error:nil];
}
-
+
if (videoURL) { // Protect against reported crash
- NSError *error = nil;
-
- // If we have write access to the source file, move it. Otherwise use copy.
- if ([fileManager isWritableFileAtPath:[videoURL path]]) {
- [fileManager moveItemAtURL:videoURL toURL:videoDestinationURL error:&error];
- } else {
- [fileManager copyItemAtURL:videoURL toURL:videoDestinationURL error:&error];
- }
-
- if (error) {
- self.callback(@[@{@"error": error.localizedFailureReason}]);
- return;
- }
+ NSError *error = nil;
+
+ // If we have write access to the source file, move it. Otherwise use copy.
+ if ([fileManager isWritableFileAtPath:[videoURL path]]) {
+ [fileManager moveItemAtURL:videoURL toURL:videoDestinationURL error:&error];
+ } else {
+ [fileManager copyItemAtURL:videoURL toURL:videoDestinationURL error:&error];
+ }
+
+ if (error) {
+ self.callback(@[@{@"error": error.localizedFailureReason}]);
+ return;
+ }
}
}
-
+
[self.response setObject:videoDestinationURL.absoluteString forKey:@"uri"];
if (videoRefURL.absoluteString) {
[self.response setObject:videoRefURL.absoluteString forKey:@"origURL"];
}
-
+
NSDictionary *storageOptions = [self.options objectForKey:@"storageOptions"];
if (storageOptions && [[storageOptions objectForKey:@"cameraRoll"] boolValue] == YES && self.picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
+#if !TARGET_OS_MACCATALYST
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeVideoAtPathToSavedPhotosAlbum:videoDestinationURL completionBlock:^(NSURL *assetURL, NSError *error) {
if (error) {
@@ -509,22 +520,23 @@
self.response[@"timestamp"] = [[ImagePickerManager ISO8601DateFormatter] stringFromDate:capturedAsset.creationDate];
}
}
-
+
self.callback(@[self.response]);
}
}
}];
+#endif
}
}
-
+
// If storage options are provided, check the skipBackup flag
if ([self.options objectForKey:@"storageOptions"] && [[self.options objectForKey:@"storageOptions"] isKindOfClass:[NSDictionary class]]) {
NSDictionary *storageOptions = [self.options objectForKey:@"storageOptions"];
-
+
if ([[storageOptions objectForKey:@"skipBackup"] boolValue]) {
[self addSkipBackupAttributeToItemAtPath:path]; // Don't back up the file to iCloud
}
-
+
if ([[storageOptions objectForKey:@"waitUntilSaved"] boolValue] == NO ||
[[storageOptions objectForKey:@"cameraRoll"] boolValue] == NO ||
self.picker.sourceType != UIImagePickerControllerSourceTypeCamera)
@@ -536,7 +548,7 @@
self.callback(@[self.response]);
}
};
-
+
dispatch_async(dispatch_get_main_queue(), ^{
[picker dismissViewControllerAnimated:YES completion:dismissCompletionBlock];
});
@@ -595,12 +607,12 @@
- (UIImage*)downscaleImageIfNecessary:(UIImage*)image maxWidth:(float)maxWidth maxHeight:(float)maxHeight
{
UIImage* newImage = image;
-
+
// Nothing to do here
if (image.size.width <= maxWidth && image.size.height <= maxHeight) {
return newImage;
}
-
+
CGSize scaledSize = CGSizeMake(image.size.width, image.size.height);
if (maxWidth < scaledSize.width) {
scaledSize = CGSizeMake(maxWidth, (maxWidth / scaledSize.width) * scaledSize.height);
@@ -608,11 +620,11 @@
if (maxHeight < scaledSize.height) {
scaledSize = CGSizeMake((maxHeight / scaledSize.height) * scaledSize.width, maxHeight);
}
-
+
// If the pixels are floats, it causes a white line in iOS8 and probably other versions too
scaledSize.width = (int)scaledSize.width;
scaledSize.height = (int)scaledSize.height;
-
+
UIGraphicsBeginImageContext(scaledSize); // this will resize
[image drawInRect:CGRectMake(0, 0, scaledSize.width, scaledSize.height)];
newImage = UIGraphicsGetImageFromCurrentImageContext();
@@ -620,7 +632,7 @@
NSLog(@"could not scale image");
}
UIGraphicsEndImageContext();
-
+
return newImage;
}
@@ -628,7 +640,7 @@
if (srcImg.imageOrientation == UIImageOrientationUp) {
return srcImg;
}
-
+
CGAffineTransform transform = CGAffineTransformIdentity;
switch (srcImg.imageOrientation) {
case UIImageOrientationDown:
@@ -636,13 +648,13 @@
transform = CGAffineTransformTranslate(transform, srcImg.size.width, srcImg.size.height);
transform = CGAffineTransformRotate(transform, M_PI);
break;
-
+
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
transform = CGAffineTransformTranslate(transform, srcImg.size.width, 0);
transform = CGAffineTransformRotate(transform, M_PI_2);
break;
-
+
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, 0, srcImg.size.height);
@@ -652,14 +664,14 @@
case UIImageOrientationUpMirrored:
break;
}
-
+
switch (srcImg.imageOrientation) {
case UIImageOrientationUpMirrored:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, srcImg.size.width, 0);
transform = CGAffineTransformScale(transform, -1, 1);
break;
-
+
case UIImageOrientationLeftMirrored:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, srcImg.size.height, 0);
@@ -671,7 +683,7 @@
case UIImageOrientationRight:
break;
}
-
+
CGContextRef ctx = CGBitmapContextCreate(NULL, srcImg.size.width, srcImg.size.height, CGImageGetBitsPerComponent(srcImg.CGImage), 0, CGImageGetColorSpace(srcImg.CGImage), CGImageGetBitmapInfo(srcImg.CGImage));
CGContextConcatCTM(ctx, transform);
switch (srcImg.imageOrientation) {
@@ -681,12 +693,12 @@
case UIImageOrientationRightMirrored:
CGContextDrawImage(ctx, CGRectMake(0,0,srcImg.size.height,srcImg.size.width), srcImg.CGImage);
break;
-
+
default:
CGContextDrawImage(ctx, CGRectMake(0,0,srcImg.size.width,srcImg.size.height), srcImg.CGImage);
break;
}
-
+
CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
UIImage *img = [UIImage imageWithCGImage:cgimg];
CGContextRelease(ctx);
@@ -701,7 +713,7 @@
NSError *error = nil;
BOOL success = [URL setResourceValue: [NSNumber numberWithBool: YES]
forKey: NSURLIsExcludedFromBackupKey error: &error];
-
+
if(!success){
NSLog(@"Error excluding %@ from backup %@", [URL lastPathComponent], error);
}

View File

@ -15,12 +15,8 @@ cd node_modules/react-native-camera/ios/RCT
patch RCTCameraManager.m ../../../../scripts/maccatalystpatches/RCTCameraManager.patch --no-backup-if-mismatch
cd ../RN/
patch RNCamera.m ../../../../scripts/maccatalystpatches/RNCamera.patch
echo "Applying patch for react-native-image-picker"
cd ../../../../
cd node_modules/react-native-image-picker/ios
patch ImagePickerManager.m ../../../scripts/maccatalystpatches/ImagePickerManager.patch --no-backup-if-mismatch
echo "Applying patch for Podfile"
cd ../../../
cd ../../../../
patch ios/Podfile ./scripts/maccatalystpatches/podfile.patch --no-backup-if-mismatch
echo "Applying patch for Realm podspec"
patch node_modules/realm/RealmJS.podspec ./scripts/maccatalystpatches/realm.patch --no-backup-if-mismatch