UIImagePickerController не может получить локальный URL изображения - PullRequest
0 голосов
/ 05 сентября 2018

Я пытаюсь загрузить изображение, выбрав его через UIImagePickerController и загрузив на сервер. Для этого мне нужен фактический локальный путь (URL) изображения. Поскольку я ориентируюсь на iOS 9.0 и выше, я использую Photos Framework. Я могу получить имя файла, а также URL-адрес из PHAsset. Я также проверяю, присутствует ли файл по этому URL-адресу, но когда я пытаюсь загрузить изображение, я не уверен, является ли это правильным URL-адресом для предоставления php-скрипту на сервере. Для сценария 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

Я только хочу знать, где я иду не так. Является Файл: ///var/mobile/Media/PhotoData/CPLAssets/group125/0888AEED-48C6-4E6E-93AB-CE99A6E706AF.JPG правильный путь к файлу?

Ответы [ 2 ]

0 голосов
/ 05 сентября 2018

PHP-скрипту требуется только изображение в форме данных и имя файла, которые вы хотите указать в файле. Это просто имя файла, и вы можете сохранить все, что имеет смысл для вашей системы.

Нет необходимости указывать путь к файлу, так как вы уже даете изображение в двоичном виде. Поэтому вы должны переопределить метод uploadImage: для получения только данных и имени файла.

0 голосов
/ 05 сентября 2018

Вам не нужно передавать локальный URL-адрес изображения на сервер. Посмотрите на следующий пример кода Swift. Надеюсь, вы сможете преобразовать его в target-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)
}
...