2017-11-19 9 views
0

URLのUIImageを使ってトップバーにUIImageViewを表示し、それをiOSネイティブのXamarin iOSアプリにキャッシュしたいとします。問題は、ViewWillAppearにFFImageLoadingログを追加すると、イメージが10回中に約9回キャンセルされることが示されますが、時には成功して表示されることがあります。私は以下を使用します:ViewWillAppearでFFImageLoadingを使用するには?

これは、最初の試行で成功するか、すべての試行が失敗します(私はまた、成功していない長い試行遅延で試しました)。 ViewDidAppearにコードを置くと、10回中に9回動作しますが、必ずしも最初の負荷ではないことはありません。ビューをロードした後にプッシュボタンに入れると、イメージは常に正常にロードされます。だから、UIImageViewがまだ描画されていない/ロードされていないので、FFImageLoadingが失敗しているのはかなり明らかですが、UIImageViewを作成してビューに追加したので、もっと何ができるのか分かりません。

にはどうすれば確実に画像をロードするためにFFImageLoadingを使用することができますか?私はそれを事前にロードすることができますが、それはUIImageViewに最初に表示される前にそれを取得する方法はまだ解決しません。 FFImageLoadingで不可能な場合は、私は代替案を公開しています。

ログ:(数回をリロードした後、同じページを)成功:

[0:] FFImageLoadingDebug_SimpleDiskCache path: /var/mobile/Containers/Data/Application/93D1FA0C-B19A-4ECA-A0DA-B0AC408A5B8E/Library/Caches/FFSimpleDiskCache 
Thread started: <Thread Pool> #3 
Thread started: <Thread Pool> #4 
Thread started: <Thread Pool> #5 
Thread started: <Thread Pool> #6 
Thread started: #7 
Thread started: <Thread Pool> #8 
Thread started: <Thread Pool> #9 
Thread started: #10 
Thread started: #11 
Thread started: <Thread Pool> #12 
Thread started: <Thread Pool> #13 
[0:] FFImageLoadingDebug_Image memory cache size: 401,5 MB 
[0:] FFImageLoadingDebug_Image loading cancelled: https://assets-cdn.github.com/images/modules/logos_page/Octocat.png;CircleTransformation,borderSize=0,borderHexColor= 
[0:] FFImageLoadingDebug_Generating/retrieving image: https://assets-cdn.github.com/images/modules/logos_page/Octocat.png;CircleTransformation,borderSize=0,borderHexColor= 
[0:] FFImageLoadingDebug_Wait for similar request for key: https://autodesk-forge.github.io/dist/sample.png?43fa010fd5f9a49ec978f5dec499349d 
[0:] FFImageLoadingDebug_Wait for similar request for key: https://autodesk-forge.github.io/dist/sample.png?43fa010fd5f9a49ec978f5dec499349d 
[0:] FFImageLoadingDebug_Wait for similar request for key: https://autodesk-forge.github.io/dist/sample.png?43fa010fd5f9a49ec978f5dec499349d 
[0:] FFImageLoadingDebug_Generating/retrieving image: https://autodesk-forge.github.io/dist/sample.png?43fa010fd5f9a49ec978f5dec499349d 
Thread started: #14 
[0:] FFImageLoadingDebug_Wait for similar request for key: https://autodesk-forge.github.io/dist/sample.png?43fa010fd5f9a49ec978f5dec499349d 
[0:] FFImageLoadingDebug_Image loading cancelled: https://assets-cdn.github.com/images/modules/logos_page/Octocat.png;CircleTransformation,borderSize=0,borderHexColor= 
[0:] FFImageLoadingDebug_File /var/mobile/Containers/Data/Application/93D1FA0C-B19A-4ECA-A0DA-B0AC408A5B8E/Library/Caches/FFSimpleDiskCache/CD275DFA133499968568338D6D522382.864000 saved to disk cache for key CD275DFA133499968568338D6D522382 
[0:] FFImageLoadingDebug_Image loaded from cache: https://autodesk-forge.github.io/dist/sample.png?43fa010fd5f9a49ec978f5dec499349d 
etc. 

ログイン:UIImageViewにロードに失敗し

[0:] FFImageLoadingDebug_Image loaded from cache: https://assets-cdn.github.com/images/modules/logos_page/Octocat.png;CircleTransformation,borderSize=0,borderHexColor= 
[0:] FFImageLoadingDebug_Image loaded from cache: https://autodesk-forge.github.io/dist/sample.png?43fa010fd5f9a49ec978f5dec499349d 
etc. 

答えて

0

私も携帯がを接続しているかどうかを確認するためにCrossConnectivityを使用)私はFFImageLoadingがキャンセルされます理由を把握できていないので、代わりに私は自分自身をロールバックするAkavacheを使用してHttpClientを。

