UIImagePickerController 无法获取本地图像 url

UIImagePickerController unable to fetch local image url

我正在尝试通过 UIImagePickerController 选取图像并将其上传到服务器来上传图像。为此,我需要图像的实际本地路径 (url)。由于我的目标是 iOS 9.0 及更高版本,因此我使用的是照片框架。 我能够从 PHAsset 获取文件名以及 url 。我也在检查文件是否存在于此 url,但是当我尝试上传图像时,我不确定这是否是提供给 [=19] 的正确 url =] 服务器上的脚本。 php 脚本需要文件名、设备上的实际位置以及文件数据。

这是我的代码:

#import "ViewController.h"
#import <Photos/Photos.h>
#import <MobileCoreServices/MobileCoreServices.h>


@interface ViewController ()



@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
        switch (status) {
            case PHAuthorizationStatusAuthorized:
                NSLog(@"PHAuthorizationStatusAuthorized");
                break;
            case PHAuthorizationStatusDenied:
                NSLog(@"PHAuthorizationStatusDenied");
                break;
            case PHAuthorizationStatusNotDetermined:
                NSLog(@"PHAuthorizationStatusNotDetermined");
                break;
            case PHAuthorizationStatusRestricted:
                NSLog(@"PHAuthorizationStatusRestricted");
                break;
        }
    }];
    NSLog(@"%@",NSHomeDirectory());

}

