2015-06-24 8 views
30

के लिए शून्य का रिटर्न देता है PHImageManager.defaultManager() का लगभग 10%। अनुरोध ImageForAsset वैध "Ugrmage" के बाद वैध वैध लौटने के बाद वैध UIImage के बजाय शून्य देता है। कोई त्रुटि या अन्य सुराग जो मैं देख सकता हूं वह शून्य के साथ जानकारी में वापस आ गया है।PHImageManager requestImageForAsset कभी-कभी iCloud फ़ोटो

ऐसा लगता है कि iCloud से डाउनलोड करने की आवश्यकता है, iCloud फोटो लाइब्रेरी और अनुकूलित आईपैड स्टोरेज दोनों सक्षम हैं। मैंने विकल्प, आकार इत्यादि को बदलने की कोशिश की है लेकिन कुछ भी मायने नहीं रखता है।

यदि मैं विफलता के बाद अनुरोध ImageForAsset को फिर से प्रयास करता हूं तो यह आमतौर पर यूआईएममेज को सही ढंग से वापस कर देगा, हालांकि कभी-कभी इसे दो रिट्रीज़ की आवश्यकता होती है।

कोई विचार क्या मैं गलत कर रहा हूं? या यह सिर्फ फोटो ढांचे में एक बग है?

func photoImage(asset: PHAsset, size: CGSize, contentMode: UIViewContentMode, completionBlock:(image: UIImage, isPlaceholder: Bool) -> Void) -> PHImageRequestID? { 

    let options = PHImageRequestOptions() 
    options.networkAccessAllowed = true 
    options.version = .Current 
    options.deliveryMode = .Opportunistic 
    options.resizeMode = .Fast 

    let requestSize = !CGSizeEqualToSize(size, CGSizeZero) ? size : PHImageManagerMaximumSize 
    let requestContentMode = contentMode == .ScaleAspectFit ? PHImageContentMode.AspectFit : PHImageContentMode.AspectFill 

    return PHImageManager.defaultManager().requestImageForAsset(asset, targetSize: requestSize, contentMode: requestContentMode, options: options) 
     { (image: UIImage!, info: [NSObject : AnyObject]!) in 
      if let image = image { 
       let degraded = info[PHImageResultIsDegradedKey] as? Bool ?? false 
       completionBlock(image: photoBlock.rotatedImage(image), isPlaceholder: degraded) 

      } else { 
       let error = info[PHImageErrorKey] as? NSError 
       NSLog("Nil image error = \(error?.localizedDescription)") 
      } 
    } 
} 
+0

पर एक नज़र डालें, मुझे बिल्कुल वही समस्या है, क्या आपको इसके लिए कोई समाधान मिला? – dlinsin

+1

मुझे एक ही समस्या दिखाई दे रही है। मुझे विश्वास है कि यह एक बग है और एक बग रिपोर्ट दायर की है। – Joey

+3

मैं यह देख रहा हूं जब मैं 'options.deliveryMode =HighQualityFormat' सेट करता हूं लेकिन जब मैं' options.deliveryMode =Opportunistic' –

उत्तर

18

मैं बस इसके माध्यम से भी चला गया। मेरी परीक्षण मुद्दा करके उपकरणों कि "अनुकूलन संग्रहण" विकल्प सक्षम है पर दिखाई देता है और bellow दो विधियों के बीच अंतर में रहता है:

[[PHImageManager defaultManager] requestImageForAsset: ...]

यदि आपके विकल्प सही तरीके से कॉन्फ़िगर किए गए हैं तो यह दूरस्थ iCloud छवियों को सफलतापूर्वक लाएगा।


[[PHImageManager defaultManager] requestImageDataForAsset: ...]

यह फ़ंक्शन केवल छवियों कि फोन स्मृति पर रहते हैं या कि किसी अन्य एक पर अपने एप्लिकेशन द्वारा हाल ही में iCloud से प्राप्त किए गए थे के लिए काम करता ।


यहाँ एक काम टुकड़ा मैं मेरे साथ -bear उपयोग कर रहा हूँ है Obj सी :)

PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init]; 
options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat; //I only want the highest possible quality 
options.synchronous = NO; 
options.networkAccessAllowed = YES; 
options.progressHandler = ^(double progress, NSError *error, BOOL *stop, NSDictionary *info) { 
     NSLog(@"%f", progress); //follow progress + update progress bar 
    }; 

    [[PHImageManager defaultManager] requestImageForAsset:myPhAsset targetSize:self.view.frame.size contentMode:PHImageContentModeAspectFill options:options resultHandler:^(UIImage *image, NSDictionary *info) { 
     NSLog(@"reponse %@", info); 
     NSLog(@"got image %f %f", image.size.width, image.size.height); 
    }]; 

Full gist available on github

स्विफ्ट 3 के लिए अपडेट किया गया:

let options = PHImageRequestOptions() 
    options.deliveryMode = PHImageRequestOptionsDeliveryMode.highQualityFormat 
    options.isSynchronous = false 
    options.isNetworkAccessAllowed = true 

    options.progressHandler = { (progress, error, stop, info) in 
     print("progress: \(progress)") 
    } 

    PHImageManager.default().requestImage(for: myPHAsset, targetSize: view.frame.size, contentMode: PHImageContentMode.aspectFill, options: options, resultHandler: { 
    (image, info) in 
     print("dict: \(String(describing: info))") 
     print("image size: \(String(describing: image?.size))") 
    }) 
