From 4138b05ac93f4786405f7e61ec72928c567f7fcf Mon Sep 17 00:00:00 2001 From: CMK Date: Wed, 7 Jul 2021 17:51:47 +0800 Subject: [PATCH] chore: using AlamofireImage instead of Nuke to fix fetch may blocked issue --- .../Diffiable/Section/StatusSection.swift | 46 +++++++------------ ...ontextMenuImagePreviewViewController.swift | 23 +++------- .../Container/MosaicImageViewContainer.swift | 4 +- Mastodon/Service/PhotoLibraryService.swift | 33 +++++++------ 4 files changed, 43 insertions(+), 63 deletions(-) diff --git a/Mastodon/Diffiable/Section/StatusSection.swift b/Mastodon/Diffiable/Section/StatusSection.swift index bcb462be..7b613dfd 100644 --- a/Mastodon/Diffiable/Section/StatusSection.swift +++ b/Mastodon/Diffiable/Section/StatusSection.swift @@ -11,7 +11,7 @@ import CoreDataStack import os.log import UIKit import AVKit -import Nuke +import AlamofireImage import MastodonMeta // import LinkPresentation @@ -639,44 +639,30 @@ extension StatusSection { } .store(in: &cell.disposeBag) - let isSingleMosaicLayout = mosaics.count == 1 - // set image - let imageSize = CGSize( - width: mosaic.imageViewSize.width * imageView.traitCollection.displayScale, - height: mosaic.imageViewSize.height * imageView.traitCollection.displayScale - ) - let url: URL? = { + let url: URL = { if UIDevice.current.userInterfaceIdiom == .phone { return meta.previewURL ?? meta.url } return meta.url }() - let request = ImageRequest( - url: url, - processors: [ - ImageProcessors.Resize( - size: imageSize, - unit: .pixels, - contentMode: isSingleMosaicLayout ? .aspectFill : .aspectFit, - crop: isSingleMosaicLayout - ) - ] - ) - let options = ImageLoadingOptions( - transition: .fadeIn(duration: 0.2) - ) - Nuke.loadImage( - with: request, - options: options, - into: imageView - ) { result in - switch result { - case .failure: - break + // let imageSize = CGSize( + // width: mosaic.imageViewSize.width * imageView.traitCollection.displayScale, + // height: mosaic.imageViewSize.height * imageView.traitCollection.displayScale + // ) + // let imageFilter = AspectScaledToFillSizeFilter(size: imageSize) + + imageView.af.setImage( + withURL: url, + placeholderImage: UIImage.placeholder(color: .systemFill), + imageTransition: .crossDissolve(0.2) + ) { response in + switch response.result { case .success: statusItemAttribute.isImageLoaded.value = true + case .failure: + break } } diff --git a/Mastodon/Scene/Share/ContextMenu/ImagePreview/ContextMenuImagePreviewViewController.swift b/Mastodon/Scene/Share/ContextMenu/ImagePreview/ContextMenuImagePreviewViewController.swift index 28b13e2f..fb2d282a 100644 --- a/Mastodon/Scene/Share/ContextMenu/ImagePreview/ContextMenuImagePreviewViewController.swift +++ b/Mastodon/Scene/Share/ContextMenu/ImagePreview/ContextMenuImagePreviewViewController.swift @@ -8,8 +8,6 @@ import func AVFoundation.AVMakeRect import UIKit import Combine -import Nuke -import FLAnimatedImage final class ContextMenuImagePreviewViewController: UIViewController { @@ -17,19 +15,13 @@ final class ContextMenuImagePreviewViewController: UIViewController { var viewModel: ContextMenuImagePreviewViewModel! - var imageTask: ImageTask? let imageView: UIImageView = { - let imageView = FLAnimatedImageView() + let imageView = UIImageView() imageView.contentMode = .scaleAspectFill imageView.layer.masksToBounds = true return imageView }() - deinit { - imageTask?.cancel() - imageTask = nil - } - } extension ContextMenuImagePreviewViewController { @@ -55,13 +47,12 @@ extension ContextMenuImagePreviewViewController { .sink { [weak self] url in guard let self = self else { return } guard let url = url else { return } - self.imageTask = Nuke.loadImage( - with: url, - options: ImageLoadingOptions( - placeholder: self.viewModel.thumbnail, - transition: .fadeIn(duration: 0.2) - ), - into: self.imageView + self.imageView.af.setImage( + withURL: url, + placeholderImage: self.viewModel.thumbnail, + imageTransition: .crossDissolve(0.2), + runImageTransitionIfCached: true, + completion: nil ) } .store(in: &disposeBag) diff --git a/Mastodon/Scene/Share/View/Container/MosaicImageViewContainer.swift b/Mastodon/Scene/Share/View/Container/MosaicImageViewContainer.swift index 62f61a38..8336e852 100644 --- a/Mastodon/Scene/Share/View/Container/MosaicImageViewContainer.swift +++ b/Mastodon/Scene/Share/View/Container/MosaicImageViewContainer.swift @@ -8,7 +8,6 @@ import os.log import func AVFoundation.AVMakeRect import UIKit -import Nuke protocol MosaicImageViewContainerPresentable: AnyObject { var mosaicImageViewContainer: MosaicImageViewContainer { get } @@ -95,7 +94,8 @@ extension MosaicImageViewContainer { func resetImageTask() { imageViews.forEach { imageView in - Nuke.cancelRequest(for: imageView) + imageView.af.cancelImageRequest() + imageView.image = nil } } diff --git a/Mastodon/Service/PhotoLibraryService.swift b/Mastodon/Service/PhotoLibraryService.swift index 32f7ea46..53e7529c 100644 --- a/Mastodon/Service/PhotoLibraryService.swift +++ b/Mastodon/Service/PhotoLibraryService.swift @@ -9,7 +9,7 @@ import os.log import UIKit import Combine import Photos -import Nuke +import AlamofireImage final class PhotoLibraryService: NSObject { @@ -49,26 +49,29 @@ extension PhotoLibraryService { let impactFeedbackGenerator = UIImpactFeedbackGenerator(style: .light) let notificationFeedbackGenerator = UINotificationFeedbackGenerator() - return ImagePipeline.shared.imagePublisher(with: url) - .handleEvents(receiveSubscription: { _ in - impactFeedbackGenerator.impactOccurred() - }, receiveCompletion: { completion in - switch completion { + return Future { promise in + ImageDownloader.default.download(URLRequest(url: url), completion: { response in + switch response.result { case .failure(let error): os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: download image %s fail: %s", ((#file as NSString).lastPathComponent), #line, #function, url.debugDescription, error.localizedDescription) - - notificationFeedbackGenerator.notificationOccurred(.error) - case .finished: + promise(.failure(error)) + case .success(let image): os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: download image %s success", ((#file as NSString).lastPathComponent), #line, #function, url.debugDescription) - - notificationFeedbackGenerator.notificationOccurred(.success) + promise(.success(image)) } }) - .map { response in - return response.image + } + .handleEvents(receiveSubscription: { _ in + impactFeedbackGenerator.impactOccurred() + }, receiveCompletion: { completion in + switch completion { + case .failure: + notificationFeedbackGenerator.notificationOccurred(.error) + case .finished: + notificationFeedbackGenerator.notificationOccurred(.success) } - .mapError { error in error as Error } - .eraseToAnyPublisher() + }) + .eraseToAnyPublisher() } func save(image: UIImage, withNotificationFeedback: Bool = false) {