diff --git a/.swift-version b/.swift-version index bf77d54..819e07a 100644 --- a/.swift-version +++ b/.swift-version @@ -1 +1 @@ -4.2 +5.0 diff --git a/.travis.yml b/.travis.yml index 0043732..37fee04 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: swift -osx_image: xcode10 +osx_image: xcode10.2 before_script: pod repo update script: travis_wait pod lib lint --allow-warnings diff --git a/AXPhotoViewer.podspec b/AXPhotoViewer.podspec index 1721f48..0eb98ff 100644 --- a/AXPhotoViewer.podspec +++ b/AXPhotoViewer.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "AXPhotoViewer" - s.version = "1.6.1" + s.version = "1.7.1" s.license = { :type => 'MIT', :file => 'LICENSE.md' } s.summary = "An iOS/tvOS photo gallery viewer, useful for viewing a large number of photos." s.homepage = "https://github.com/alexhillc/AXPhotoViewer" @@ -29,31 +29,40 @@ Pod::Spec.new do |s| end s.subspec 'SDWebImage' do |ss| + ss.ios.deployment_target = '8.0' + ss.tvos.deployment_target = '9.0' ss.dependency 'AXPhotoViewer/Core' ss.dependency 'SDWebImage', '>= 4.0.0' ss.source_files = 'Source/Integrations/SDWebImageIntegration.swift' end s.subspec 'PINRemoteImage' do |ps| + ps.ios.deployment_target = '8.0' + ps.tvos.deployment_target = '9.0' ps.dependency 'AXPhotoViewer/Core' ps.dependency 'PINRemoteImage', '~> 3.0.0-beta.9' ps.source_files = 'Source/Integrations/PINRemoteImageIntegration.swift' end s.subspec 'AFNetworking' do |as| + as.ios.deployment_target = '8.0' + as.tvos.deployment_target = '9.0' as.dependency 'AXPhotoViewer/Core' as.dependency 'AFNetworking/NSURLSession', '>= 3.1.0' as.source_files = 'Source/Integrations/AFNetworkingIntegration.swift' end s.subspec 'Kingfisher' do |ks| + ks.ios.deployment_target = '10.0' + ks.tvos.deployment_target = '10.0' ks.dependency 'AXPhotoViewer/Core' ks.dependency 'Kingfisher', '>= 3.10.0' ks.source_files = 'Source/Integrations/KingfisherIntegration.swift' end s.subspec 'Nuke' do |nk| - nk.ios.deployment_target = '9.0' + nk.ios.deployment_target = '10.0' + nk.tvos.deployment_target = '10.0' nk.dependency 'AXPhotoViewer/Core' nk.dependency 'Nuke', '>= 7.0' nk.source_files = 'Source/Integrations/NukeIntegration.swift' diff --git a/CHANGELOG.md b/CHANGELOG.md index b71f7fb..6666caa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# 1.7.1 +- [**NEW**] Better RTL support on device locales that support RTL (further support will require a refactor using AutoLayout) +- [**FIXED**] KingfisherIntegration was out of date #55 + +# 1.7.0 +- Requires Swift 5.0 + # 1.6.1 - [**FIXED**] When captionView layout occurred more than once while animation was occurring, new captions would be applied mid animation diff --git a/Example/iOS/AXPhotoViewerExample.xcodeproj/project.pbxproj b/Example/iOS/AXPhotoViewerExample.xcodeproj/project.pbxproj index 8ad2544..553639c 100644 --- a/Example/iOS/AXPhotoViewerExample.xcodeproj/project.pbxproj +++ b/Example/iOS/AXPhotoViewerExample.xcodeproj/project.pbxproj @@ -122,14 +122,14 @@ TargetAttributes = { FA8359D51EC01BD500B256C2 = { CreatedOnToolsVersion = 8.3; - LastSwiftMigration = 0900; + LastSwiftMigration = 1020; ProvisioningStyle = Automatic; }; }; }; buildConfigurationList = FA8359D11EC01BD500B256C2 /* Build configuration list for PBXProject "AXPhotoViewerExample" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, @@ -164,7 +164,7 @@ files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-AXPhotoViewerExample/Pods-AXPhotoViewerExample-frameworks.sh", + "${PODS_ROOT}/Target Support Files/Pods-AXPhotoViewerExample/Pods-AXPhotoViewerExample-frameworks.sh", "${BUILT_PRODUCTS_DIR}/AXPhotoViewer/AXPhotoViewer.framework", "${BUILT_PRODUCTS_DIR}/AXStateButton/AXStateButton.framework", "${BUILT_PRODUCTS_DIR}/DRPLoadingSpinner/DRPLoadingSpinner.framework", @@ -187,7 +187,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AXPhotoViewerExample/Pods-AXPhotoViewerExample-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-AXPhotoViewerExample/Pods-AXPhotoViewerExample-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; FAF414F9A9C922FCB012523A /* [CP] Check Pods Manifest.lock */ = { @@ -358,8 +358,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.bawkbawk.AXPhotoViewerExample; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.2; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -373,8 +372,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.bawkbawk.AXPhotoViewerExample; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.2; + SWIFT_VERSION = 5.0; }; name = Release; }; diff --git a/Example/iOS/AXPhotoViewerExample/AppDelegate.swift b/Example/iOS/AXPhotoViewerExample/AppDelegate.swift index fefaae4..f7659a8 100644 --- a/Example/iOS/AXPhotoViewerExample/AppDelegate.swift +++ b/Example/iOS/AXPhotoViewerExample/AppDelegate.swift @@ -13,7 +13,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { self.window = UIWindow(frame: UIScreen.main.bounds) self.window?.rootViewController = TableViewController() self.window?.makeKeyAndVisible() diff --git a/Example/iOS/AXPhotoViewerExample/TableViewController.swift b/Example/iOS/AXPhotoViewerExample/TableViewController.swift index 118c7f2..c868f22 100644 --- a/Example/iOS/AXPhotoViewerExample/TableViewController.swift +++ b/Example/iOS/AXPhotoViewerExample/TableViewController.swift @@ -124,9 +124,7 @@ class TableViewController: UITableViewController, AXPhotosViewControllerDelegate } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - guard let cell = tableView.dequeueReusableCell(withIdentifier: ReuseIdentifier) else { - return UITableViewCell() - } + guard let cell = tableView.dequeueReusableCell(withIdentifier: ReuseIdentifier) else { return UITableViewCell() } // sample project worst practices top kek if cell.contentView.viewWithTag(666) == nil { @@ -143,9 +141,7 @@ class TableViewController: UITableViewController, AXPhotosViewControllerDelegate } override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { - guard let imageView = cell.contentView.viewWithTag(666) as? FLAnimatedImageView else { - return - } + guard let imageView = cell.contentView.viewWithTag(666) as? FLAnimatedImageView else { return } self.cancelLoad(at: indexPath, for: imageView) self.loadContent(at: indexPath, into: imageView) @@ -156,14 +152,10 @@ class TableViewController: UITableViewController, AXPhotosViewControllerDelegate let imageView = cell?.contentView.viewWithTag(666) as? FLAnimatedImageView let transitionInfo = AXTransitionInfo(interactiveDismissalEnabled: true, startingView: imageView) { [weak self] (photo, index) -> UIImageView? in - guard let `self` = self else { - return nil - } + guard let `self` = self else { return nil } let indexPath = IndexPath(row: index, section: 0) - guard let cell = self.tableView.cellForRow(at: indexPath) else { - return nil - } + guard let cell = self.tableView.cellForRow(at: indexPath) else { return nil } // adjusting the reference view attached to our transition info to allow for contextual animation return cell.contentView.viewWithTag(666) as? FLAnimatedImageView diff --git a/Example/iOS/Podfile.lock b/Example/iOS/Podfile.lock index 8bd2fc8..62d0d86 100644 --- a/Example/iOS/Podfile.lock +++ b/Example/iOS/Podfile.lock @@ -1,9 +1,9 @@ PODS: - - AXPhotoViewer/Core (1.5.0): + - AXPhotoViewer/Core (1.7.0): - AXStateButton (>= 1.1.3) - FLAnimatedImage (>= 1.0.0) - FLAnimatedImage-tvOS (>= 1.0.16) - - AXPhotoViewer/PINRemoteImage (1.5.0): + - AXPhotoViewer/PINRemoteImage (1.7.0): - AXPhotoViewer/Core - PINRemoteImage (~> 3.0.0-beta.9) - AXStateButton (1.1.4) @@ -53,7 +53,7 @@ EXTERNAL SOURCES: :path: "../../AXPhotoViewer.podspec" SPEC CHECKSUMS: - AXPhotoViewer: b21480ab848dea4d13b14a232b2d2fe378937577 + AXPhotoViewer: 530af2fdd8eca4336f509c4c3463826b3f12a4c2 AXStateButton: 6c515a433e37551505046429b5be04c12daa8c07 DRPLoadingSpinner: 725e530bf4ebe2cc351b1fbc94d24fe8ac3300fd FLAnimatedImage: 4a0b56255d9b05f18b6dd7ee06871be5d3b89e31 @@ -64,4 +64,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 6f4a81711307afc468e5f3e553aeb2549b5e1280 -COCOAPODS: 1.5.3 +COCOAPODS: 1.6.1 diff --git a/Example/tvOS/AXPhotoViewerExample.xcodeproj/project.pbxproj b/Example/tvOS/AXPhotoViewerExample.xcodeproj/project.pbxproj index e810597..c413ae5 100644 --- a/Example/tvOS/AXPhotoViewerExample.xcodeproj/project.pbxproj +++ b/Example/tvOS/AXPhotoViewerExample.xcodeproj/project.pbxproj @@ -114,6 +114,7 @@ TargetAttributes = { FA983C20205B1374006C2399 = { CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 1020; ProvisioningStyle = Automatic; }; }; @@ -330,7 +331,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.boop.AXPhotoViewerExample; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 4.2; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 3; }; name = Debug; @@ -347,7 +348,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.boop.AXPhotoViewerExample; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 4.2; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 3; }; name = Release; diff --git a/Example/tvOS/AXPhotoViewerExample/AppDelegate.swift b/Example/tvOS/AXPhotoViewerExample/AppDelegate.swift index ca83864..9e32c52 100644 --- a/Example/tvOS/AXPhotoViewerExample/AppDelegate.swift +++ b/Example/tvOS/AXPhotoViewerExample/AppDelegate.swift @@ -13,8 +13,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { let cacheSizeMemory = 1024 * 1024 * 200 let cacheSizeDisk = 1024 * 1024 * 200 let sharedCache = URLCache(memoryCapacity: cacheSizeMemory, diskCapacity: cacheSizeDisk, diskPath: nil) diff --git a/README.md b/README.md index d138ace..f3f9955 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +# This project is unmaintained. +## Alex passed away in an accident in late 2019. His love of iOS development will always be remembered. + # AXPhotoViewer [![Build Status](https://travis-ci.org/alexhillc/AXPhotoViewer.svg?branch=master)](https://travis-ci.org/alexhillc/AXPhotoViewer)

