Background:
I have an app written in react-native that uses the react-native-share
package.
I've forked this package as there is an issue where a downloaded image or video won't share from a placeholder asset (PHAsset) URL (e.g. ph://[media-id]
)
I've had some partial success with the code below and Images now work. Videos are proving a little more tricky. I can take the ph://
URL and get the asset which results in a file://
URL that works ONLY when sharing via airdrop. The URL resolves and I get the MP4 file on my desktop...great!
The Problem:
However, if I try and share the same file://
URL to a message or email I just see the link itself.
Possible solution:
I'm assuming I need to resolve that video asset to an NSData
object in the Obj-c and then send the file itself back for the share component to handle (like the image one does) but I'm not too great with Obj-C so would appreciate some help!
For videos, the file is always an mp4 file.
Here's my code: (I'm passing the ph://
URL to the native side...)
...
if([URL.scheme.lowercaseString isEqualToString:@"ph"]) {
NSString *assetIdentifier = [urlsArray[i] stringByReplacingOccurrencesOfString: @"ph://" withString: @""];
PHFetchResult *fetchResult = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers: @[assetIdentifier] options:nil];
PHAsset *asset = fetchResult.firstObject;
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
options.synchronous = YES;
options.version = PHImageRequestOptionsVersionCurrent;
options.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
options.resizeMode = PHImageRequestOptionsResizeModeNone;
PHVideoRequestOptions *options2 = [[PHVideoRequestOptions alloc] init];
options2.networkAccessAllowed = YES;
options2.deliveryMode = PHVideoRequestOptionsDeliveryModeHighQualityFormat;
options2.version = PHVideoRequestOptionsVersionCurrent;
NSString __block *url = @"";
if (asset){
switch(asset.mediaType) {
case PHAssetMediaTypeVideo: {
//*** THIS IS THE PROBLEMATIC AREA ***
[[PHImageManager defaultManager] requestAVAssetForVideo:asset options:options2 resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
AVURLAsset *urlAsset = (AVURLAsset*)asset;
url = [[urlAsset URL] absoluteString];
[items addObject: url]; //items is passed over to the share handler
dispatch_semaphore_signal(semaphore); //added to counter-act the fact requestAVAssetForVideo is asynchronous
}];
break;
}
case PHAssetMediaTypeImage: {
//*** THIS SHARES IMAGES AS EXPECTED ***
[[PHImageManager defaultManager] requestImageDataForAsset:asset options:options resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info)
{
[items addObject:imageData]; //items is passed over to the share handler
dispatch_semaphore_signal(semaphore); //added to counter-act the fact requestAVAssetForVideo is asynchronous
}];
break;
}
default: {
RCTLogError(@"Asset type can't be shared");
return;
}
}
}
}
...