- (IBAction)fileSelect:(id)sender {

    UIAlertController * actionSheet = [UIAlertController alertControllerWithTitle:nil message:@"File oprions:" preferredStyle:UIAlertControllerStyleActionSheet];

    UIAlertAction * camera = [UIAlertAction actionWithTitle:@"Take photo with camera" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        NSLog(@"Camera");
        UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];

        // Set source to the camera
        imagePicker.sourceType =  UIImagePickerControllerSourceTypeCamera;

        // Delegate is self
        imagePicker.delegate = self;

        // Allow editing of image ?


        // Show image picker


        //[[UINavigationBar appearance] setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
        [self presentViewController:imagePicker animated:YES completion:nil];
    }];

    UIAlertAction * gallery = [UIAlertAction actionWithTitle:@"Choose an existing photo" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        NSLog(@"Gallery");
        UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];

        // Set source to the camera
        imagePicker.sourceType =  UIImagePickerControllerSourceTypePhotoLibrary;

        // Delegate is self
        imagePicker.delegate = self;

        // Allow editing of image ?


        // Show image picker


        //[[UINavigationBar appearance] setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
        [self presentViewController:imagePicker animated:YES completion:nil];

    }];

    UIAlertAction * document = [UIAlertAction actionWithTitle:@"Choose a document" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        NSLog(@"Document");
        NSArray *types = @[(NSString*)kUTTypeImage,
                           (NSString*)kUTTypeSpreadsheet,
                           (NSString*)kUTTypePresentation,
                           (NSString*)kUTTypeDatabase,
                           (NSString*)kUTTypeFolder,
                           (NSString*)kUTTypeZipArchive,
                           (NSString*)kUTTypeVideo,
                           (NSString*)kUTTypePDF,
                           (NSString*)kUTTypeMovie,
                           (NSString*)kUTTypeAudio,
                           (NSString*)kUTTypeMPEG,
                           (NSString*)kUTTypeMPEG2Video,
                           (NSString*)kUTTypeMP3,
                           (NSString*)kUTTypeMPEG4,
                           (NSString*)kUTTypeMPEG4Audio,
                           (NSString*)kUTTypeJPEG,
                           (NSString*)kUTTypePNG,
                           (NSString*)kUTTypeGIF,
                           (NSString*)kUTTypeRTFD,
                           (NSString*)kUTTypeWebArchive,
                           (NSString*)kUTTypeText,
                           (NSString*)kUTTypePlainText,
                           (NSString*)kUTTypeRTF];
        //Create a object of document picker view and set the mode to Import
        UIDocumentPickerViewController *docPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:types inMode:UIDocumentPickerModeImport];
        //Set the delegate
        docPicker.delegate = self;
        //present the document picker
        [self presentViewController:docPicker animated:YES completion:nil];
    }];

    UIAlertAction * cancel = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        NSLog(@"Cancelled");
    }];


    [actionSheet addAction:camera];
    [actionSheet addAction:gallery];
    [actionSheet addAction:document];
    [actionSheet addAction:cancel];

    //For iPad a PopOverViewController is needed
    UIPopoverPresentationController * popoverController = actionSheet.popoverPresentationController;
    actionSheet.modalPresentationStyle = UIModalPresentationPopover;
    popoverController.sourceView = self.view;
    popoverController.sourceRect =  CGRectMake(self.view.bounds.size.width/2, self.view.bounds.size.height/2, 0, 0);
    popoverController.permittedArrowDirections = 0;
    popoverController.delegate = self;

    [self presentViewController:actionSheet animated:true completion:nil];
}
#pragma mark - Image Picker Delegate

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
{
    NSLog(@"Image picked");
    NSLog(@"%@",info);


    if (picker.sourceType == UIImagePickerControllerSourceTypePhotoLibrary)
    {
//        NSData * data = UIImageJPEGRepresentation([info valueForKey:@"UIImagePickerControllerOriginalImage"], 0.5);
//
//        NSString * path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/image.JPEG"];
//        [data writeToFile:path atomically:true];

    }
    else
    {
        UIImageWriteToSavedPhotosAlbum([info valueForKey:@"UIImagePickerControllerOriginalImage"], nil, nil, nil);
    }

    UIImageView * imgView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 50, 50)];
    imgView.contentMode = UIViewContentModeScaleAspectFit;
    imgView.image = [info valueForKey:@"UIImagePickerControllerOriginalImage"];

    /* //Works in simulator, iOS 10+, iPhone
    NSURL * fileurl = [info valueForKey:@"UIImagePickerControllerImageURL"];
    NSMutableString * filepath = [NSMutableString stringWithFormat:@"%@",fileurl];
    [filepath replaceOccurrencesOfString:@"file://" withString:@"" options:0 range:NSMakeRange(0, filepath.length)];
    */
    NSURL *refURL = [info valueForKey:UIImagePickerControllerReferenceURL];
    PHFetchResult *result = [PHAsset fetchAssetsWithALAssetURLs:@[refURL] options:nil];
    PHAsset *asset = [result firstObject];
    [[PHImageManager defaultManager] requestImageDataForAsset:asset options:nil resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
        UIImage* newImage = [UIImage imageWithData:imageData];
        imgView.image = newImage;
    }];
    NSMutableString * __block filepath = nil;
    NSString __block *filename = [[result firstObject] filename];


    [result enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        PHAsset *asset = (PHAsset *)obj;
        [asset requestContentEditingInputWithOptions:nil completionHandler:^(PHContentEditingInput * _Nullable contentEditingInput, NSDictionary * _Nonnull info) {
            NSLog(@"URL:%@",  contentEditingInput.fullSizeImageURL.absoluteString);
            //file:///var/mobile/Media/PhotoData/CPLAssets/group125/0888AEED-48C6-4E6E-93AB-CE99A6E706AF.JPG
            NSString* path = [contentEditingInput.fullSizeImageURL.absoluteString substringFromIndex:7];//screw all the crap of file://
            NSFileManager *fileManager = [NSFileManager defaultManager];
            BOOL isExist = [fileManager fileExistsAtPath:path];
            if (isExist)
                filepath = [path mutableCopy];

            else {
                NSLog(@"damn");
            }
        }];
    }];

    UIAlertController *alertController = [UIAlertController
                                          alertControllerWithTitle:@"UIImagePicker"
                                          message:@"Image picked"
                                          preferredStyle:UIAlertControllerStyleAlert];
    [alertController.view addSubview:imgView];


    [alertController addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        [self uploadImage:imgView.image withPath:filepath andName:filename];// works perfectly if provided with proper filepath
    }]];


    [self dismissViewControllerAnimated:true completion:nil];
    [self presentViewController:alertController animated:YES completion:nil];





}
@end

I only wish to know where am I going wrong. Is file:///var/mobile/Media/PhotoData/CPLAssets/group125/0888AEED-48C6-4E6E-93AB-CE99A6E706AF.JPG the proper filepath?

您不必将本地图像 URL 传递到服务器。请查看以下示例 Swift 代码。希望您能够将其转换为 objective-c

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {

    if let chosenImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
        let imageData = UIImageJPEGRepresentation(chosenImage,0.5)
        var imageFileName = "default_name.jpg"
        if let imageUrl = info["UIImagePickerControllerImageURL"] as? URL {
            imageFileName = imageUrl.absoluteURL.lastPathComponent
        }
        //
        // Now pass imageData and imageFileName to the server

        //
    } else {
        print("Error while fetching image")
    }
    dismiss(animated:true, completion: nil)
}

PHP脚本只需要数据格式和文件名中的图像以及您要提供的文件。只需命名一个文件,您可以保留对您的系统有意义的任何内容。

无需提供文件路径,因为您已经以二进制形式提供了图像。所以你应该重新实现你的 uploadImage: 方法来只接收数据和文件名。