2017-05-04 113 views
9

Zdobądź ogromną nagrodę za to pozornie łatwe pytanie, które nie ma znaczenia.Pobierz nazwę pliku obrazu zapisanego na albumie zdjęć

W nowoczesnych iOS (2017),

tutaj rzeczywiście jedynym sposobem wiem aby zapisać obraz na zdjęciach systemem iOS i uzyskać nazwy pliku/ścieżki.

import UIKit 
import Photos 

func saveTheImage...() { 

    UIImageWriteToSavedPhotosAlbum(yourUIImage, self, 
     #selector(Images.image(_:didFinishSavingWithError:contextInfo:)), 
     nil) 
} 

func image(_ image: UIImage, didFinishSavingWithError error: NSError?, contextInfo: UnsafeRawPointer) { 
    guard error == nil else { 
     print("Couldn't save the image!") 
     return 
    } 
    doGetFileName() 
} 

func doGetFileName() { 
    let fo: PHFetchOptions = PHFetchOptions() 
    fo.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)] 
    let r = PHAsset.fetchAssets(with: PHAssetMediaType.image, options: fo) 
    if let mostRecentThingy = r.firstObject { 

     PHImageManager.default().requestImageData(
      for: mostRecentThingy, 
      options: PHImageRequestOptions(), 
      resultHandler: { (imagedata, dataUTI, orientation, info) in 

       if info!.keys.contains("PHImageFileURLKey") { 
        let path = info!["PHImageFileURLKey"] as! NSURL 

        print("Holy cow. The path is \(path)") 
       } 
       else { print("bizarre problem") } 
      }) 

    } 
    else { print("unimaginable catastrophe") } 
} 

Istnieją dwa problemy z tym:

1. WTH?!?

2. Nie działa w warunkach wyścigu.

Jest to niezwykle nieporęczne i na wiele sposobów wygląda na nieprzyjemne.

Czy to jest naprawdę droga, dzisiaj?

+0

Czy naprawdę potrzebujesz adresu URL? Czy mógłbyś również użyć właściwości 'localIdentifier' powiązanego' PHObject'? –

Odpowiedz

1
extension PHPhotoLibrary { 

    func save(imageData: Data, withLocation location: CLLocation?) -> Promise<PHAsset> { 
     var placeholder: PHObjectPlaceholder! 
     return Promise { fullfil, reject in 
      performChanges({ 
       let request = PHAssetCreationRequest.forAsset() 
       request.addResource(with: .photo, data: imageData, options: .none) 
       request.location = location 
       placeholder = request.placeholderForCreatedAsset 
      }, completionHandler: { (success, error) -> Void in 
       if let error = error { 
        reject(error) 
        return 
       } 

       guard let asset = PHAsset.fetchAssets(withLocalIdentifiers: [placeholder.localIdentifier], options: .none).firstObject else { 
        reject(NSError()) 
        return 
       } 

       fullfil(asset) 
      }) 
     } 
    } 
} 

myślę, że można to zrobić z PHPhotoLibrary i PHObjectPlaceholder.

+0

PHPhotoLibrary ... co do diabła, nawet nie słyszałem o tym !! – Fattie

+0

https://developer.apple.com/reference/photos/phphotolibrary Dokument ten można znaleźć tutaj. –

+0

Dla przyszłych googlersów, wierzę **, ale nie jestem pewien ** to jest poprawna nowoczesna odpowiedź. – Fattie

2

Wystarczy zapisać obraz programowo, dzięki czemu można uzyskać obraz z kamery i zapisać go z drogi:

//save image in Document Derectory 
     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES); 
     NSString *documentsDirectory = [paths objectAtIndex:0]; 
     NSLog(@"Get Path : %@",documentsDirectory); 

     //create Folder if Not Exist 
     NSError *error = nil; 
     NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:@"/YourFolder"]; 

     if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath]) 
     [[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:&error]; //Create folder 

     NSString *[email protected]"YourPhotoName"; 
     NSString* path= [dataPath stringByAppendingString:[NSString stringWithFormat:@"/%@.png",yourPhotoName]]; 
     NSData* imageData = UIImagePNGRepresentation(imageToSaved); //which got from camera 

     [imageData writeToFile:path atomically:YES]; 

     imagePath = path; 
     NSLog(@"Save Image Path : %@",imagePath); 
+0

Witaj Dong, próbuję odkryć ścieżkę *** jeśli jest w systemie albumów ze zdjęciami Apple *** – Fattie

+0

@Fattie: Próbowałem z symulatorem z tym kodem: ============= = - (void) imagePickerController: (UIImagePickerController *) picker didFinishPickingMediaWithInfo: (NSDictionary *) info { NSURL * localUrl = (NSURL *) [info valueForKey: UIImagePickerControllerReferenceURL]; NSLog (@ "image url% @", localUrl.absoluteString); } ====== i otrzymałem coś w rodzaju: plik obrazu url - biblioteka: //asset/asset.JPG? Id = ED7AC36B-A150-4C38-BB8C-B6D696F4F2ED & ext = JPG Powiedz, czy potrzebujesz. ^^ –

0

Może to jest inne podejście, ale tutaj jest to, co robię w mojej aplikacji i I jestem z niego zadowolony:

func saveImage(image: UIImage, name: String) { 

    var metadata = [AnyHashable : Any]() 
    let iptcKey = kCGImagePropertyIPTCDictionary as String 
    var iptcMetadata = [AnyHashable : Any]() 

    iptcMetadata[kCGImagePropertyIPTCObjectName as String] = name 
    metadata[iptcKey] = iptcMetadata 

    let library = ALAssetsLibrary() 

    library.writeImage(toSavedPhotosAlbum: image.cgImage, metadata: metadata) { url, error in 

     // etc... 
    } 
} 

Jeśli nie chcesz używać ALAssetsLibrary, będziesz prawdopodobnie zainteresowany this answer.

Powiązane problemy