From c7581d384278e6feef3975050b9a5a489e386bdc Mon Sep 17 00:00:00 2001 From: "jstephen@redhat.com" Date: Fri, 27 Oct 2023 15:32:15 -0400 Subject: [PATCH] Replace unmaintained moa library with SDWebImage --- Cartfile | 2 +- Cartfile.resolved | 2 +- FreeOTP.xcodeproj/project.pbxproj | 118 ++++++++++++++++++++++++++++- FreeOTP/ImageDownloader.swift | 31 +++----- FreeOTP/TokensViewController.swift | 6 +- 5 files changed, 129 insertions(+), 30 deletions(-) diff --git a/Cartfile b/Cartfile index e7b2652..08f7c55 100644 --- a/Cartfile +++ b/Cartfile @@ -1,3 +1,3 @@ github "norio-nomura/Base32" "0.9.0" -github "evgenyneu/moa" ~> 12.0 github "roberthein/TinyConstraints" ~> 4.0 +github "SDWebImage/SDWebImage" diff --git a/Cartfile.resolved b/Cartfile.resolved index 21f81c9..8d3d5c4 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,3 +1,3 @@ -github "evgenyneu/moa" "12.0.0" +github "SDWebImage/SDWebImage" "5.18.4" github "norio-nomura/Base32" "0.9.0" github "roberthein/TinyConstraints" "4.0.2" diff --git a/FreeOTP.xcodeproj/project.pbxproj b/FreeOTP.xcodeproj/project.pbxproj index 068dc69..957935b 100644 --- a/FreeOTP.xcodeproj/project.pbxproj +++ b/FreeOTP.xcodeproj/project.pbxproj @@ -15,6 +15,8 @@ 2800418823FC56E500256D27 /* SectionHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2800418723FC56E500256D27 /* SectionHeader.swift */; }; 2820C85A23EE53CB002D3695 /* URILockViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2820C85923EE53CB002D3695 /* URILockViewController.swift */; }; 282341B4245A13D000025167 /* RecommendedIconCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 282341B3245A13D000025167 /* RecommendedIconCell.swift */; }; + 282D9E492AEC102C000C6699 /* SDWebImage.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 282D9E482AEC102C000C6699 /* SDWebImage.xcframework */; }; + 282D9E4A2AEC102C000C6699 /* SDWebImage.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 282D9E482AEC102C000C6699 /* SDWebImage.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 282F614D2AD49328008A22F6 /* fa-solid-900.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 282F614A2AD49328008A22F6 /* fa-solid-900.ttf */; }; 282F614E2AD49328008A22F6 /* fa-brands-400.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 282F614B2AD49328008A22F6 /* fa-brands-400.ttf */; }; 282F614F2AD49328008A22F6 /* fa-regular-400.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 282F614C2AD49328008A22F6 /* fa-regular-400.ttf */; }; @@ -61,8 +63,6 @@ F1CA93DA1B56AB9500828B8B /* token.png in Resources */ = {isa = PBXBuildFile; fileRef = F1CA93D61B56AB9500828B8B /* token.png */; }; FC81F0CD278751A90094DEAC /* Base32.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = FC9C895B270B749C00A25825 /* Base32.xcframework */; }; FC81F0CE278751A90094DEAC /* Base32.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = FC9C895B270B749C00A25825 /* Base32.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - FC81F0D2278751AD0094DEAC /* moa.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = FC9C895A270B749C00A25825 /* moa.xcframework */; }; - FC81F0D3278751AD0094DEAC /* moa.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = FC9C895A270B749C00A25825 /* moa.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; FC81F0D4278751AF0094DEAC /* TinyConstraints.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = FC9C8959270B749C00A25825 /* TinyConstraints.xcframework */; }; FC81F0D5278751AF0094DEAC /* TinyConstraints.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = FC9C8959270B749C00A25825 /* TinyConstraints.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; /* End PBXBuildFile section */ @@ -91,8 +91,8 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - FC81F0D3278751AD0094DEAC /* moa.xcframework in Embed Frameworks */, FC81F0D5278751AF0094DEAC /* TinyConstraints.xcframework in Embed Frameworks */, + 282D9E4A2AEC102C000C6699 /* SDWebImage.xcframework in Embed Frameworks */, FC81F0CE278751A90094DEAC /* Base32.xcframework in Embed Frameworks */, ); name = "Embed Frameworks"; @@ -109,6 +109,49 @@ 2800418723FC56E500256D27 /* SectionHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SectionHeader.swift; sourceTree = ""; }; 2820C85923EE53CB002D3695 /* URILockViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URILockViewController.swift; sourceTree = ""; }; 282341B3245A13D000025167 /* RecommendedIconCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendedIconCell.swift; sourceTree = ""; }; + 282D9E1A2AEC0BDE000C6699 /* ManualInputTokenData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManualInputTokenData.swift; sourceTree = ""; }; + 282D9E1C2AEC0BDE000C6699 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + 282D9E1D2AEC0BDE000C6699 /* token.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = token.png; sourceTree = ""; }; + 282D9E1E2AEC0BDE000C6699 /* FontAwesomeIconCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontAwesomeIconCell.swift; sourceTree = ""; }; + 282D9E1F2AEC0BDE000C6699 /* qrcode.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = qrcode.png; sourceTree = ""; }; + 282D9E202AEC0BDE000C6699 /* OTP.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OTP.swift; sourceTree = ""; }; + 282D9E212AEC0BDE000C6699 /* lock.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = lock.png; sourceTree = ""; }; + 282D9E222AEC0BDE000C6699 /* URIParameters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URIParameters.swift; sourceTree = ""; }; + 282D9E232AEC0BDE000C6699 /* URIMainIconViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URIMainIconViewController.swift; sourceTree = ""; }; + 282D9E242AEC0BDE000C6699 /* URILockViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URILockViewController.swift; sourceTree = ""; }; + 282D9E252AEC0BDE000C6699 /* URILabelViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URILabelViewController.swift; sourceTree = ""; }; + 282D9E262AEC0BDE000C6699 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 282D9E272AEC0BDE000C6699 /* ScanViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanViewController.swift; sourceTree = ""; }; + 282D9E292AEC0BDE000C6699 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 282D9E2A2AEC0BDE000C6699 /* TokenStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenStore.swift; sourceTree = ""; }; + 282D9E2B2AEC0BDE000C6699 /* ImageDownloader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageDownloader.swift; sourceTree = ""; }; + 282D9E2C2AEC0BDE000C6699 /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = ""; }; + 282D9E2D2AEC0BDE000C6699 /* URIIconViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URIIconViewController.swift; sourceTree = ""; }; + 282D9E2E2AEC0BDE000C6699 /* ManualToUrlcModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManualToUrlcModule.swift; sourceTree = ""; }; + 282D9E2F2AEC0BDE000C6699 /* KeychainStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainStore.swift; sourceTree = ""; }; + 282D9E302AEC0BDE000C6699 /* ManualAddViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManualAddViewController.swift; sourceTree = ""; }; + 282D9E312AEC0BDE000C6699 /* TokenIcon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenIcon.swift; sourceTree = ""; }; + 282D9E322AEC0BDE000C6699 /* TokensViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokensViewController.swift; sourceTree = ""; }; + 282D9E332AEC0BDE000C6699 /* EmptyStateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyStateView.swift; sourceTree = ""; }; + 282D9E342AEC0BDE000C6699 /* UICollectionViewFlowLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UICollectionViewFlowLayout.swift; sourceTree = ""; }; + 282D9E352AEC0BDE000C6699 /* TokenCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenCell.swift; sourceTree = ""; }; + 282D9E362AEC0BDE000C6699 /* Style.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Style.swift; sourceTree = ""; }; + 282D9E372AEC0BDE000C6699 /* Launch.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Launch.storyboard; sourceTree = ""; }; + 282D9E382AEC0BDE000C6699 /* Device.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Device.swift; sourceTree = ""; }; + 282D9E392AEC0BDE000C6699 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 282D9E3A2AEC0BDE000C6699 /* RTLSupport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RTLSupport.swift; sourceTree = ""; }; + 282D9E3B2AEC0BDE000C6699 /* CircleProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleProgressView.swift; sourceTree = ""; }; + 282D9E3C2AEC0BDE000C6699 /* RecommendedIconCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendedIconCell.swift; sourceTree = ""; }; + 282D9E3D2AEC0BDE000C6699 /* Token.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Token.swift; sourceTree = ""; }; + 282D9E3E2AEC0BDE000C6699 /* AboutViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutViewController.swift; sourceTree = ""; }; + 282D9E3F2AEC0BDE000C6699 /* default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = default.png; sourceTree = ""; }; + 282D9E402AEC0BDE000C6699 /* FreeOTP-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "FreeOTP-Bridging-Header.h"; sourceTree = ""; }; + 282D9E412AEC0BDE000C6699 /* MainNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainNavigationController.swift; sourceTree = ""; }; + 282D9E422AEC0BDE000C6699 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 282D9E432AEC0BDE000C6699 /* iTunesArtwork@2x */ = {isa = PBXFileReference; lastKnownFileType = file; path = "iTunesArtwork@2x"; sourceTree = ""; }; + 282D9E442AEC0BDE000C6699 /* SectionHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SectionHeader.swift; sourceTree = ""; }; + 282D9E452AEC0C94000C6699 /* SDWebImage.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDWebImage.framework; path = "Carthage/Build/SDWebImage.xcframework/ios-arm64_x86_64-simulator/SDWebImage.framework"; sourceTree = ""; }; + 282D9E482AEC102C000C6699 /* SDWebImage.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = SDWebImage.xcframework; path = Carthage/Build/SDWebImage.xcframework; sourceTree = ""; }; 282F614A2AD49328008A22F6 /* fa-solid-900.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "fa-solid-900.ttf"; path = "../../../Downloads/fontawesome-free-6.4.2-web/webfonts/fa-solid-900.ttf"; sourceTree = ""; }; 282F614B2AD49328008A22F6 /* fa-brands-400.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "fa-brands-400.ttf"; path = "../../../Downloads/fontawesome-free-6.4.2-web/webfonts/fa-brands-400.ttf"; sourceTree = ""; }; 282F614C2AD49328008A22F6 /* fa-regular-400.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "fa-regular-400.ttf"; path = "../../../Downloads/fontawesome-free-6.4.2-web/webfonts/fa-regular-400.ttf"; sourceTree = ""; }; @@ -183,8 +226,8 @@ F18FA53A1B571E4800B1CEAD /* CoreGraphics.framework in Frameworks */, F18FA53E1B571E5D00B1CEAD /* Foundation.framework in Frameworks */, F18FA5381B571E3B00B1CEAD /* Photos.framework in Frameworks */, - FC81F0D2278751AD0094DEAC /* moa.xcframework in Frameworks */, F18FA53C1B571E5500B1CEAD /* UIKit.framework in Frameworks */, + 282D9E492AEC102C000C6699 /* SDWebImage.xcframework in Frameworks */, FC81F0CD278751A90094DEAC /* Base32.xcframework in Frameworks */, FC81F0D4278751AF0094DEAC /* TinyConstraints.xcframework in Frameworks */, ); @@ -200,6 +243,54 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 282D9E192AEC0BDE000C6699 /* FreeOTP */ = { + isa = PBXGroup; + children = ( + 282D9E1A2AEC0BDE000C6699 /* ManualInputTokenData.swift */, + 282D9E1B2AEC0BDE000C6699 /* InfoPlist.strings */, + 282D9E1D2AEC0BDE000C6699 /* token.png */, + 282D9E1E2AEC0BDE000C6699 /* FontAwesomeIconCell.swift */, + 282D9E1F2AEC0BDE000C6699 /* qrcode.png */, + 282D9E202AEC0BDE000C6699 /* OTP.swift */, + 282D9E212AEC0BDE000C6699 /* lock.png */, + 282D9E222AEC0BDE000C6699 /* URIParameters.swift */, + 282D9E232AEC0BDE000C6699 /* URIMainIconViewController.swift */, + 282D9E242AEC0BDE000C6699 /* URILockViewController.swift */, + 282D9E252AEC0BDE000C6699 /* URILabelViewController.swift */, + 282D9E262AEC0BDE000C6699 /* Assets.xcassets */, + 282D9E272AEC0BDE000C6699 /* ScanViewController.swift */, + 282D9E282AEC0BDE000C6699 /* Main.storyboard */, + 282D9E2A2AEC0BDE000C6699 /* TokenStore.swift */, + 282D9E2B2AEC0BDE000C6699 /* ImageDownloader.swift */, + 282D9E2C2AEC0BDE000C6699 /* ShareViewController.swift */, + 282D9E2D2AEC0BDE000C6699 /* URIIconViewController.swift */, + 282D9E2E2AEC0BDE000C6699 /* ManualToUrlcModule.swift */, + 282D9E2F2AEC0BDE000C6699 /* KeychainStore.swift */, + 282D9E302AEC0BDE000C6699 /* ManualAddViewController.swift */, + 282D9E312AEC0BDE000C6699 /* TokenIcon.swift */, + 282D9E322AEC0BDE000C6699 /* TokensViewController.swift */, + 282D9E332AEC0BDE000C6699 /* EmptyStateView.swift */, + 282D9E342AEC0BDE000C6699 /* UICollectionViewFlowLayout.swift */, + 282D9E352AEC0BDE000C6699 /* TokenCell.swift */, + 282D9E362AEC0BDE000C6699 /* Style.swift */, + 282D9E372AEC0BDE000C6699 /* Launch.storyboard */, + 282D9E382AEC0BDE000C6699 /* Device.swift */, + 282D9E392AEC0BDE000C6699 /* AppDelegate.swift */, + 282D9E3A2AEC0BDE000C6699 /* RTLSupport.swift */, + 282D9E3B2AEC0BDE000C6699 /* CircleProgressView.swift */, + 282D9E3C2AEC0BDE000C6699 /* RecommendedIconCell.swift */, + 282D9E3D2AEC0BDE000C6699 /* Token.swift */, + 282D9E3E2AEC0BDE000C6699 /* AboutViewController.swift */, + 282D9E3F2AEC0BDE000C6699 /* default.png */, + 282D9E402AEC0BDE000C6699 /* FreeOTP-Bridging-Header.h */, + 282D9E412AEC0BDE000C6699 /* MainNavigationController.swift */, + 282D9E422AEC0BDE000C6699 /* Info.plist */, + 282D9E432AEC0BDE000C6699 /* iTunesArtwork@2x */, + 282D9E442AEC0BDE000C6699 /* SectionHeader.swift */, + ); + path = FreeOTP; + sourceTree = ""; + }; 89F8EFF9256BA8CB00460AA9 /* FreeOTPUITests */ = { isa = PBXGroup; children = ( @@ -326,6 +417,9 @@ FC9C8958270B749C00A25825 /* Frameworks */ = { isa = PBXGroup; children = ( + 282D9E482AEC102C000C6699 /* SDWebImage.xcframework */, + 282D9E452AEC0C94000C6699 /* SDWebImage.framework */, + 282D9E192AEC0BDE000C6699 /* FreeOTP */, FC9C895B270B749C00A25825 /* Base32.xcframework */, FC9C895C270B749C00A25825 /* FontAwesome.xcframework */, FC9C895A270B749C00A25825 /* moa.xcframework */, @@ -548,6 +642,22 @@ /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ + 282D9E1B2AEC0BDE000C6699 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 282D9E1C2AEC0BDE000C6699 /* en */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + 282D9E282AEC0BDE000C6699 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 282D9E292AEC0BDE000C6699 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; F10D88C71B56A3C400482D15 /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( diff --git a/FreeOTP/ImageDownloader.swift b/FreeOTP/ImageDownloader.swift index aada3e6..cfa19a1 100644 --- a/FreeOTP/ImageDownloader.swift +++ b/FreeOTP/ImageDownloader.swift @@ -18,10 +18,10 @@ // limitations under the License. // -import moa import Foundation import Photos import UIKit +import SDWebImage class ImageDownloader : NSObject { fileprivate let DEFAULT = UIImage(contentsOfFile: Bundle.main.path(forResource: "default", ofType: "png")!)! @@ -87,7 +87,7 @@ class ImageDownloader : NSObject { return completion(DEFAULT) } - func fromURL(_ url: URL, completion: @escaping (UIImage) -> Void) { + func fromURL(_ url: URL, _ iv: UIImageView, completion: @escaping (UIImage) -> Void) { switch url.scheme! { case "file": if let img = UIImage(contentsOfFile: url.path) { @@ -100,24 +100,13 @@ class ImageDownloader : NSObject { case "http": fallthrough case "https": - let moa = Moa() - - moa.onError = { - (e, r) -> () in - moa.errorImage = nil // Keep a strong reference to moa - completion(self.DEFAULT) - } - - moa.onSuccess = { - (i: MoaImage) -> MoaImage? in - moa.errorImage = nil // Keep a strong reference to moa - completion(i) - return nil - } - - moa.url = url.absoluteString + iv.sd_setImage(with: url, placeholderImage: self.DEFAULT, + completed: { (image, error, cacheType, url) in + if let image { + completion(image) + } + }) return - default: break } @@ -125,7 +114,7 @@ class ImageDownloader : NSObject { return completion(DEFAULT) } - func fromURI(_ uri: String?, completion: @escaping (UIImage) -> Void) { + func fromURI(_ uri: String?, _ iv: UIImageView, completion: @escaping (UIImage) -> Void) { if var u = uri { if u.hasPrefix("phasset:") { let id = String(u[u.index(u.startIndex, offsetBy: "phasset:".count)...]) @@ -142,7 +131,7 @@ class ImageDownloader : NSObject { } if let remote = URL(string: u) { - return fromURL(remote, completion: completion) + return fromURL(remote, iv, completion: completion) } } } diff --git a/FreeOTP/TokensViewController.swift b/FreeOTP/TokensViewController.swift index e31356d..c5787a0 100644 --- a/FreeOTP/TokensViewController.swift +++ b/FreeOTP/TokensViewController.swift @@ -39,10 +39,10 @@ class TokensViewController : UICollectionViewController, UICollectionViewDelegat // the tokens array private var tokensArray: [Token]! = [] // contains all the tokens as loaded from the store private var searchedTokensArray: [Token]! = [] // contains the filtered tokens - + // search params private var searchingTokens = false - + override func numberOfSections(in collectionView: UICollectionView) -> Int { return 1 } @@ -66,7 +66,7 @@ class TokensViewController : UICollectionViewController, UICollectionViewDelegat if image.hasSuffix("/FreeOTP.app/default.png") { cell.imageView.image = defaultIcon } else { - ImageDownloader(imageSize).fromURI(token.image, completion: { + ImageDownloader(imageSize).fromURI(token.image, cell.imageView, completion: { (image: UIImage) -> Void in UIView.animate(withDuration: 0.3, animations: { cell.imageView.image = image.addImagePadding(x: 30, y: 30)