Soru Bir PHAsset'in iCloud'dan tam olarak indirilememesi nasıl belirlenir (bu yüzden options.networkAccessAllowed ile tekrar talep etmem gerekir)


Dokümanlar şöyle diyor:

PHImageResultIsInCloudKey:   Fotoğraf varlık verilerinin yerel cihazda mı saklandığını veya iCloud'dan indirilip indirilmeyeceğini belirten bir Boole değeri. (NSNumber)   EVET ise, resim sağlanmamıştır, çünkü varlık verileri iCloud'dan indirilmelidir. Verileri indirmek için başka bir istek gönderin ve networkAccessAllowed seçeneği için EVET seçeneğini belirtin.

Ancak bu anahtar her zaman, bir cihaza iCloud Photo Library'de depolandığında, cihazda zaten tamamen indirilmiş olsa bile (app uygulamasında indirildiyse de, Fotoğraflar uygulamasında da açılmıştır) EVET'dir.

Bir resim mevcut değilse, kullanıcıya onu indirme olanağı vermek istiyorum (ancak en azından Wifi yokken otomatik olarak yapmayın).

Resmin indirilmesi gerekip gerekmediğini nasıl anlarım?

Daha da meraklı: Sonuç blokum requestImageForAsset:targetSize:contentMode:options:resultHandler: indirilmesi gereken bir görüntü için çağrılır, daha küçük ve bozulmuş bir sürüm teslim edildikten sonra requestedImage == nil ile son bir çağrı alırım.

Bu durumda indirgenemiyorum, görüntü yok ve görüntü hala iCloud'dan indirilmeli, çünkü Fotoğraflar uygulamasından sadece küçük bir küçük resim yerel olarak kullanılabilir.

Bunu iPhone ve iPad'lerde farklı iOS 8 sürümleriyle (8.1.x, 8.2 beta, 8.3 beta) test ettim, davranış her zaman aynı.

Fotoğrafı Fotoğraflar uygulamasında açtıktan sonra, sonuç işleyicisinin son çağrısı tam boyutlu görüntüye sahip olur, ancak PHImageResultIsInCloudKey hala YES olacaktır.

İşte bazı kodları resimlerden nasıl talep ediyorum:

PHImageRequestOptions *options = [[PHImageRequestOptions alloc]init];
options.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
options.networkAccessAllowed = NO;

[self.imageManager requestImageForAsset:asset targetSize:size contentMode:PHImageContentModeAspectFill options:options resultHandler:^(UIImage *requestedImage, NSDictionary *info) {
    // Checking for requestedImage and the info keys here
    // When a full sized image was loaded, the result of PHImageResultIsInCloudKey is still YES
    // When a full sized image couldn't be loaded cause it's in the cloud, isDegraded is NO and PHImageResultIsInCloudKey is YES (as always) and requestedImage is nil
}];

17
2018-02-12 16:10


Menşei




Cevaplar:


PHImageResultIsInCloudKey'nin güvenilir olmadığını doğrulayabilirim. İCloud'da saklanan görüntüler için, orijinal görüntü cihaza indirilmiş olsa bile 1 değerini döndürür. Bu davranış, belgelerin aksine ve radar.apple.com adresindeki bir hatayı bildirmenizi öneririm. Benim düşünceme göre PhotoKit hala çok olgunlaşmamış bir çerçevedir - pek çok konu ve bazı garip kavramsal kararlar içerir.


8
2018-02-13 12:24



Bunu doğruladığın için teşekkürler. Bu yüzden, "requireImage == nil" ifadesinin, öğenin indirilmesi gerektiğine dair bir ipucu olarak kontrol edilmesinin güvenli olup olmadığı konusunda daha fazla test yapacağım. Yukarıdaki alıntılanan dokümanlar, "hiçbir resim sağlanmamıştır, çünkü varlık verileri iCloud'dan indirilmelidir", en azından bu kısım doğrudur. ;) Ayrıca bir hata raporu da gönderecek. - Thyraz
Benim yorumumda, belgeler doğru ve bu davranış da doğru. Size yapmak istediğiniz her şeyi yapmak için ihtiyacınız olan tüm verileri verir: UIImage ve bilgi. Resmi aldınız ve bozulmuyorsa, bu görüntü iCloud'da veya sizde değilse sizin için önemli değil. Olabilir! Ayrıca, 1 döndürdüğünde doğru, çünkü API, size indirmeyi bitirmiş ve bu yöntemde size vermiş olsa bile, görüntü gerçekten iCloud'dadır. - Velociround


Ararsan requestImageDataForAsset: ile networkAccessAllowed ayarlanır NO, geri döndü imageData olacak nil klip iCloud'dan henüz indirilmemişse. Aksi halde, klip iCloud'da saklanmasına rağmen gerçek verileri döndürür.

PHImageManager *manager = [PHImageManager defaultManager];    
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
options.networkAccessAllowed = NO;
[manager
 requestImageDataForAsset:asset
 options:options
 resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
    if ([[info valueForKey:PHImageResultIsInCloudKey] boolValue]) {
    // Image is in iCloud
        if (imageData) {
            // Image is downloaded
        } else {
            // Image is not downloaded
        }
    }
 }];

12
2018-01-22 01:37



Öncelikle imageData'yi kontrol etmemizi ve görüntü verilerinin sıfır olması durumunda iCloud'da görüntü olup olmadığını kontrol etmemizi ve görüntüyü iCloud'dan indirmemizi öneririz. - Robin Garg


PHAsset'in iCloud'dan olup olmadığını kontrol etmek için progressHandler'ı kullanabilirsiniz.

__block BOOL isPhotoInICloud = NO;
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
options.progressHandler = ^(double progress, NSError *error, BOOL *stop, NSDictionary *info){

    isPhotoInICloud = YES;
    // some code to update the download progress
});
options.networkAccessAllowed = YES;
options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
options.synchronous = NO;

[[PHImageManager defaultManager] requestImageForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeAspectFit options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
// use the options to get the high quality image for only once time.
});

1
2017-11-01 01:41



Başka bir bağlantı yararlı olabilir: stackoverflow.com/questions/31966571/... - Chris Forever


Bir PHAsset'in hala bulutta olup olmadığını kontrol etmenin en iyi yolu, networkAccessAllowed = NO ile PHImageManager üzerinden denemek ve erişmektir. Eğer görüntü / öğe almazsanız, o zaman hala bulutta olduğunu bilirsiniz (ve o kazandı indirilemedi:

    + (void)checkCloudStatusForPHAsset:(PHAsset*)phAsset completion:(void (^)(BOOL isInCloud))completionBlock
{
    if (phAsset) {
        if (phAsset.mediaType == PHAssetMediaTypeVideo) {
            PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];
            options.version = PHVideoRequestOptionsVersionOriginal;
            options.deliveryMode = PHVideoRequestOptionsDeliveryModeHighQualityFormat;
            options.networkAccessAllowed = NO;
            [[PHImageManager defaultManager] requestAVAssetForVideo:phAsset options:options resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
                completionBlock(asset == nil);
            }];
        }
        else if (phAsset.mediaType == PHAssetMediaTypeImage) {
            PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
            options.version = PHImageRequestOptionsVersionOriginal;
            options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
            options.resizeMode = PHImageRequestOptionsResizeModeNone;
            options.networkAccessAllowed = NO;
            [[PHImageManager defaultManager] requestImageDataForAsset:phAsset options:options resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
                completionBlock(imageData == nil);
            }];
        }
        else {
            completionBlock(NO);
        }
    }
    else {
        completionBlock(NO);
    }
}

0
2018-06-14 14:06