Adds support for picking remote images on iOS (multi-picking from Gallery)
This commit is contained in:
parent
806a074216
commit
7d6bffd692
|
@ -1,3 +1,7 @@
|
||||||
|
## 1.7.0
|
||||||
|
**Breaking change**
|
||||||
|
Added support for multi-picks from Photos app on iOS through [BSImagePicker](https://github.com/mikaoj/BSImagePicker) — use any of the `getMulti` methods with `FileType.image`. From now on, you'll need to set your iOS minimum version to 10.0 and add `use_frameworks!` in your ios/Podfile.
|
||||||
|
|
||||||
## 1.6.3+2
|
## 1.6.3+2
|
||||||
* Fixes a crash on Android when a file has an id that can't be resolved and uses a name instead (#221);
|
* Fixes a crash on Android when a file has an id that can't be resolved and uses a name instead (#221);
|
||||||
* Minor fix on Go (Desktop) - Windows (thanks @marchellodev);
|
* Minor fix on Go (Desktop) - Windows (thanks @marchellodev);
|
||||||
|
|
|
@ -99,6 +99,7 @@
|
||||||
[_viewController presentViewController:self.documentPickerController animated:YES completion:nil];
|
[_viewController presentViewController:self.documentPickerController animated:YES completion:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (void) resolvePickImage:(BOOL)withMultiPick {
|
- (void) resolvePickImage:(BOOL)withMultiPick {
|
||||||
|
|
||||||
if(!withMultiPick) {
|
if(!withMultiPick) {
|
||||||
|
@ -112,42 +113,69 @@
|
||||||
} else {
|
} else {
|
||||||
ImagePickerController * multiImagePickerController = [[ImagePickerController alloc] initWithSelectedAssets:@[]];
|
ImagePickerController * multiImagePickerController = [[ImagePickerController alloc] initWithSelectedAssets:@[]];
|
||||||
|
|
||||||
|
UIProgressView * progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(0.0, 0.0, multiImagePickerController.view.bounds.size.width, 10.0)];
|
||||||
|
CGAffineTransform transform = CGAffineTransformMakeScale(1.0f, 4.0f);
|
||||||
|
progressView.transform = transform;
|
||||||
|
|
||||||
[_viewController presentImagePicker:multiImagePickerController
|
[_viewController presentImagePicker:multiImagePickerController
|
||||||
animated:YES
|
animated:YES
|
||||||
select:^(PHAsset * _Nonnull selectedAsset) {}
|
select:^(PHAsset * _Nonnull selectedAsset) {}
|
||||||
deselect:^(PHAsset * _Nonnull deselectedAsset) {}
|
deselect:^(PHAsset * _Nonnull deselectedAsset) {}
|
||||||
cancel:^(NSArray<PHAsset *> * _Nonnull canceledAsset) {}
|
cancel:^(NSArray<PHAsset *> * _Nonnull canceledAsset) {
|
||||||
finish:^(NSArray<PHAsset *> * _Nonnull assets) {
|
self->_result(nil);
|
||||||
NSMutableArray<NSString*> *paths = [[NSMutableArray<NSString*> alloc] init];
|
self->_result = nil;
|
||||||
|
}
|
||||||
if(assets.count > 0) {
|
finish:^(NSArray<PHAsset *> * _Nonnull assets) {
|
||||||
dispatch_semaphore_t completer = dispatch_semaphore_create(0);
|
int totalRemoteAssets = [FileUtils countRemoteAssets:assets];
|
||||||
__block int processedAssets = 0;
|
NSMutableArray<NSString*> *paths = [[NSMutableArray<NSString*> alloc] init];
|
||||||
|
NSMutableDictionary<NSString*, NSNumber*> * progresses = [[NSMutableDictionary<NSString*, NSNumber*> alloc] initWithCapacity: totalRemoteAssets];
|
||||||
for(PHAsset* asset in assets){
|
|
||||||
[asset requestContentEditingInputWithOptions:[PHContentEditingInputRequestOptions new] completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
|
|
||||||
NSURL *imageURL = contentEditingInput.fullSizeImageURL;
|
|
||||||
[paths addObject:imageURL.path];
|
|
||||||
|
|
||||||
if(++processedAssets == assets.count) {
|
|
||||||
dispatch_semaphore_signal(completer);
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (![NSThread isMainThread]) {
|
|
||||||
dispatch_semaphore_wait(completer, DISPATCH_TIME_FOREVER);
|
|
||||||
} else {
|
|
||||||
while (dispatch_semaphore_wait(completer, DISPATCH_TIME_NOW)) {
|
|
||||||
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self->_result(paths);
|
if(totalRemoteAssets > 0) {
|
||||||
self->_result = nil;
|
[multiImagePickerController.view addSubview:progressView];
|
||||||
|
}
|
||||||
} completion:^{}];
|
|
||||||
|
if(assets.count > 0) {
|
||||||
|
dispatch_semaphore_t completer = dispatch_semaphore_create(0);
|
||||||
|
__block int processedAssets = 0;
|
||||||
|
|
||||||
|
for(PHAsset* asset in assets){
|
||||||
|
PHContentEditingInputRequestOptions * options = [[PHContentEditingInputRequestOptions alloc] init];
|
||||||
|
options.networkAccessAllowed = YES;
|
||||||
|
|
||||||
|
if(![FileUtils isLocalAsset:asset]){
|
||||||
|
options.progressHandler = ^(double progress, BOOL * _Nonnull stop) {
|
||||||
|
progresses[asset.localIdentifier] = [NSNumber numberWithFloat:progress];
|
||||||
|
@synchronized(progresses){
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
progressView.progress = [[[progresses allValues] valueForKeyPath:@"@sum.self"] floatValue] / totalRemoteAssets;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[asset requestContentEditingInputWithOptions:options completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
|
||||||
|
NSURL *imageURL = contentEditingInput.fullSizeImageURL;
|
||||||
|
[paths addObject:imageURL.path];
|
||||||
|
|
||||||
|
if(++processedAssets == assets.count) {
|
||||||
|
dispatch_semaphore_signal(completer);
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (![NSThread isMainThread]) {
|
||||||
|
dispatch_semaphore_wait(completer, DISPATCH_TIME_FOREVER);
|
||||||
|
} else {
|
||||||
|
while (dispatch_semaphore_wait(completer, DISPATCH_TIME_NOW)) {
|
||||||
|
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self->_result(paths);
|
||||||
|
self->_result = nil;
|
||||||
|
|
||||||
|
} completion:^{}];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
// Created by Miguel Ruivo on 05/12/2018.
|
// Created by Miguel Ruivo on 05/12/2018.
|
||||||
//
|
//
|
||||||
#import <MobileCoreServices/MobileCoreServices.h>
|
#import <MobileCoreServices/MobileCoreServices.h>
|
||||||
|
#import <Photos/Photos.h>
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#define Log(fmt, ...) NSLog((@"\n\n***** " fmt @"\n* %s [Line %d]\n\n\n"), ##__VA_ARGS__, __PRETTY_FUNCTION__, __LINE__)
|
#define Log(fmt, ...) NSLog((@"\n\n***** " fmt @"\n* %s [Line %d]\n\n\n"), ##__VA_ARGS__, __PRETTY_FUNCTION__, __LINE__)
|
||||||
|
@ -15,6 +16,8 @@
|
||||||
@interface FileUtils : NSObject
|
@interface FileUtils : NSObject
|
||||||
+ (NSArray<NSString*>*) resolveType:(NSString*)type withAllowedExtensions:(NSArray<NSString*>*)allowedExtensions;
|
+ (NSArray<NSString*>*) resolveType:(NSString*)type withAllowedExtensions:(NSArray<NSString*>*)allowedExtensions;
|
||||||
+ (NSArray*) resolvePath:(NSArray<NSURL *> *)urls;
|
+ (NSArray*) resolvePath:(NSArray<NSURL *> *)urls;
|
||||||
|
+ (int) countRemoteAssets:(NSArray<PHAsset*> *)assets;
|
||||||
|
+ (BOOL) isLocalAsset:(PHAsset *) asset;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -57,4 +57,20 @@
|
||||||
return paths;
|
return paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (int)countRemoteAssets:(NSArray<PHAsset*> *)assets {
|
||||||
|
int total = 0;
|
||||||
|
for(PHAsset * asset in assets) {
|
||||||
|
NSArray *resourceArray = [PHAssetResource assetResourcesForAsset:asset];
|
||||||
|
if(![[resourceArray.firstObject valueForKey:@"locallyAvailable"] boolValue]) {
|
||||||
|
total++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (BOOL)isLocalAsset:(PHAsset *) asset {
|
||||||
|
NSArray *resourceArray = [PHAssetResource assetResourcesForAsset:asset];
|
||||||
|
return [[resourceArray.firstObject valueForKey:@"locallyAvailable"] boolValue];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
name: file_picker
|
name: file_picker
|
||||||
description: A package that allows you to use a native file explorer to pick single or multiple absolute file paths, with extension filtering support.
|
description: A package that allows you to use a native file explorer to pick single or multiple absolute file paths, with extension filtering support.
|
||||||
homepage: https://github.com/miguelpruivo/plugins_flutter_file_picker
|
homepage: https://github.com/miguelpruivo/plugins_flutter_file_picker
|
||||||
version: 1.6.3+2
|
version: 1.7.0
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
|
|
Loading…
Reference in New Issue