+4

मुझे वास्तव में समझ में नहीं आता कि यह कैसा माना जाता है मूल समस्या को हल करने के लिए? – dlinsin

+1

मैं डिनिन्सिन से सहमत हूं, यह वही दिखता है जो मैं कर रहा हूं और यह अभी भी नियमित रूप से विफल रहता है। – LenK

+1

मैं इसका उपयोग कर रहा हूं और कभी असफल नहीं हुआ। यह ढांचे में भी एक बग हो सकता है क्योंकि यह अभी भी अस्थिर है। – ahbou

1

(400, 400) से अधिक लक्ष्य आकार का उपयोग करने का प्रयास करें। इससे मेरी मदद मिली।

1

मुझे पता चला कि इसका नेटवर्क या आईक्लाउड से कोई लेना देना नहीं था। यह कभी-कभी उन छवियों पर असफल रहा, जो पूरी तरह से स्थानीय थे। कभी-कभी यह मेरे कैमरे से छवियां थी, कभी-कभी यह वेब से सहेजी गई छवियों से होगी।

मुझे कोई फिक्स नहीं मिला, लेकिन @Nadzeya द्वारा प्रेरित एक काम जो मेरे लिए 100% समय काम करता था हमेशा संपत्ति आकार के बराबर लक्ष्य आकार का अनुरोध करने के लिए था।

ईजी।

PHCachingImageManager().requestImage(for: asset, 
           targetSize: CGSize(width: asset.pixelWidth, height: asset.pixelHeight) , 
          contentMode: .aspectFit, 
           options: options, 
          resultHandler: { (image, info) in 
     if (image == nil) { 
      print("Error loading image") 
      print("\(info)") 
     } else { 
      view.image = image 
     } 
    }); 

मेरा मानना ​​है कि यह करने के लिए कमियां होगा कि हम स्मृति में वापस पूर्ण छवि हो रही है, और फिर स्केलिंग ऐसा करने के लिए मजबूर कर रहा imageView, लेकिन कम से कम अपने प्रयोग के मामले में, वहाँ एक नहीं था ध्यान देने योग्य प्रदर्शन मुद्दा, और यह एक धुंधला या शून्य छवि लोड करने से काफी बेहतर था।

एक संभावित अनुकूलन यहां छवि के पुन: अनुरोध करने के लिए है, अगर छवि शून्य के रूप में वापस आती है।

0

क्या यह काम मुझे PHImageManager तुल्यकालिक संपत्ति डेटा लोड हो रहा दे रहा था के लिए, लेकिन एक अतुल्यकालिक पृष्ठभूमि धागे से। सरलीकृत यह इस तरह दिखता है:

DispatchQueue.global(qos: .userInitiated).async { 
     let requestOptions = PHImageRequestOptions() 
     requestOptions.isNetworkAccessAllowed = true 
     requestOptions.version = .current 
     requestOptions.deliveryMode = .opportunistic 
     requestOptions.isSynchronous = true 
     PHImageManager.default().requestImage(for: asset, targetSize: size, contentMode: .aspectFit, options: requestOptions) { image, _ in 
      DispatchQueue.main.async { /* do something with the image */ } 
     } 
    } 
0

मैं बहुत सी बातें

  • की कोशिश की है targetSize से अधिक (400, 400): काम नहीं
  • targetSize संपत्ति के आकार के बराबर है: काम नहीं
  • सेटिंग्स में iCloud फ़ोटो में Optimize Storage अक्षम करें: काम नहीं
  • पृष्ठभूमि कतार में requestImage डिस्पैच करें:
  • पर काम न करें 0
  • उपयोग PHImageManagerMaximumSize: काम नहीं
  • उपयोग isNetworkAccessAllowed: PHImageRequestOptions में विभिन्न मूल्यों के साथ
  • प्ले काम नहीं, version की तरह, deliveryMode, resizeMode: काम नहीं
  • जोड़ें progressHandler: फिर
  • कॉल requestImage काम यह नहीं मामले विफल रहे: काम नहीं

मुझे लगता है कि मैं UIImage औरके साथ जानकारी प्राप्त करता हूं, की तरह इस रडार में Photos Frameworks returns no error or image for particular assets

उपयोग पहलू फिट

मेरे लिए क्या काम करते हैं, https://github.com/hyperoslo/Gallery/blob/master/Sources/Images/Image.swift#L34

  • देख उपयोग targetSize < 200 के साथ: यही कारण है कि मैं थंबनेल लोड कर सकते हैं
  • aspectFit का उपयोग करें: contentMode पर निर्दिष्ट करें मेरे लिए चाल है

यहाँ कोड

let options = PHImageRequestOptions() 
options.isSynchronous = true 
options.isNetworkAccessAllowed = true 

var result: UIImage? = nil 

PHImageManager.default().requestImage(
    for: asset, 
    targetSize: size, 
    contentMode: .aspectFit, 
    options: options) { (image, _) in 
    result = image 
} 

return result 

लायें है एसिंक्रोनस रूप

ऊपर रेस स्थिति का कारण हो सकता है, तो सुनिश्चित करें कि आप एसिंक्रोनस रूप से लाने, जो कोई isSynchronous मतलब है बनाते हैं। https://github.com/hyperoslo/Gallery/pull/72

संबंधित मुद्दे