diff --git a/Source/Classes/Models/AXTransitionInfo.swift b/Source/Classes/Models/AXTransitionInfo.swift index c9b14e7..3f3caa4 100644 --- a/Source/Classes/Models/AXTransitionInfo.swift +++ b/Source/Classes/Models/AXTransitionInfo.swift @@ -86,9 +86,7 @@ if let endingView = endingView { self.resolveEndingViewClosure = { [weak self] (photo, index) in - guard let `self` = self else { - return - } + guard let `self` = self else { return } if let endingView = endingView(photo, index) { guard endingView.bounds != .zero else { diff --git a/Source/Classes/Transition Controller + Animators/AXPhotosDismissalAnimator.swift b/Source/Classes/Transition Controller + Animators/AXPhotosDismissalAnimator.swift index 8048bfa..112b0f8 100644 --- a/Source/Classes/Transition Controller + Animators/AXPhotosDismissalAnimator.swift +++ b/Source/Classes/Transition Controller + Animators/AXPhotosDismissalAnimator.swift @@ -152,9 +152,7 @@ class AXPhotosDismissalAnimator: AXPhotosTransitionAnimator, UIViewControllerInt var offscreenImageViewCenter: CGPoint? let scaleAnimations = { [weak self] () in - guard let `self` = self else { - return - } + guard let `self` = self else { return } if self.canPerformContextualDismissal() { let endingView = self.transitionInfo.endingView! @@ -173,9 +171,7 @@ class AXPhotosDismissalAnimator: AXPhotosTransitionAnimator, UIViewControllerInt } let scaleCompletion = { [weak self] (_ finished: Bool) in - guard let `self` = self else { - return - } + guard let `self` = self else { return } self.delegate?.transitionAnimator(self, didCompleteDismissalWith: imageViewContainer.imageView) @@ -414,10 +410,8 @@ class AXPhotosDismissalAnimator: AXPhotosTransitionAnimator, UIViewControllerInt let overlayView = photosViewController.overlayView let animations = { [weak self] () in - guard let `self` = self else { - return - } - + guard let `self` = self else { return } + imageView.center.y = self.imageViewInitialCenter.y overlayView.topStackContainer.frame.origin.y = self.topStackContainerInitialOriginY overlayView.bottomStackContainer.frame.origin.y = self.bottomStackContainerInitialOriginY @@ -426,9 +420,7 @@ class AXPhotosDismissalAnimator: AXPhotosTransitionAnimator, UIViewControllerInt } let completion = { [weak self] (_ finished: Bool) in - guard let `self` = self else { - return - } + guard let `self` = self else { return } if self.canPerformContextualDismissal() { guard let referenceView = self.transitionInfo.endingView else { diff --git a/Source/Classes/Transition Controller + Animators/AXPhotosPresentationAnimator.swift b/Source/Classes/Transition Controller + Animators/AXPhotosPresentationAnimator.swift index 4db8f48..e1919a6 100644 --- a/Source/Classes/Transition Controller + Animators/AXPhotosPresentationAnimator.swift +++ b/Source/Classes/Transition Controller + Animators/AXPhotosPresentationAnimator.swift @@ -68,9 +68,7 @@ class AXPhotosPresentationAnimator: AXPhotosTransitionAnimator { } let scaleCompletion = { [weak self] (_ finished: Bool) in - guard let `self` = self else { - return - } + guard let `self` = self else { return } self.delegate?.transitionAnimator(self, didCompletePresentationWith: startingViewContainer.imageView) diff --git a/Source/Classes/Transition Controller + Animators/AXPhotosTransitionController.swift b/Source/Classes/Transition Controller + Animators/AXPhotosTransitionController.swift index 9345a19..b293edd 100644 --- a/Source/Classes/Transition Controller + Animators/AXPhotosTransitionController.swift +++ b/Source/Classes/Transition Controller + Animators/AXPhotosTransitionController.swift @@ -75,9 +75,7 @@ class AXPhotosTransitionController: NSObject, UIViewControllerTransitioningDeleg return nil } - guard let photo = photosViewController.dataSource.photo(at: photosViewController.currentPhotoIndex) else { - return nil - } + guard let photo = photosViewController.dataSource.photo(at: photosViewController.currentPhotoIndex) else { return nil } // resolve transitionInfo's endingView self.transitionInfo.resolveEndingViewClosure?(photo, photosViewController.currentPhotoIndex) diff --git a/Source/Classes/View Controllers/AXPhotoViewController.swift b/Source/Classes/View Controllers/AXPhotoViewController.swift index 641529c..001645a 100644 --- a/Source/Classes/View Controllers/AXPhotoViewController.swift +++ b/Source/Classes/View Controllers/AXPhotoViewController.swift @@ -103,10 +103,7 @@ import FLAnimatedImage_tvOS resetImageView() let error = photo.ax_error ?? NSError() self.loadingView?.showError(error, retryHandler: { [weak self] in - guard let `self` = self else { - return - } - + guard let `self` = self else { return } self.delegate?.photoViewController(self, retryDownloadFor: photo) self.loadingView?.removeError() self.loadingView?.startLoading(initialProgress: photo.ax_progress) @@ -173,10 +170,7 @@ import FLAnimatedImage_tvOS self.zoomingImageView.imageView.ax_syncFrames(with: referenceView) } else if let error = userInfo[AXPhotosViewControllerNotification.ErrorKey] as? Error { self.loadingView?.showError(error, retryHandler: { [weak self] in - guard let `self` = self, let photo = self.photo else { - return - } - + guard let `self` = self, let photo = self.photo else { return } self.delegate?.photoViewController(self, retryDownloadFor: photo) self.loadingView?.removeError() self.loadingView?.startLoading(initialProgress: photo.ax_progress) diff --git a/Source/Classes/View Controllers/AXPhotosViewController.swift b/Source/Classes/View Controllers/AXPhotosViewController.swift index de6721e..3f657f5 100644 --- a/Source/Classes/View Controllers/AXPhotosViewController.swift +++ b/Source/Classes/View Controllers/AXPhotosViewController.swift @@ -421,9 +421,7 @@ import FLAnimatedImage_tvOS if self.isFirstAppearance { let visible: Bool = true self.overlayView.setShowInterface(visible, animated: true, alongside: { [weak self] in - guard let `self` = self else { - return - } + guard let `self` = self else { return } #if os(iOS) self.updateStatusBarAppearance(show: visible) @@ -450,10 +448,7 @@ import FLAnimatedImage_tvOS self.overlayView.frame = self.view.bounds self.overlayView.performAfterShowInterfaceCompletion { [weak self] in // if being dismissed, let's just return early rather than update insets - guard let `self` = self, !self.isBeingDismissed else { - return - } - + guard let `self` = self, !self.isBeingDismissed else { return } self.updateOverlayInsets() } } @@ -471,9 +466,7 @@ import FLAnimatedImage_tvOS // MARK: - PhotosViewControllerTransitionAnimatorDelegate func transitionController(_ transitionController: AXPhotosTransitionController, didCompletePresentationWith transitionView: UIImageView) { - guard let photo = self.dataSource.photo(at: self.currentPhotoIndex) else { - return - } + guard let photo = self.dataSource.photo(at: self.currentPhotoIndex) else { return } self.notificationCenter.post( name: .photoImageUpdate, @@ -528,9 +521,7 @@ import FLAnimatedImage_tvOS return } - guard let photoViewController = self.makePhotoViewController(for: photoIndex) else { - return - } + guard let photoViewController = self.makePhotoViewController(for: photoIndex) else { return } let forward = (photoIndex > self.currentPhotoIndex) self.pageViewController.setViewControllers([photoViewController], @@ -538,6 +529,7 @@ import FLAnimatedImage_tvOS animated: animated, completion: nil) self.loadPhotos(at: photoIndex) + self.currentPhotoIndex = photoIndex } // MARK: - Page VC Configuration @@ -562,15 +554,13 @@ import FLAnimatedImage_tvOS // MARK: - Overlay fileprivate func updateOverlay(for photoIndex: Int) { - guard let photo = self.dataSource.photo(at: photoIndex) else { - return - } + guard let photo = self.dataSource.photo(at: photoIndex) else { return } self.willUpdate(overlayView: self.overlayView, for: photo, at: photoIndex, totalNumberOfPhotos: self.dataSource.numberOfPhotos) #if os(iOS) if self.dataSource.numberOfPhotos > 1 { - self.overlayView.internalTitle = String.localizedStringWithFormat("%d of %d", photoIndex + 1, self.dataSource.numberOfPhotos) + self.overlayView.internalTitle = String.localizedStringWithFormat(NSLocalizedString("%d of %d", comment: ""), photoIndex + 1, self.dataSource.numberOfPhotos) } else { self.overlayView.internalTitle = nil } @@ -608,9 +598,7 @@ import FLAnimatedImage_tvOS @objc fileprivate func didSingleTapWithGestureRecognizer(_ sender: UITapGestureRecognizer) { let show = (self.overlayView.alpha == 0) self.overlayView.setShowInterface(show, animated: true, alongside: { [weak self] in - guard let `self` = self else { - return - } + guard let `self` = self else { return } #if os(iOS) self.updateStatusBarAppearance(show: show) @@ -644,9 +632,7 @@ import FLAnimatedImage_tvOS // MARK: - Default bar button actions @objc public func shareAction(_ barButtonItem: UIBarButtonItem) { - guard let photo = self.dataSource.photo(at: self.currentPhotoIndex) else { - return - } + guard let photo = self.dataSource.photo(at: self.currentPhotoIndex) else { return } if self.handleActionButtonTapped(photo: photo) { return @@ -659,15 +645,11 @@ import FLAnimatedImage_tvOS anyRepresentation = image } - guard let uAnyRepresentation = anyRepresentation else { - return - } + guard let uAnyRepresentation = anyRepresentation else { return } let activityViewController = UIActivityViewController(activityItems: [uAnyRepresentation], applicationActivities: nil) activityViewController.completionWithItemsHandler = { [weak self] (activityType, completed, returnedItems, activityError) in - guard let `self` = self else { - return - } + guard let `self` = self else { return } if completed, let activityType = activityType { self.actionCompleted(activityType: activityType, for: photo) @@ -691,9 +673,7 @@ import FLAnimatedImage_tvOS let indexes = startIndex...(startIndex + numberOfPhotosToLoad) for index in indexes { - guard let photo = self.dataSource.photo(at: index) else { - return - } + guard let photo = self.dataSource.photo(at: index) else { return } if photo.ax_loadingState == .notLoaded || photo.ax_loadingState == .loadingCancelled { photo.ax_loadingState = .loading @@ -709,9 +689,7 @@ import FLAnimatedImage_tvOS weak var weakSelf = self func reduceMemory(for photo: AXPhotoProtocol) { - guard let `self` = weakSelf else { - return - } + guard let `self` = weakSelf else { return } if photo.ax_loadingState == .loading { self.networkIntegration.cancelLoad(for: photo) @@ -735,9 +713,7 @@ import FLAnimatedImage_tvOS // MARK: - Reuse / Factory fileprivate func makePhotoViewController(for pageIndex: Int) -> AXPhotoViewController? { - guard let photo = self.dataSource.photo(at: pageIndex) else { - return nil - } + guard let photo = self.dataSource.photo(at: pageIndex) else { return nil } var photoViewController: AXPhotoViewController @@ -745,9 +721,7 @@ import FLAnimatedImage_tvOS photoViewController = self.recycledViewControllers.removeLast() photoViewController.prepareForReuse() } else { - guard let loadingView = self.makeLoadingView(for: pageIndex) else { - return nil - } + guard let loadingView = self.makeLoadingView(for: pageIndex) else { return nil } photoViewController = AXPhotoViewController(loadingView: loadingView, notificationCenter: self.notificationCenter) photoViewController.addLifecycleObserver(self) @@ -782,7 +756,7 @@ import FLAnimatedImage_tvOS return } - if let index = self.orderedViewControllers.index(of: photoViewController) { + if let index = self.orderedViewControllers.firstIndex(of: photoViewController) { self.orderedViewControllers.remove(at: index) } @@ -801,9 +775,7 @@ import FLAnimatedImage_tvOS } fileprivate func lifecycleContextDidUpdate(object: Any?, change: [NSKeyValueChangeKey : Any]?) { - guard let photoViewController = object as? AXPhotoViewController else { - return - } + guard let photoViewController = object as? AXPhotoViewController else { return } if change?[.newKey] is NSNull { self.recyclePhotoViewController(photoViewController) @@ -811,9 +783,7 @@ import FLAnimatedImage_tvOS } fileprivate func contentOffsetContextDidUpdate(object: Any?, change: [NSKeyValueChangeKey : Any]?) { - guard let scrollView = object as? UIScrollView, !self.isSizeTransitioning else { - return - } + guard let scrollView = object as? UIScrollView, !self.isSizeTransitioning else { return } var percent: CGFloat if self.pagingConfig.navigationOrientation == .horizontal { @@ -829,15 +799,34 @@ import FLAnimatedImage_tvOS horizontalSwipeDirection = .left } - let swipePercent = (horizontalSwipeDirection == .left) ? (1 - abs(percent)) : abs(percent) + let layoutDirection: UIUserInterfaceLayoutDirection + if #available(iOS 9.0, tvOS 9.0, *) { + layoutDirection = UIView.userInterfaceLayoutDirection(for: self.pageViewController.view.semanticContentAttribute) + } else { + layoutDirection = .leftToRight + } + + let swipePercent: CGFloat + if horizontalSwipeDirection == .left { + if layoutDirection == .leftToRight { + swipePercent = 1 - abs(percent) + } else { + swipePercent = abs(percent) + } + } else { + if layoutDirection == .leftToRight { + swipePercent = abs(percent) + } else { + swipePercent = 1 - abs(percent) + } + } + var lowIndex: Int = NSNotFound var highIndex: Int = NSNotFound let viewControllers = self.computeVisibleViewControllers(in: scrollView) if horizontalSwipeDirection == .left { - guard let viewController = viewControllers.first else { - return - } + guard let viewController = viewControllers.first else { return } if viewControllers.count > 1 { lowIndex = viewController.pageIndex @@ -848,9 +837,7 @@ import FLAnimatedImage_tvOS highIndex = viewController.pageIndex } } else if horizontalSwipeDirection == .right { - guard let viewController = viewControllers.last else { - return - } + guard let viewController = viewControllers.last else { return } if viewControllers.count > 1 { highIndex = viewController.pageIndex @@ -913,18 +900,12 @@ import FLAnimatedImage_tvOS // MARK: - UIPageViewControllerDataSource public func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) { - guard let viewController = pendingViewControllers.first as? AXPhotoViewController else { - return - } - + guard let viewController = pendingViewControllers.first as? AXPhotoViewController else { return } self.loadPhotos(at: viewController.pageIndex) } public func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) { - guard let viewController = pageViewController.viewControllers?.first as? AXPhotoViewController else { - return - } - + guard let viewController = pageViewController.viewControllers?.first as? AXPhotoViewController else { return } self.reduceMemoryForPhotos(at: viewController.pageIndex) } @@ -947,19 +928,13 @@ import FLAnimatedImage_tvOS } public func pageViewController(_ pageViewController: UIPageViewController, viewControllerAt index: Int) -> UIViewController? { - guard index >= 0 && self.dataSource.numberOfPhotos > index else { - return nil - } - + guard index >= 0 && self.dataSource.numberOfPhotos > index else { return nil } return self.makePhotoViewController(for: index) } // MARK: - AXPhotoViewControllerDelegate public func photoViewController(_ photoViewController: AXPhotoViewController, retryDownloadFor photo: AXPhotoProtocol) { - guard photo.ax_loadingState != .loading && photo.ax_loadingState != .loaded else { - return - } - + guard photo.ax_loadingState != .loading && photo.ax_loadingState != .loaded else { return } photo.ax_error = nil photo.ax_loadingState = .loading self.networkIntegration.loadPhoto(photo) @@ -969,11 +944,7 @@ import FLAnimatedImage_tvOS maximumZoomScaleForPhotoAt index: Int, minimumZoomScale: CGFloat, imageSize: CGSize) -> CGFloat { - - guard let photo = self.dataSource.photo(at: index) else { - return .leastNormalMagnitude - } - + guard let photo = self.dataSource.photo(at: index) else { return .leastNormalMagnitude } return self.maximumZoomScale(for: photo, minimumZoomScale: minimumZoomScale, imageSize: imageSize) } diff --git a/Source/Classes/View Controllers/AXPreviewingPhotosViewController.swift b/Source/Classes/View Controllers/AXPreviewingPhotosViewController.swift index 7edf3b4..083f093 100644 --- a/Source/Classes/View Controllers/AXPreviewingPhotosViewController.swift +++ b/Source/Classes/View Controllers/AXPreviewingPhotosViewController.swift @@ -105,10 +105,7 @@ import FLAnimatedImage } fileprivate func configure(with index: Int) { - guard let photo = self.dataSource.photo(at: index) else { - return - } - + guard let photo = self.dataSource.photo(at: index) else { return } self.networkIntegration.loadPhoto(photo) } diff --git a/Source/Classes/Views/AXCaptionView.swift b/Source/Classes/Views/AXCaptionView.swift index 9b7fb35..0909de3 100644 --- a/Source/Classes/Views/AXCaptionView.swift +++ b/Source/Classes/Views/AXCaptionView.swift @@ -222,9 +222,7 @@ import UIKit weak var weakSelf = self func applySizingAttributes() { - guard let `self` = weakSelf else { - return - } + guard let `self` = weakSelf else { return } self.titleLabel.attributedText = self.titleSizingLabel.attributedText self.titleLabel.frame = self.titleSizingLabel.frame @@ -240,67 +238,69 @@ import UIKit } if self.animateCaptionInfoChanges && self.needsCaptionLayoutAnim { - if !self.isCaptionAnimatingOut { - self.isCaptionAnimatingOut = true + // ensure that this block runs in its own animation context (container may animate) + DispatchQueue.main.async { [weak self] in + guard let `self` = self else { return } + + let animateOut: () -> Void = { + self.titleLabel.alpha = 0 + self.descriptionLabel.alpha = 0 + self.creditLabel.alpha = 0 + } - // ensure that this block runs in its own animation context (container may animate) - DispatchQueue.main.async { [weak self] in - guard let `self` = self else { + let animateOutCompletion: (_ finished: Bool) -> Void = { (finished) in + if !finished { return } - let animateOut: () -> Void = { - self.titleLabel.alpha = 0 - self.descriptionLabel.alpha = 0 - self.creditLabel.alpha = 0 - } - - let animateOutCompletion: (_ finished: Bool) -> Void = { (finished) in - if !finished { - return - } - - applySizingAttributes() - self.isCaptionAnimatingOut = false - } - - let animateIn: () -> Void = { - self.titleLabel.alpha = 1 - self.descriptionLabel.alpha = 1 - self.creditLabel.alpha = 1 + applySizingAttributes() + self.isCaptionAnimatingOut = false + } + + let animateIn: () -> Void = { + self.titleLabel.alpha = 1 + self.descriptionLabel.alpha = 1 + self.creditLabel.alpha = 1 + } + + let animateInCompletion: (_ finished: Bool) -> Void = { (finished) in + if !finished { + return } - let animateInCompletion: (_ finished: Bool) -> Void = { (finished) in - if !finished { - return - } - - self.isCaptionAnimatingIn = false + self.isCaptionAnimatingIn = false + } + + if self.isCaptionAnimatingOut { + return + } + + self.isCaptionAnimatingOut = true + UIView.animate(withDuration: AXConstants.frameAnimDuration / 2, + delay: 0, + options: [.beginFromCurrentState, .curveEaseOut], + animations: animateOut) { (finished) in + if self.isCaptionAnimatingIn { + return } + animateOutCompletion(finished) UIView.animate(withDuration: AXConstants.frameAnimDuration / 2, delay: 0, - options: [.beginFromCurrentState, .curveEaseOut], - animations: animateOut) { (finished) in - if self.isCaptionAnimatingIn { - return - } - - animateOutCompletion(finished) - self.isCaptionAnimatingIn = true - UIView.animate(withDuration: AXConstants.frameAnimDuration / 2, - delay: 0, - options: [.beginFromCurrentState, .curveEaseIn], - animations: animateIn, - completion: animateInCompletion) - } + options: [.beginFromCurrentState, .curveEaseIn], + animations: animateIn, + completion: animateInCompletion) } - - self.needsCaptionLayoutAnim = false } + + self.needsCaptionLayoutAnim = false + } else { - if !self.isCaptionAnimatingIn && !self.isCaptionAnimatingOut { - applySizingAttributes() + DispatchQueue.main.async { [weak self] in + guard let `self` = self else { return } + if !self.isCaptionAnimatingOut && !self.isCaptionAnimatingIn { + applySizingAttributes() + } } } @@ -384,10 +384,8 @@ import UIKit // MARK: - Helpers private func makeAttributedStringWithDefaults(_ defaults: [NSAttributedString.Key: Any], for attributedString: NSAttributedString) -> (attributedString: NSAttributedString, - removedDefaultKeys: Set) { - guard let defaultAttributedString = attributedString.mutableCopy() as? NSMutableAttributedString else { - return (attributedString, []) - } + removedDefaultKeys: Set) { + guard let defaultAttributedString = attributedString.mutableCopy() as? NSMutableAttributedString else { return (attributedString, []) } var removedKeys = Set() var defaultAttributes = defaults @@ -404,16 +402,12 @@ import UIKit private func makeFontAdjustedAttributedString(for attributedString: NSAttributedString?, fontTextStyle: UIFont.TextStyle) -> NSAttributedString? { - guard let fontAdjustedAttributedString = attributedString?.mutableCopy() as? NSMutableAttributedString else { - return attributedString - } + guard let fontAdjustedAttributedString = attributedString?.mutableCopy() as? NSMutableAttributedString else { return attributedString } fontAdjustedAttributedString.enumerateAttribute(NSAttributedString.Key.font, in: NSMakeRange(0, fontAdjustedAttributedString.length), options: [], using: { [weak self] (value, range, stop) in - guard let oldFont = value as? UIFont else { - return - } + guard let oldFont = value as? UIFont else { return } var newFontDescriptor: UIFontDescriptor if #available(iOS 10.0, tvOS 10.0, *) { diff --git a/Source/Classes/Views/AXImageViewTransitionContainer.swift b/Source/Classes/Views/AXImageViewTransitionContainer.swift index f714b23..7a24af3 100644 --- a/Source/Classes/Views/AXImageViewTransitionContainer.swift +++ b/Source/Classes/Views/AXImageViewTransitionContainer.swift @@ -46,9 +46,7 @@ final class AXImageViewTransitionContainer: UIView { override func layoutSubviews() { super.layoutSubviews() - guard let imageSize = self.imageView.image?.size else { - return - } + guard let imageSize = self.imageView.image?.size else { return } switch self.contentMode { case .scaleToFill: @@ -90,6 +88,8 @@ final class AXImageViewTransitionContainer: UIView { case .bottomRight: self.imageView.bounds = imageSize.rect() self.imageView.center = self.bounds.size.bottomRight(forSize: imageSize) + @unknown default: + break } } diff --git a/Source/Classes/Views/AXLoadingView.swift b/Source/Classes/Views/AXLoadingView.swift index cc7b1ea..2b97ef4 100644 --- a/Source/Classes/Views/AXLoadingView.swift +++ b/Source/Classes/Views/AXLoadingView.swift @@ -116,13 +116,9 @@ @discardableResult fileprivate func computeSize(for constrainedSize: CGSize, applySizingLayout: Bool) -> CGSize { func makeAttributedStringWithAttributes(_ attributes: [NSAttributedString.Key: Any], for attributedString: NSAttributedString?) -> NSAttributedString? { - guard let newAttributedString = attributedString?.mutableCopy() as? NSMutableAttributedString else { - return attributedString - } - + guard let newAttributedString = attributedString?.mutableCopy() as? NSMutableAttributedString else { return attributedString } newAttributedString.setAttributes(nil, range: NSMakeRange(0, newAttributedString.length)) newAttributedString.addAttributes(attributes, range: NSMakeRange(0, newAttributedString.length)) - return newAttributedString.copy() as? NSAttributedString } diff --git a/Source/Classes/Views/AXOverlayView.swift b/Source/Classes/Views/AXOverlayView.swift index 92f1e9f..f518bde 100644 --- a/Source/Classes/Views/AXOverlayView.swift +++ b/Source/Classes/Views/AXOverlayView.swift @@ -121,7 +121,7 @@ import UIKit return } - let index = self.bottomStackContainer.subviews.index(of: oldCaptionView) + let index = self.bottomStackContainer.subviews.firstIndex(of: oldCaptionView) oldCaptionView.removeFromSuperview() self.bottomStackContainer.insertSubview(captionView, at: index ?? 0) self.setNeedsLayout() @@ -303,10 +303,7 @@ import UIKit let size = self.bottomStackContainer.sizeThatFits(self.frame.size) let animations = { [weak self] in - guard let `self` = self else { - return - } - + guard let `self` = self else { return } self.bottomStackContainer.frame = CGRect(origin: CGPoint(x: 0, y: self.frame.size.height - size.height), size: size) self.bottomStackContainer.setNeedsLayout() self.bottomStackContainer.layoutIfNeeded() @@ -408,10 +405,7 @@ import UIKit } if let attributedText = attributedText { - guard let titleBarButtonItemLabel = self.titleBarButtonItem.customView as? UILabel else { - return - } - + guard let titleBarButtonItemLabel = self.titleBarButtonItem.customView as? UILabel else { return } if titleBarButtonItemLabel.attributedText != attributedText { titleBarButtonItemLabel.attributedText = attributedText titleBarButtonItemLabel.sizeToFit() diff --git a/Source/Integrations/AFNetworkingIntegration.swift b/Source/Integrations/AFNetworkingIntegration.swift index 408c437..466b29e 100644 --- a/Source/Integrations/AFNetworkingIntegration.swift +++ b/Source/Integrations/AFNetworkingIntegration.swift @@ -19,10 +19,7 @@ class AFNetworkingIntegration: NSObject, AXNetworkIntegrationProtocol { public func loadPhoto(_ photo: AXPhotoProtocol) { if photo.imageData != nil || photo.image != nil { AXDispatchUtils.executeInBackground { [weak self] in - guard let `self` = self else { - return - } - + guard let `self` = self else { return } self.delegate?.networkIntegration(self, loadDidFinishWith: photo) } return @@ -33,42 +30,28 @@ class AFNetworkingIntegration: NSObject, AXNetworkIntegrationProtocol { } let progress: (_ progress: Progress) -> Void = { [weak self] (progress) in - guard let `self` = self else { - return - } - AXDispatchUtils.executeInBackground { [weak self] in - guard let `self` = self else { - return - } - + guard let `self` = self else { return } self.delegate?.networkIntegration?(self, didUpdateLoadingProgress: CGFloat(progress.fractionCompleted), for: photo) } } let success: (_ dataTask: URLSessionDataTask, _ responseObject: Any?) -> Void = { [weak self] (dataTask, responseObject) in - guard let `self` = self else { - return - } + guard let `self` = self else { return } self.downloadTasks.removeObject(forKey: photo) if let responseGIFData = responseObject as? Data { photo.imageData = responseGIFData AXDispatchUtils.executeInBackground { [weak self] in - guard let `self` = self else { - return - } + guard let `self` = self else { return } self.delegate?.networkIntegration(self, loadDidFinishWith: photo) } } else if let responseImage = responseObject as? UIImage { photo.image = responseImage AXDispatchUtils.executeInBackground { [weak self] in - guard let `self` = self else { - return - } - + guard let `self` = self else { return } self.delegate?.networkIntegration(self, loadDidFinishWith: photo) } } else { @@ -78,19 +61,14 @@ class AFNetworkingIntegration: NSObject, AXNetworkIntegrationProtocol { userInfo: nil ) AXDispatchUtils.executeInBackground { [weak self] in - guard let `self` = self else { - return - } - + guard let `self` = self else { return } self.delegate?.networkIntegration(self, loadDidFailWith: error, for: photo) } } } let failure: (_ dataTask: URLSessionDataTask?, _ error: Error) -> Void = { [weak self] (dataTask, error) in - guard let `self` = self else { - return - } + guard let `self` = self else { return } self.downloadTasks.removeObject(forKey: photo) @@ -100,25 +78,21 @@ class AFNetworkingIntegration: NSObject, AXNetworkIntegrationProtocol { userInfo: nil ) AXDispatchUtils.executeInBackground { [weak self] in - guard let `self` = self else { - return - } - + guard let `self` = self else { return } self.delegate?.networkIntegration(self, loadDidFailWith: error, for: photo) } } - guard let dataTask = AXHTTPSessionManager.shared.get(url.absoluteString, parameters: nil, progress: progress, success: success, failure: failure) else { - return - } - + guard let dataTask = AXHTTPSessionManager.shared.get(url.absoluteString, + parameters: nil, + progress: progress, + success: success, + failure: failure) else { return } self.downloadTasks.setObject(dataTask, forKey: photo) } func cancelLoad(for photo: AXPhotoProtocol) { - guard let dataTask = self.downloadTasks.object(forKey: photo) else { - return - } + guard let dataTask = self.downloadTasks.object(forKey: photo) else { return } dataTask.cancel() self.downloadTasks.removeObject(forKey: photo) @@ -136,7 +110,7 @@ class AFNetworkingIntegration: NSObject, AXNetworkIntegrationProtocol { } -/// An `AFHTTPSesssionManager` with our subclassed `AXAFImageResponseSerializer`. +/// An `AFHTTPSesssionManager` with our subclassed `AXImageResponseSerializer`. class AXHTTPSessionManager: AFHTTPSessionManager { static let shared = AXHTTPSessionManager() @@ -156,10 +130,7 @@ class AXHTTPSessionManager: AFHTTPSessionManager { class AXImageResponseSerializer: AFImageResponseSerializer { override func responseObject(for response: URLResponse?, data: Data?, error: NSErrorPointer) -> Any? { - if let `data` = data, data.containsGIF() { - return data - } - + if let `data` = data, data.containsGIF() { return data } return super.responseObject(for: response, data: data, error: error) } diff --git a/Source/Integrations/KingfisherIntegration.swift b/Source/Integrations/KingfisherIntegration.swift index d985c0d..474157b 100644 --- a/Source/Integrations/KingfisherIntegration.swift +++ b/Source/Integrations/KingfisherIntegration.swift @@ -10,102 +10,74 @@ import Kingfisher class KingfisherIntegration: NSObject, AXNetworkIntegrationProtocol { - + weak public var delegate: AXNetworkIntegrationDelegate? - - fileprivate var retrieveImageTasks = NSMapTable(keyOptions: .strongMemory, valueOptions: .strongMemory) - + + fileprivate var retrieveImageTasks: [Int: DownloadTask] = [:] + public func loadPhoto(_ photo: AXPhotoProtocol) { if photo.imageData != nil || photo.image != nil { AXDispatchUtils.executeInBackground { [weak self] in - guard let `self` = self else { - return - } - + guard let `self` = self else { return } self.delegate?.networkIntegration(self, loadDidFinishWith: photo) } return } - - guard let url = photo.url else { - return - } - + + guard let url = photo.url else { return } + let progress: DownloadProgressBlock = { [weak self] (receivedSize, totalSize) in - guard let `self` = self else { - return - } - AXDispatchUtils.executeInBackground { [weak self] in - guard let `self` = self else { - return - } - + guard let `self` = self else { return } self.delegate?.networkIntegration?(self, didUpdateLoadingProgress: CGFloat(receivedSize) / CGFloat(totalSize), for: photo) } } - - let completion: CompletionHandler = { [weak self] (image, error, cacheType, imageURL) in - guard let `self` = self else { - return - } - - self.retrieveImageTasks.removeObject(forKey: photo) - - if let imageData = image?.kf.gifRepresentation() { - photo.imageData = imageData - AXDispatchUtils.executeInBackground { [weak self] in - guard let `self` = self else { - return + + let completion: ((Result) -> Void) = { [weak self] (result) in + guard let `self` = self else { return } + + self.retrieveImageTasks[photo.hash] = nil + + switch result { + case .success(let retrieveImageResult): + if let imageData = retrieveImageResult.image.kf.gifRepresentation() { + photo.imageData = imageData + AXDispatchUtils.executeInBackground { [weak self] in + guard let `self` = self else { return } + self.delegate?.networkIntegration(self, loadDidFinishWith: photo) } - - self.delegate?.networkIntegration(self, loadDidFinishWith: photo) - } - } else if let image = image { - photo.image = image - AXDispatchUtils.executeInBackground { [weak self] in - guard let `self` = self else { - return + } else { + photo.image = retrieveImageResult.image + AXDispatchUtils.executeInBackground { [weak self] in + guard let `self` = self else { return } + self.delegate?.networkIntegration(self, loadDidFinishWith: photo) } - - self.delegate?.networkIntegration(self, loadDidFinishWith: photo) } - } else { + case .failure(let error): let error = NSError( domain: AXNetworkIntegrationErrorDomain, code: AXNetworkIntegrationFailedToLoadErrorCode, - userInfo: nil + userInfo: ["description": error.errorDescription ?? ""] ) AXDispatchUtils.executeInBackground { [weak self] in - guard let `self` = self else { - return - } - + guard let `self` = self else { return } self.delegate?.networkIntegration(self, loadDidFailWith: error, for: photo) } } } - + let task = KingfisherManager.shared.retrieveImage(with: url, options: nil, progressBlock: progress, completionHandler: completion) - self.retrieveImageTasks.setObject(task, forKey: photo) + self.retrieveImageTasks[photo.hash] = task } - + func cancelLoad(for photo: AXPhotoProtocol) { - guard let downloadTask = self.retrieveImageTasks.object(forKey: photo) else { - return - } - + guard let downloadTask = self.retrieveImageTasks[photo.hash] else { return } downloadTask.cancel() } - + func cancelAllLoads() { - let enumerator = self.retrieveImageTasks.objectEnumerator() - - while let downloadTask = enumerator?.nextObject() as? RetrieveImageTask { - downloadTask.cancel() - } - - self.retrieveImageTasks.removeAllObjects() + self.retrieveImageTasks.forEach({ $1.cancel() }) + self.retrieveImageTasks.removeAll() } } diff --git a/Source/Integrations/NukeIntegration.swift b/Source/Integrations/NukeIntegration.swift index 80eaee1..c0ee0d7 100644 --- a/Source/Integrations/NukeIntegration.swift +++ b/Source/Integrations/NukeIntegration.swift @@ -18,56 +18,36 @@ class NukeIntegration: NSObject, AXNetworkIntegrationProtocol { public func loadPhoto(_ photo: AXPhotoProtocol) { if photo.imageData != nil || photo.image != nil { AXDispatchUtils.executeInBackground { [weak self] in - guard let `self` = self else { - return - } - + guard let `self` = self else { return } self.delegate?.networkIntegration(self, loadDidFinishWith: photo) } return } - guard let url = photo.url else { - return - } + guard let url = photo.url else { return } let progress: ImageTask.ProgressHandler = { [weak self] (_, receivedSize, totalSize) in - guard let `self` = self else { - return - } - AXDispatchUtils.executeInBackground { [weak self] in - guard let `self` = self else { - return - } - + guard let `self` = self else { return } self.delegate?.networkIntegration?(self, didUpdateLoadingProgress: CGFloat(receivedSize) / CGFloat(totalSize), for: photo) } } let completion: ImageTask.Completion = { [weak self] (response, error) in - guard let `self` = self else { - return - } + guard let `self` = self else { return } self.retrieveImageTasks.removeObject(forKey: photo) if let imageData = response?.image.animatedImageData { photo.imageData = imageData AXDispatchUtils.executeInBackground { [weak self] in - guard let `self` = self else { - return - } - + guard let `self` = self else { return } self.delegate?.networkIntegration(self, loadDidFinishWith: photo) } } else if let image = response?.image { photo.image = image AXDispatchUtils.executeInBackground { [weak self] in - guard let `self` = self else { - return - } - + guard let `self` = self else { return } self.delegate?.networkIntegration(self, loadDidFinishWith: photo) } } else { @@ -77,10 +57,7 @@ class NukeIntegration: NSObject, AXNetworkIntegrationProtocol { userInfo: nil ) AXDispatchUtils.executeInBackground { [weak self] in - guard let `self` = self else { - return - } - + guard let `self` = self else { return } self.delegate?.networkIntegration(self, loadDidFailWith: error, for: photo) } } @@ -91,10 +68,7 @@ class NukeIntegration: NSObject, AXNetworkIntegrationProtocol { } func cancelLoad(for photo: AXPhotoProtocol) { - guard let downloadTask = self.retrieveImageTasks.object(forKey: photo) else { - return - } - + guard let downloadTask = self.retrieveImageTasks.object(forKey: photo) else { return } downloadTask.cancel() } diff --git a/Source/Integrations/PINRemoteImageIntegration.swift b/Source/Integrations/PINRemoteImageIntegration.swift index 07706c9..61dc513 100644 --- a/Source/Integrations/PINRemoteImageIntegration.swift +++ b/Source/Integrations/PINRemoteImageIntegration.swift @@ -28,56 +28,36 @@ class PINRemoteImageIntegration: NSObject, AXNetworkIntegrationProtocol, PINRemo func loadPhoto(_ photo: AXPhotoProtocol) { if photo.imageData != nil || photo.image != nil { AXDispatchUtils.executeInBackground { [weak self] in - guard let `self` = self else { - return - } - + guard let `self` = self else { return } self.delegate?.networkIntegration(self, loadDidFinishWith: photo) } return } - guard let url = photo.url else { - return - } + guard let url = photo.url else { return } let progress: PINRemoteImageManagerProgressDownload = { [weak self] (completedBytes, totalBytes) in - guard let `self` = self else { - return - } - AXDispatchUtils.executeInBackground { [weak self] in - guard let `self` = self else { - return - } - + guard let `self` = self else { return } self.delegate?.networkIntegration?(self, didUpdateLoadingProgress: CGFloat(completedBytes) / CGFloat(totalBytes), for: photo) } } let completion: PINRemoteImageManagerImageCompletion = { [weak self] (result) in - guard let `self` = self else { - return - } + guard let `self` = self else { return } self.downloadUUIDs.removeObject(forKey: photo) if let data = result.alternativeRepresentation as? Data { photo.imageData = data AXDispatchUtils.executeInBackground { [weak self] in - guard let `self` = self else { - return - } - + guard let `self` = self else { return } self.delegate?.networkIntegration(self, loadDidFinishWith: photo) } } else if let image = result.image { photo.image = image AXDispatchUtils.executeInBackground { [weak self] in - guard let `self` = self else { - return - } - + guard let `self` = self else { return } self.delegate?.networkIntegration(self, loadDidFinishWith: photo) } } else { @@ -87,27 +67,18 @@ class PINRemoteImageIntegration: NSObject, AXNetworkIntegrationProtocol, PINRemo userInfo: nil ) AXDispatchUtils.executeInBackground { [weak self] in - guard let `self` = self else { - return - } - + guard let `self` = self else { return } self.delegate?.networkIntegration(self, loadDidFailWith: error, for: photo) } } } - guard let uuid = self.imageManager.downloadImage(with: url, options: [], progressDownload: progress, completion: completion) else { - return - } - + guard let uuid = self.imageManager.downloadImage(with: url, options: [], progressDownload: progress, completion: completion) else { return } self.downloadUUIDs.setObject(uuid as NSUUID, forKey: photo) } func cancelLoad(for photo: AXPhotoProtocol) { - guard let uuid = self.downloadUUIDs.object(forKey: photo) else { - return - } - + guard let uuid = self.downloadUUIDs.object(forKey: photo) else { return } self.imageManager.cancelTask(with: uuid as UUID, storeResumeData: true) } @@ -123,10 +94,7 @@ class PINRemoteImageIntegration: NSObject, AXNetworkIntegrationProtocol, PINRemo // MARK: - PINRemoteImageManagerAlternateRepresentationProvider func alternateRepresentation(with data: Data!, options: PINRemoteImageManagerDownloadOptions = []) -> Any! { - guard let `data` = data else { - return nil - } - + guard let `data` = data else { return nil } return data.containsGIF() ? data : nil } diff --git a/Source/Integrations/SDWebImageIntegration.swift b/Source/Integrations/SDWebImageIntegration.swift index e817b21..bb50ab3 100644 --- a/Source/Integrations/SDWebImageIntegration.swift +++ b/Source/Integrations/SDWebImageIntegration.swift @@ -18,56 +18,36 @@ class SDWebImageIntegration: NSObject, AXNetworkIntegrationProtocol { func loadPhoto(_ photo: AXPhotoProtocol) { if photo.imageData != nil || photo.image != nil { AXDispatchUtils.executeInBackground { [weak self] in - guard let `self` = self else { - return - } - + guard let `self` = self else { return } self.delegate?.networkIntegration(self, loadDidFinishWith: photo) } return } - guard let url = photo.url else { - return - } + guard let url = photo.url else { return } let progress: SDWebImageDownloaderProgressBlock = { [weak self] (receivedSize, expectedSize, targetURL) in - guard let `self` = self else { - return - } - AXDispatchUtils.executeInBackground { [weak self] in - guard let `self` = self else { - return - } - + guard let `self` = self else { return } self.delegate?.networkIntegration?(self, didUpdateLoadingProgress: CGFloat(receivedSize) / CGFloat(expectedSize), for: photo) } } let completion: SDInternalCompletionBlock = { [weak self] (image, data, error, cacheType, finished, imageURL) in - guard let `self` = self else { - return - } + guard let `self` = self else { return } self.downloadOperations.removeObject(forKey: photo) if let data = data, data.containsGIF() { photo.imageData = data AXDispatchUtils.executeInBackground { [weak self] in - guard let `self` = self else { - return - } - + guard let `self` = self else { return } self.delegate?.networkIntegration(self, loadDidFinishWith: photo) } } else if let image = image { photo.image = image AXDispatchUtils.executeInBackground { [weak self] in - guard let `self` = self else { - return - } - + guard let `self` = self else { return } self.delegate?.networkIntegration(self, loadDidFinishWith: photo) } } else { @@ -77,27 +57,18 @@ class SDWebImageIntegration: NSObject, AXNetworkIntegrationProtocol { userInfo: nil ) AXDispatchUtils.executeInBackground { [weak self] in - guard let `self` = self else { - return - } - + guard let `self` = self else { return } self.delegate?.networkIntegration(self, loadDidFailWith: error, for: photo) } } } - guard let operation = SDWebImageManager.shared().loadImage(with: url, options: [], progress: progress, completed: completion) else { - return - } - + guard let operation = SDWebImageManager.shared.loadImage(with: url, options: [], progress: progress, completed: completion) else { return } self.downloadOperations.setObject(operation, forKey: photo) } func cancelLoad(for photo: AXPhotoProtocol) { - guard let downloadOperation = self.downloadOperations.object(forKey: photo) else { - return - } - + guard let downloadOperation = self.downloadOperations.object(forKey: photo) else { return } downloadOperation.cancel() } diff --git a/Source/Integrations/SimpleNetworkIntegration.swift b/Source/Integrations/SimpleNetworkIntegration.swift index a161bb5..9186281 100644 --- a/Source/Integrations/SimpleNetworkIntegration.swift +++ b/Source/Integrations/SimpleNetworkIntegration.swift @@ -26,18 +26,13 @@ open class SimpleNetworkIntegration: NSObject, AXNetworkIntegrationProtocol, Sim public func loadPhoto(_ photo: AXPhotoProtocol) { if photo.imageData != nil || photo.image != nil { AXDispatchUtils.executeInBackground { [weak self] in - guard let `self` = self else { - return - } - + guard let `self` = self else { return } self.delegate?.networkIntegration(self, loadDidFinishWith: photo) } return } - guard let url = photo.url else { - return - } + guard let url = photo.url else { return } let dataTask = self.urlSessionWrapper.dataTask(with: url) self.dataTasks.setObject(dataTask, forKey: photo) @@ -46,10 +41,7 @@ open class SimpleNetworkIntegration: NSObject, AXNetworkIntegrationProtocol, Sim } public func cancelLoad(for photo: AXPhotoProtocol) { - guard let dataTask = self.dataTasks.object(forKey: photo) else { - return - } - + guard let dataTask = self.dataTasks.object(forKey: photo) else { return } dataTask.cancel() } @@ -68,16 +60,10 @@ open class SimpleNetworkIntegration: NSObject, AXNetworkIntegrationProtocol, Sim fileprivate func urlSessionWrapper(_ urlSessionWrapper: SimpleNetworkIntegrationURLSessionWrapper, dataTask: URLSessionDataTask, didUpdateProgress progress: CGFloat) { - - guard let photo = self.photos[dataTask.taskIdentifier] else { - return - } + guard let photo = self.photos[dataTask.taskIdentifier] else { return } AXDispatchUtils.executeInBackground { [weak self] in - guard let `self` = self else { - return - } - + guard let `self` = self else { return } self.delegate?.networkIntegration?(self, didUpdateLoadingProgress: progress, for: photo) @@ -88,10 +74,7 @@ open class SimpleNetworkIntegration: NSObject, AXNetworkIntegrationProtocol, Sim task: URLSessionTask, didCompleteWithError error: Error?, object: Any?) { - - guard let photo = self.photos[task.taskIdentifier] else { - return - } + guard let photo = self.photos[task.taskIdentifier] else { return } weak var weakSelf = self func removeDataTask() { @@ -102,18 +85,13 @@ open class SimpleNetworkIntegration: NSObject, AXNetworkIntegrationProtocol, Sim if let error = error { removeDataTask() AXDispatchUtils.executeInBackground { [weak self] in - guard let `self` = self else { - return - } - + guard let `self` = self else { return } self.delegate?.networkIntegration(self, loadDidFailWith: error, for: photo) } return } - guard let data = object as? Data else { - return - } + guard let data = object as? Data else { return } if data.containsGIF() { photo.imageData = data @@ -123,10 +101,7 @@ open class SimpleNetworkIntegration: NSObject, AXNetworkIntegrationProtocol, Sim removeDataTask() AXDispatchUtils.executeInBackground { [weak self] in - guard let `self` = self else { - return - } - + guard let `self` = self else { return } self.delegate?.networkIntegration(self, loadDidFinishWith: photo) } }