Skip to content

feat: use own implementation to save cropped images on ios #28

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions ios/RNCFileSystem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// RNFileSystem.h
// RNCImageEditor
//
// Created by Dawid Urbaniak on 30/05/2019.
// Copyright © 2019 Facebook. All rights reserved.
//

#ifndef RNCFileSystem_h
#define RNCFileSystem_h

#import <Foundation/Foundation.h>

@interface RNCFileSystem : NSObject

+ (BOOL)ensureDirExistsWithPath:(NSString *)path;
+ (NSString *)generatePathInDirectory:(NSString *)directory withExtension:(NSString *)extension;
+ (NSString *)cacheDirectoryPath;

@end

#endif /* RNCFileSystem_h */
40 changes: 40 additions & 0 deletions ios/RNCFileSystem.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// RNFileSystem.m
// RNCImageEditor
//
// Created by Dawid Urbaniak on 30/05/2019.
// Copyright © 2019 Facebook. All rights reserved.
//

#import "RNCFileSystem.h"

@implementation RNCFileSystem

+ (BOOL)ensureDirExistsWithPath:(NSString *)path
{
BOOL isDir = NO;
NSError *error;
BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDir];
if (!(exists && isDir)) {
[[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error];
if (error) {
return NO;
}
}
return YES;
}

+ (NSString *)generatePathInDirectory:(NSString *)directory withExtension:(NSString *)extension
{
NSString *fileName = [[[NSUUID UUID] UUIDString] stringByAppendingString:extension];
[RNCFileSystem ensureDirExistsWithPath:directory];
return [directory stringByAppendingPathComponent:fileName];
}

+ (NSString *)cacheDirectoryPath
{
NSArray *array = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
return [array objectAtIndex:0];
}

@end
24 changes: 15 additions & 9 deletions ios/RNCImageEditor.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

#import <React/RCTImageLoader.h>
#import <React/RCTImageStoreManager.h>
#import "RNCFileSystem.h"
#import "RNCImageUtils.h"
#if __has_include(<RCTImage/RCTImageUtils.h>)
#import <RCTImage/RCTImageUtils.h>
#else
Expand All @@ -28,7 +30,8 @@ @implementation RNCImageEditor
@synthesize bridge = _bridge;

/**
* Crops an image and adds the result to the image store.
* Crops an image and saves the result to temporary file. Consider using
* CameraRoll API or other third-party module to save it in gallery.
*
* @param imageRequest An image URL
* @param cropData Dictionary with `offset`, `size` and `displaySize`.
Expand Down Expand Up @@ -69,15 +72,18 @@ @implementation RNCImageEditor
}

// Store image
[self->_bridge.imageStoreManager storeImage:croppedImage withBlock:^(NSString *croppedImageTag) {
if (!croppedImageTag) {
NSString *errorMessage = @"Error storing cropped image in RCTImageStoreManager";
RCTLogWarn(@"%@", errorMessage);
errorCallback(RCTErrorWithMessage(errorMessage));
NSString *path = [RNCFileSystem generatePathInDirectory:[[RNCFileSystem cacheDirectoryPath] stringByAppendingPathComponent:@"ReactNative_cropped_image_"] withExtension:@".jpg"];

NSData *imageData = UIImageJPEGRepresentation(croppedImage, 1);
NSError *writeError;
NSString *uri = [RNCImageUtils writeImage:imageData toPath:path error:&writeError];

if (writeError != nil) {
errorCallback(writeError);
return;
}
successCallback(@[croppedImageTag]);
}];
}

successCallback(@[uri]);
}];
}

Expand Down
12 changes: 12 additions & 0 deletions ios/RNCImageEditor.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
objects = {

/* Begin PBXBuildFile section */
1478DE2B22A0403F00D818FA /* RNCFileSystem.m in Sources */ = {isa = PBXBuildFile; fileRef = 1478DE2A22A0403F00D818FA /* RNCFileSystem.m */; };
1478DE2E22A044E500D818FA /* RNCImageUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 1478DE2D22A044E500D818FA /* RNCImageUtils.m */; };
B3E7B58A1CC2AC0600A0062D /* RNCImageEditor.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* RNCImageEditor.m */; };
/* End PBXBuildFile section */

Expand All @@ -24,6 +26,10 @@

/* Begin PBXFileReference section */
134814201AA4EA6300B7C361 /* libRNCImageEditor.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNCImageEditor.a; sourceTree = BUILT_PRODUCTS_DIR; };
1478DE2A22A0403F00D818FA /* RNCFileSystem.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNCFileSystem.m; sourceTree = "<group>"; };
1478DE2C22A0406800D818FA /* RNCFileSystem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNCFileSystem.h; sourceTree = "<group>"; };
1478DE2D22A044E500D818FA /* RNCImageUtils.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNCImageUtils.m; sourceTree = "<group>"; };
1478DE2F22A0450800D818FA /* RNCImageUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNCImageUtils.h; sourceTree = "<group>"; };
B3E7B5881CC2AC0600A0062D /* RNCImageEditor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNCImageEditor.h; sourceTree = "<group>"; };
B3E7B5891CC2AC0600A0062D /* RNCImageEditor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNCImageEditor.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
Expand All @@ -50,6 +56,10 @@
58B511D21A9E6C8500147676 = {
isa = PBXGroup;
children = (
1478DE2A22A0403F00D818FA /* RNCFileSystem.m */,
1478DE2D22A044E500D818FA /* RNCImageUtils.m */,
1478DE2F22A0450800D818FA /* RNCImageUtils.h */,
1478DE2C22A0406800D818FA /* RNCFileSystem.h */,
B3E7B5881CC2AC0600A0062D /* RNCImageEditor.h */,
B3E7B5891CC2AC0600A0062D /* RNCImageEditor.m */,
134814211AA4EA7D00B7C361 /* Products */,
Expand Down Expand Up @@ -112,6 +122,8 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
1478DE2E22A044E500D818FA /* RNCImageUtils.m in Sources */,
1478DE2B22A0403F00D818FA /* RNCFileSystem.m in Sources */,
B3E7B58A1CC2AC0600A0062D /* RNCImageEditor.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
21 changes: 21 additions & 0 deletions ios/RNCImageUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// RNCImageUtils.h
// RNCImageEditor
//
// Created by Dawid Urbaniak on 30/05/2019.
// Copyright © 2019 Facebook. All rights reserved.
//

#ifndef RNCImageUtils_h
#define RNCImageUtils_h

#import <Foundation/Foundation.h>

@interface RNCImageUtils : NSObject

+ (NSString *)writeImage:(NSData *)image toPath:(NSString *)path error:(NSError **)error;

@end


#endif /* RNCImageUtils_h */
24 changes: 24 additions & 0 deletions ios/RNCImageUtils.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// RNCImageUtils.m
// RNCImageEditor
//
// Created by Dawid Urbaniak on 30/05/2019.
// Copyright © 2019 Facebook. All rights reserved.
//

#import "RNCImageUtils.h"

@implementation RNCImageUtils

+ (id)writeImage:(id)image toPath:(id)path error:(NSError **)error
{
BOOL res = [image writeToFile:path atomically:YES];
if (res == NO) {
*error = [NSError errorWithDomain:@"org.reactnativecommunity.imageeditor.writeToFileError" code:101 userInfo:[NSDictionary dictionary]];
return nil;
}
NSURL *fileURL = [NSURL fileURLWithPath:path];
return [fileURL absoluteString];
}

@end