Merge remote-tracking branch 'ivpusic/master'

This commit is contained in:
Andrew Shini 2016-09-11 07:58:56 +10:00
commit e45feb3423
5 changed files with 132 additions and 2 deletions

View File

@ -47,6 +47,17 @@ ImagePicker.openCamera({
});
```
#### Optional cleanup
Module is creating tmp images which are going to be cleaned up automatically somewhere in the future. If you want to force cleanup, you can use `clean` to clean all tmp files, or `cleanSingle(path)` to clean single tmp file.
```javascript
ImagePicker.clean().then(() => {
console.log('removed all tmp images from tmp directory');
}).catch(e => {
alert(e);
});
```
#### Request Object
| Property | Type | Description |
@ -79,6 +90,14 @@ react-native link react-native-image-crop-picker
#### Post-install steps
##### iOS
###### cocoapods users
- Add `platform :ios, '8.0'` to Podfile (!important)
- Add `pod 'RSKImageCropper'` and `pod 'QBImagePickerController'` to Podfile
###### non-cocoapods users
- Drag and drop the ios/ImageCropPickerSDK folder to your xcode project. (Make sure Copy items if needed IS ticked)
- Click on project General tab
- Under `Deployment Info` set `Deployment Target` to `8.0`
@ -89,6 +108,25 @@ react-native link react-native-image-crop-picker
- [Optional] If you want to use camera picker in your project, add following to `AndroidManifest.xml`
- `<uses-permission android:name="android.permission.CAMERA"/>`
#### Production build
##### iOS
###### cocoapods users
- You are already done
###### non-cocoapods users
If you are using pre-built frameworks from `ios/ImageCropPickerSDK`, then before deploying app to production you should strip off simulator ARCHs from these, or you can add frameworks from `Libraries/imageCropPicker/Libraries/_framework_name_.xcodeproj/Products/_framework_name_.framework` to Embedded Binaries instead of pre-built ones.
Related issue: https://github.com/ivpusic/react-native-image-crop-picker/issues/61.
Details for second approach:
1. Remove the pre-built frameworks from `Embedded Binaries`
2. Build for Device
4. Add the newly built binaries for both frameworks to `Embedded Binaries` (located at `Libraries/imageCropPicker/Libraries/_framework_name_.xcodeproj/Products/_framework_name_.framework`)
## How it works?
It is basically wrapper around few libraries
@ -103,3 +141,4 @@ It is basically wrapper around few libraries
## License
*MIT*

View File

@ -90,6 +90,16 @@ public class PickerModule extends ReactContextBaseJavaModule implements Activity
cropping = options.hasKey("cropping") ? options.getBoolean("cropping") : cropping;
}
@ReactMethod
public void clean(final Promise promise) {
promise.resolve(null);
}
@ReactMethod
public void cleanSingle(final String path, final Promise promise) {
promise.resolve(null);
}
@ReactMethod
public void openCamera(final ReadableMap options, final Promise promise) {
int requestCode = CAMERA_PICKER_REQUEST;

View File

@ -60,6 +60,25 @@ export default class App extends Component {
}).catch(e => {});
}
cleanupImages() {
ImagePicker.clean().then(() => {
console.log('removed tmp images from tmp directory');
}).catch(e => {
alert(e);
});
}
cleanupSingleImage() {
let image = this.state.image || (this.state.images && this.state.images.length ? this.state.images[0] : null);
console.log('will cleanup image', image);
ImagePicker.cleanSingle(image ? image.uri : null).then(() => {
console.log(`removed tmp image ${image.uri} from tmp directory`);
}).catch(e => {
alert(e);
})
}
pickSingle(cropit) {
ImagePicker.openPicker({
width: 300,
@ -117,6 +136,12 @@ export default class App extends Component {
<TouchableOpacity onPress={this.pickMultiple.bind(this)} style={styles.button}>
<Text style={styles.text}>Select Multiple</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this.cleanupImages.bind(this)} style={styles.button}>
<Text style={styles.text}>Cleanup All Images</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this.cleanupSingleImage.bind(this)} style={styles.button}>
<Text style={styles.text}>Cleanup Single Image</Text>
</TouchableOpacity>
</View>;
}
}

View File

@ -16,6 +16,9 @@
#define ERROR_PICKER_CANCEL_KEY @"picker_cancel"
#define ERROR_PICKER_CANCEL_MSG @"User cancelled image selection"
#define ERROR_CLEANUP_ERROR_KEY @"cleanup_error"
#define ERROR_CLEANUP_ERROR_MSG @"Error while cleaning up tmp files"
#define ERROR_CANNOT_SAVE_IMAGE_KEY @"cannot_save_image"
#define ERROR_CANNOT_SAVE_IMAGE_MSG @"Cannot save image. Unable to write to tmp location."
@ -113,6 +116,48 @@ RCT_EXPORT_METHOD(openCamera:(NSDictionary *)options
[picker dismissViewControllerAnimated:YES completion:NULL];
}
- (NSString*) getTmpDirectory {
NSString* TMP_DIRECTORY = @"/react-native-image-crop-picker/";
return [NSTemporaryDirectory() stringByAppendingString:TMP_DIRECTORY];
}
- (BOOL)cleanTmpDirectory {
NSString* tmpDirectoryPath = [self getTmpDirectory];
NSArray* tmpDirectory = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:tmpDirectoryPath error:NULL];
for (NSString *file in tmpDirectory) {
BOOL deleted = [[NSFileManager defaultManager] removeItemAtPath:[NSString stringWithFormat:@"%@%@", tmpDirectoryPath, file] error:NULL];
if (!deleted) {
return NO;
}
}
return YES;
}
RCT_EXPORT_METHOD(cleanSingle:(NSString *) path
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
BOOL deleted = [[NSFileManager defaultManager] removeItemAtPath:path error:NULL];
if (!deleted) {
reject(ERROR_CLEANUP_ERROR_KEY, ERROR_CLEANUP_ERROR_MSG, nil);
} else {
resolve(nil);
}
}
RCT_REMAP_METHOD(clean, resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
if (![self cleanTmpDirectory]) {
reject(ERROR_CLEANUP_ERROR_KEY, ERROR_CLEANUP_ERROR_MSG, nil);
} else {
resolve(nil);
}
}
RCT_EXPORT_METHOD(openPicker:(NSDictionary *)options
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
@ -158,6 +203,7 @@ RCT_EXPORT_METHOD(openPicker:(NSDictionary *)options
NSString *filePath = [self persistFile:data];
if (filePath == nil) {
self.reject(ERROR_CANNOT_SAVE_IMAGE_KEY, ERROR_CANNOT_SAVE_IMAGE_MSG, nil);
[imagePickerController dismissViewControllerAnimated:YES completion:nil];
return;
}
@ -212,6 +258,7 @@ RCT_EXPORT_METHOD(openPicker:(NSDictionary *)options
NSString *filePath = [self persistFile:data];
if (filePath == nil) {
self.reject(ERROR_CANNOT_SAVE_IMAGE_KEY, ERROR_CANNOT_SAVE_IMAGE_MSG, nil);
[viewController dismissViewControllerAnimated:YES completion:nil];
return;
}
@ -301,6 +348,7 @@ RCT_EXPORT_METHOD(openPicker:(NSDictionary *)options
NSString *filePath = [self persistFile:data];
if (filePath == nil) {
self.reject(ERROR_CANNOT_SAVE_IMAGE_KEY, ERROR_CANNOT_SAVE_IMAGE_MSG, nil);
[controller dismissViewControllerAnimated:YES completion:nil];
return;
}
@ -319,8 +367,16 @@ RCT_EXPORT_METHOD(openPicker:(NSDictionary *)options
// at the moment it is not possible to upload image by reading PHAsset
// we are saving image and saving it to the tmp location where we are allowed to access image later
- (NSString*) persistFile:(NSData*)data {
// create tmp directory
NSString *tmpDirFullPath = [self getTmpDirectory];
BOOL dirCreated = [[NSFileManager defaultManager] createDirectoryAtPath: tmpDirFullPath
withIntermediateDirectories:YES attributes:nil error:nil];
if (!dirCreated) {
return nil;
}
// create temp file
NSString *filePath = [NSTemporaryDirectory() stringByAppendingString:[[NSUUID UUID] UUIDString]];
NSString *filePath = [tmpDirFullPath stringByAppendingString:[[NSUUID UUID] UUIDString]];
filePath = [filePath stringByAppendingString:@".jpg"];
// save cropped file

View File

@ -1,6 +1,6 @@
{
"name": "react-native-image-crop-picker",
"version": "0.8.1",
"version": "0.8.2",
"description": "Select single or multiple images, with croping option",
"main": "index.js",
"scripts": {