Closed RocKhalil closed 3 years ago
Hello @RocKhalil, it should be possible.
But maybe is there a way to tell react-native-cameraroll to return another type for photo.image.uri
@jgcmarins I wrote a small hack for it right now (within the cameraroll
) in order to keep going with the development; but I'll try writing a fix to allow ph
asset to be read directly.
Maybe you can get inspired by this for the react-native-share
updates
if ([assetMediaTypeLabel isEqual:@"image"]) {
[asset requestContentEditingInputWithOptions:nil completionHandler:^(PHContentEditingInput * _Nullable contentEditingInput, NSDictionary * _Nonnull info) {
url = contentEditingInput.fullSizeImageURL.absoluteString;
}];
} else {
[[PHImageManager defaultManager] requestAVAssetForVideo:asset options:nil resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
AVURLAsset *urlAsset = (AVURLAsset*)asset;
url = [[urlAsset URL] absoluteString];
}];
}
do { } while( [url isEqual:@""] );
I know that the code is not performance oriented, but I need to move on from this task and will get back to this one as soon as possible.
@RocKhalil great to hear that. Pull requests are welcome. Feel free to open one with this improvement. I can help with code review.
@jgcmarins I tried adding the above piece of code to RNShare
directly; here's where I currently stand:
#import <Photos/Photos.h>
RCT_EXPORT_METHOD(open:(NSDictionary *)options
failureCallback:(RCTResponseErrorBlock)failureCallback
successCallback:(RCTResponseSenderBlock)successCallback)
{
....
if ([URL.scheme.lowercaseString isEqualToString:@"data"]) {
...
} else if ([URL.scheme.lowercaseString isEqualToString:@"ph"]) {
NSString *assetIdentifier = [urlsArray[i] stringByReplacingOccurrencesOfString: @"ph://" withString: @""];
PHFetchResult *fetchResult = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers: @[assetIdentifier] options:nil];
PHAsset *asset = fetchResult.firstObject;
NSString __block *url = @"";
if (asset){
switch (asset.mediaType) {
case PHAssetMediaTypeVideo:
[[PHImageManager defaultManager] requestAVAssetForVideo:asset options:nil resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
AVURLAsset *urlAsset = (AVURLAsset*)asset;
url = [[urlAsset URL] absoluteString];
}];
break;
case PHAssetMediaTypeImage:
[asset requestContentEditingInputWithOptions:nil completionHandler:^(PHContentEditingInput * _Nullable contentEditingInput, NSDictionary * _Nonnull info) {
url = contentEditingInput.fullSizeImageURL.absoluteString;
}
];
break;
default:
RCTLogError(@"Asset type can't be shared");
return;
}
do { } while( [url isEqual:@""] );
[items addObject: url];
}
} else {
[items addObject:URL];
}
....
}
Now the issue is that do { } while( [url isEqual:@""] )
is executed on the main_queue and the app is freezing. I'm not that advanced is Objective-C and not sure how to await
a block for completing instead of doing this method.
If you can help me with this, I'll test the solution and create a PR asap.
Thanks :-)
@jgcmarins the previous answer had some issues (not sharing correctly), so I wrote a better fix for PHAsset
sharing:
#import <UIKit/UIWindow.h>
#import <UIKit/UIActivityViewController.h>
RCT_REMAP_METHOD(getShareModal, assetURI:(NSString *)assetURI)
{
NSMutableArray *activityItems = [NSMutableArray array];
// image Loader
PHImageManager *im = [PHImageManager defaultManager];
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
options.synchronous = YES;
options.version = PHImageRequestOptionsVersionCurrent;
options.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
options.resizeMode = PHImageRequestOptionsResizeModeNone;
PHFetchResult<PHAsset *> *fetchResult;
NSString *const localIdentifier = [assetURI substringFromIndex:@"ph://".length];
fetchResult = [PHAsset fetchAssetsWithLocalIdentifiers:@[localIdentifier] options:nil];
PHAsset *const _Nonnull asset = [fetchResult firstObject];
// load image
[im requestImageDataForAsset:asset options:options resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info)
{
[activityItems addObject:imageData];
}];
// generate the activity view
UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:nil];
// prevent sharing to gallery again
activityVC.excludedActivityTypes = @[UIActivityTypeSaveToCameraRoll];
// get the top root view controller
UIViewController *topRootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (topRootViewController.presentedViewController)
{
topRootViewController = topRootViewController.presentedViewController;
}
// present it
[topRootViewController presentViewController:activityVC animated:YES completion:nil];
}
This way, whoever is calling the API will only do: getShareModal('ph://....')
and the modal will show.
That's great. Does it makes sense to support PHAsset. I mean, does Apple is moving around to this type for URIs?
@jgcmarins mainly yes.
It will also give compatibility to share images retrieved from @react-native-community/cameraroll
.
All the images that come from the system are PHAsset
and should be handled this way..
👍
This looks like a cleaner version of a fix I had to write to get the share working for image and video phasset urls on iOS. I used dispatch_semaphore...
to signal when to continue after getting what I need from the asset.
I'm just in the process of extending the IG share (and stories) to also cater for ph:// urls too.
This looks like a cleaner version of a fix I had to write to get the share working for image and video phasset urls on iOS. I used
dispatch_semaphore...
to signal when to continue after getting when I need from the asset.I'm just in the process of extending the IG share (and stories) to also cater for ph:// urls too.
This would be a great to rn-share. Do you need any help on that?
This would be a great to rn-share. Do you need any help on that?
Cheers! 👍🏻 I might to perhaps tighten up the Obj-C code as I don’t have lots of experience in it. I’ll get it working for what I’m doing and then put a PR together. Just want to get stories with stickers working again!
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. You may also mark this issue as a "discussion" and i will leave this open
Hey! Did this end up being merged into react-native-share? Can you share ph://
assets now?
About
I'm trying to share images from my CameraRoll using
@react-native-community/react-native-share
and@react-native-community/cameraroll
Code Preview
This isn't the actual one, but works fine for demo purposes.
Question
On android, it's working perfectly. However, on iOS, we get from
photo.image.uri
aPHAsset
url of the asset. Right now, when the share dialog opens, we can't see the file that is being shared and we only see001
which is the PHAsset's last file path. Is there any way to share theph://....
image or video directly ?