これはViewWillAppearから更新するたびに動作します。 IObservableを使用しているため、メインのUIスレッドで画像を更新することが重要です(InvokeOnMainThread)。 URLから画像をロードすることができるのUIViewを追加するために使用

UrlImageViewクラス:

public class UrlImageView : UIImageView 
    { 
     private GetImageFromUrlObserver getImageFromUrlObserver = null; 

     public UrlImageView() : base() 
     { 
      getImageFromUrlObserver = new GetImageFromUrlObserver(this); 
     } 

     public void GetImageFromUrl(string url) 
     { 
      if (getImageFromUrlObserver != null) 
      { 
       getImageFromUrlObserver.GetImage(url); 
      } 
     } 

     public void Update(byte[] image) 
     { 
      this.InvokeOnMainThread(() => 
      { 
       var data = NSData.FromArray(image); 
       this.Image = UIImage.LoadFromData(data); 
      });    
     } 
    } 

IObserverクラス(画像データが取得されるとき、それはOnNextをトリガする)

public class GetImageFromUrlObserver : IObserver<byte[]> 
    { 
     private UrlImageView urlImageView; 
     private IDisposable unsubscriber; 

     public GetImageFromUrlObserver(UrlImageView view) 
     { 
      urlImageView = view; 
     } 

     public void GetImage(string url) 
     { 
      Subscribe(ImageLoader.GetImageFromUrl(url)); 
     } 

     private void Subscribe(IObservable<byte[]> provider) 
     { 
      if (provider != null) 
       unsubscriber = provider.Subscribe(this); 
     } 

     public void OnCompleted() 
     { 
      Unsubscribe(); 
     } 

     public void OnError(Exception error) 
     { 
      throw new NotImplementedException(); 
     } 

     public void OnNext(byte[] image) 
     {  
      if (urlImageView != null) 
      { 
       urlImageView.Update(image); 
      } 
     } 

     private void Unsubscribe() 
     { 
      if (unsubscriber != null) 
      { 
       urlImageView = null; 
       unsubscriber.Dispose(); 
       unsubscriber = null; 
      }    
     } 
    } 

イメージデータを取得するHttpClientクラス

public static class ImageLoader 
{ 
     public static IObservable<byte[]> GetImageFromUrl(string url) 
     { 
      IObservable<byte[]> result = null; 
      var httpClient = new HttpClient(new NativeMessageHandler()); 
     }); 

     try 
      { 
        var cache = BlobCache.LocalMachine; 
        result = cache.GetAndFetchLatest(
        url, /* simply use url as cache key */ 
        async() => 
        { 
         try 
         { 
          if (!CrossConnectivity.Current.IsConnected) return null; 
          HttpResponseMessage httpResponse = await httpClient.GetAsync(url); 
          return await httpResponse.Content.ReadAsByteArrayAsync().ConfigureAwait(false); ; 
         } 
         catch (Exception e) 
         { 
          EventTrackers.TrackException("GetImageFromUrl inner - " + e.Message); 
          return null; 
         } 
        }, 
        offset => 
        { 
         TimeSpan elapsed = DateTimeOffset.Now - offset;        
         return elapsed > new TimeSpan(hours: cacheUpdateFrequencyHours, minutes: cacheUpdateFrequencyMinutes, seconds: 0); 
        } 
       ); 

      } 
      catch (Exception e) 
      { 
       EventTrackers.TrackException("GetImageFromUrl - " + e.Message); 
       return null; 
      } 

      return result; 
} 

あなたは呼び出す画像を表示するには:

UrlImageView image = new UrlImageView(); 
View.AddSubview(image); 
image.GetImageFromUrl(url); 
1

official sampleを参照してください。それは役に立つかもしれません。

var taskImage = ImageService.Instance.LoadUrl(imageURL) 
            .ErrorPlaceholder("error.png", ImageSource.ApplicationBundle) 
            .LoadingPlaceholder("placeholder", ImageSource.CompiledResource); 
if(transformation==0) 
{ 
    taskImage.Into(imageView); 
    transformation++; 
} 
else if(transformation==1) 
{ 
    taskImage.Transform(new CircleTransformation()).Into(imageView); 
    transformation++; 
} 
else if(transformation==2) 
{ 
    taskImage.Transform(new RoundedTransformation(10)).Into(imageView); 
    transformation = 0; 
} 
+0

おかげで、私は長い時間のためにそれを見ていなかった、それは私がすべての権利をやっていることを確認し(私はにUIImageを設定するテストnullでも違いはありません)。だから私はさらに、画像がUIImageViewにロードされない理由を混乱させる。私は、それらが何かを明らかにするためにログを追加しました。他のすべてのFFImageLoadingイメージはちょうどうまく読み込まれていることに注意してください。 – Tarostar

+0

@Tarostar FFImageLoadingの代わりに[SDWebImage](https://components.xamarin.com/view/sdwebimage)を使用してください。 –

関連する問題