Skip to content

Commit

Permalink
[Extensions] Switch SDWebImage to Kingfisher
Browse files Browse the repository at this point in the history
  • Loading branch information
kirb committed Jun 23, 2022
1 parent 7196cc9 commit 73fe5ad
Show file tree
Hide file tree
Showing 9 changed files with 130 additions and 83 deletions.
20 changes: 10 additions & 10 deletions Zebra.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
4E339B8027D0E45300F013C1 /* URL+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E339B7F27D0E45300F013C1 /* URL+Additions.swift */; };
4E3B564F2853196D0058F096 /* SourceRefreshController+AppLifecycle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E3B564E2853196D0058F096 /* SourceRefreshController+AppLifecycle.swift */; };
4E5F41C6285C2952003658AA /* libzstd.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EB235B5283E1A7300713CBB /* libzstd.xcframework */; };
4E5F41CD285CB723003658AA /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = 4E5F41CC285CB723003658AA /* Kingfisher */; };
4E6F94472856434D002F5BD9 /* CSProgress+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E6F94462856434D002F5BD9 /* CSProgress+Additions.swift */; };
4E6F945128564BD7002F5BD9 /* CSProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E6F945028564BD7002F5BD9 /* CSProgress.swift */; };
4E7DC8B128589B0C0007392D /* BaseListCollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E7DC8B028589B0C0007392D /* BaseListCollectionViewController.swift */; };
Expand All @@ -61,7 +62,6 @@
4EA26EA627CCBD3B0019A5AA /* LoadingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EA26EA527CCBD3B0019A5AA /* LoadingViewController.swift */; };
4EA26EB727CCDAC80019A5AA /* BaseSceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EA26EB627CCDAC80019A5AA /* BaseSceneDelegate.swift */; };
4EA26EBA27CCEEBC0019A5AA /* BrowseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EA26EB927CCEEBC0019A5AA /* BrowseViewController.swift */; };
4EA26EC127CCF52E0019A5AA /* SDWebImage in Frameworks */ = {isa = PBXBuildFile; productRef = 4EA26EC027CCF52E0019A5AA /* SDWebImage */; };
4EA26EC427CCF6500019A5AA /* DepictionKit in Frameworks */ = {isa = PBXBuildFile; productRef = 4EA26EC327CCF6500019A5AA /* DepictionKit */; };
4EA2F1DD27DA2A0D0080DC35 /* Installed.pack in Resources */ = {isa = PBXBuildFile; fileRef = 4EA2F1DC27DA2A0D0080DC35 /* Installed.pack */; };
4EA893DD27DDABD600E2EC7A /* sandboxed.json in Resources */ = {isa = PBXBuildFile; fileRef = 4EA893DC27DDABD600E2EC7A /* sandboxed.json */; };
Expand Down Expand Up @@ -507,10 +507,10 @@
4EBF6FBB2841084600639096 /* Plains.framework in Frameworks */,
E1428E7927794FC4005B0885 /* Evander in Frameworks */,
4EA26EC427CCF6500019A5AA /* DepictionKit in Frameworks */,
4EA26EC127CCF52E0019A5AA /* SDWebImage in Frameworks */,
4E87FBB52856DB96005C4704 /* libCSProgress.a in Frameworks */,
895071992239E414004AE338 /* libMobileGestalt.tbd in Frameworks */,
898C50432649F9E0002CDC09 /* MessageUI.framework in Frameworks */,
4E5F41CD285CB723003658AA /* Kingfisher in Frameworks */,
E193C67E277A91CA00B2469E /* WebKit.framework in Frameworks */,
89051722237239A9000F0A32 /* libc++.tbd in Frameworks */,
);
Expand Down Expand Up @@ -1355,8 +1355,8 @@
name = Zebra;
packageProductDependencies = (
E1428E7827794FC4005B0885 /* Evander */,
4EA26EC027CCF52E0019A5AA /* SDWebImage */,
4EA26EC327CCF6500019A5AA /* DepictionKit */,
4E5F41CC285CB723003658AA /* Kingfisher */,
);
productName = Zebra;
productReference = 89C5FDDD21B1B13700A10E58 /* Zebra.app */;
Expand Down Expand Up @@ -1437,7 +1437,7 @@
mainGroup = 89C5FDD421B1B13700A10E58;
packageReferences = (
E1428E7727794FC4005B0885 /* XCRemoteSwiftPackageReference "Evander" */,
4EA26EBF27CCF52E0019A5AA /* XCRemoteSwiftPackageReference "SDWebImage" */,
4E5F41CB285CB723003658AA /* XCRemoteSwiftPackageReference "Kingfisher" */,
);
productRefGroup = 89C5FDDE21B1B13700A10E58 /* Products */;
projectDirPath = "";
Expand Down Expand Up @@ -2124,12 +2124,12 @@
/* End XCConfigurationList section */

/* Begin XCRemoteSwiftPackageReference section */
4EA26EBF27CCF52E0019A5AA /* XCRemoteSwiftPackageReference "SDWebImage" */ = {
4E5F41CB285CB723003658AA /* XCRemoteSwiftPackageReference "Kingfisher" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/SDWebImage/SDWebImage";
repositoryURL = "https://github.com/onevcat/Kingfisher";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 5.0.0;
minimumVersion = 7.0.0;
};
};
E1428E7727794FC4005B0885 /* XCRemoteSwiftPackageReference "Evander" */ = {
Expand All @@ -2143,10 +2143,10 @@
/* End XCRemoteSwiftPackageReference section */

/* Begin XCSwiftPackageProductDependency section */
4EA26EC027CCF52E0019A5AA /* SDWebImage */ = {
4E5F41CC285CB723003658AA /* Kingfisher */ = {
isa = XCSwiftPackageProductDependency;
package = 4EA26EBF27CCF52E0019A5AA /* XCRemoteSwiftPackageReference "SDWebImage" */;
productName = SDWebImage;
package = 4E5F41CB285CB723003658AA /* XCRemoteSwiftPackageReference "Kingfisher" */;
productName = Kingfisher;
};
4EA26EC327CCF6500019A5AA /* DepictionKit */ = {
isa = XCSwiftPackageProductDependency;
Expand Down
8 changes: 4 additions & 4 deletions Zebra.xcworkspace/xcshareddata/swiftpm/Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@
}
},
{
"package": "SDWebImage",
"repositoryURL": "https://github.com/SDWebImage/SDWebImage",
"package": "Kingfisher",
"repositoryURL": "https://github.com/onevcat/Kingfisher",
"state": {
"branch": null,
"revision": "2e63d0061da449ad0ed130768d05dceb1496de44",
"version": "5.12.5"
"revision": "022e4eeb79f817748544b318b991d9a70036bbf8",
"version": "7.2.4"
}
}
]
Expand Down
9 changes: 7 additions & 2 deletions Zebra/Controllers/App/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import UIKit
import os.log
import SDWebImage
import Kingfisher

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
Expand All @@ -32,7 +32,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate {

_ = SourceRefreshController.shared

SDImageCache.shared.config.maxDiskAge = 1 * 24 * 60 * 60 // 1 day
KingfisherManager.shared.defaultOptions = [
.transition(.fade(0.2)),
.cacheOriginalImage,
.backgroundDecode
]
KingfisherManager.shared.downloader.sessionConfiguration = URLSession.image.configuration

UITabBarItem.appearance().badgeColor = .badge

Expand Down
50 changes: 50 additions & 0 deletions Zebra/Extensions/UIImage+Additions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,56 @@
//

import UIKit
import Kingfisher

extension UIImageView {

/// > Note: Wait till the image view has been laid out before calling this. If `frame.size == .zero`,
/// > the image load will be skipped. Call this from `layoutSubviews` to ensure relayout as needed.
func load(url: URL?, usingScale: Bool = false, fallbackImage: UIImage? = nil) {
let scale = window?.screen.scale ?? UIScreen.main.scale
var sources = [Kingfisher.Source]()

if let url = url?.secureURL {
// Scaled image
if usingScale && scale != 1 {
let fileBaseName = url
.deletingPathExtension()
.lastPathComponent
.replacingOccurrences(regex: "@\\d+x$", with: "")

let numberFormatter = NumberFormatter()
numberFormatter.maximumFractionDigits = 1

let scaledURL = url/".."/"\(fileBaseName)@\(numberFormatter.string(for: scale)!)x.\(url.pathExtension)"
if scaledURL != url {
sources += [.network(scaledURL)]
}
}

// Originally supplied url
sources += [.network(url)]
}

if sources.isEmpty || frame.size == .zero {
kf.cancelDownloadTask()
image = fallbackImage
return
}

image = nil
let primarySource = sources.removeFirst()
kf.setImage(with: primarySource,
placeholder: fallbackImage,
options: [
.keepCurrentImageWhileLoading,
.processor(DownsamplingImageProcessor(size: frame.size)),
.scaleFactor(scale),
.alternativeSources(sources)
])
}

}

extension UIImage.SymbolConfiguration {

Expand Down
37 changes: 37 additions & 0 deletions Zebra/Extensions/URL+Additions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,47 @@

import Foundation

fileprivate let permittedInsecureDomains: [String] = {
if let ats = Bundle.main.object(forInfoDictionaryKey: "NSAppTransportSecurity") as? [String: Any],
let exceptions = ats["NSExceptionDomains"] as? [String: [String: Any]] {
return exceptions.compactMap { key, value in (value["NSExceptionAllowsInsecureHTTPLoads"] as? Bool) ?? false ? key : nil }
}
return []
}()

extension URL {
static func / (lhs: URL, rhs: String) -> URL {
rhs == ".." ? lhs.deletingLastPathComponent() : lhs.appendingPathComponent(rhs)
}

/// Return a URL that can be loaded, or at least attempted to be loaded, within App Transport
/// Security restrictions.
var secureURL: URL? {
switch scheme {
case "http":
if let host = host,
permittedInsecureDomains.contains(host) {
return self
}

guard var url = URLComponents(url: self, resolvingAgainstBaseURL: true) else {
return nil
}
url.scheme = "https"
return url.url

case "https", "file":
return self

default:
return nil
}
}

/// Return a cleaned URL for display.
var displayString: String {
absoluteString.replacingOccurrences(regex: "^https?://|/$", with: "")
}
}

extension FileManager {
Expand Down
20 changes: 14 additions & 6 deletions Zebra/Extensions/URLSession+Additions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,28 @@ import Foundation
extension URLSession {

static let standard: URLSession = {
let config = URLSessionConfiguration.default.copy() as! URLSessionConfiguration
config.httpCookieStorage = nil
config.httpCookieAcceptPolicy = .never
config.httpAdditionalHeaders = URLController.httpHeaders
config.tlsMinimumSupportedProtocolVersion = .TLSv12
return URLSession(configuration: config)
}()

static let image: URLSession = {
let config = URLSessionConfiguration.ephemeral.copy() as! URLSessionConfiguration
// Disable setting or storing cookies. Requests made via zbra_standardSession shouldn’t be
// using cookies.
config.urlCache = nil
config.httpCookieStorage = nil
config.httpCookieAcceptPolicy = .never
config.httpAdditionalHeaders = URLController.httpHeaders
config.tlsMinimumSupportedProtocolVersion = .TLSv12
return URLSession(configuration: config)
}()

static let download: URLSession = {
let config = URLSessionConfiguration.default.copy() as! URLSessionConfiguration
// Disable setting or storing cookies. Requests made via zbra_standardSession shouldn’t be
// using cookies.
config.httpMaximumConnectionsPerHost = 8
let config = URLSessionConfiguration.ephemeral.copy() as! URLSessionConfiguration
config.httpCookieStorage = nil
config.httpCookieAcceptPolicy = .never
config.httpAdditionalHeaders = URLController.aptHeaders
config.tlsMinimumSupportedProtocolVersion = .TLSv12
return URLSession(configuration: config)
Expand Down
57 changes: 3 additions & 54 deletions Zebra/UI/Common/IconImageView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,16 @@
//

import UIKit
import SDWebImage

class IconImageView: UIView {

var image: UIImage? {
get { imageView.image }
set {
imageView.sd_cancelCurrentImageLoad()
imageView.load(url: nil)
imageView.image = newValue
}
}
var imageURL: URL? {
didSet { updateImageURL() }
}
var fallbackImage: UIImage?

private var backgroundView: UIView!
private var imageView: UIImageView!
Expand All @@ -44,7 +39,6 @@ class IconImageView: UIView {
imageView.layer.cornerCurve = .continuous
imageView.layer.minificationFilter = .trilinear
imageView.layer.magnificationFilter = .trilinear
imageView.sd_imageTransition = .fade(duration: 0.2)
addSubview(imageView)

borderView = UIView(frame: bounds)
Expand Down Expand Up @@ -78,53 +72,8 @@ class IconImageView: UIView {
borderView.layer.borderColor = UIColor.separator.cgColor
}

func setImageURL(_ imageURL: URL, fallbackImage: UIImage? = nil) {
self.fallbackImage = fallbackImage
self.imageURL = imageURL
}

private func loadImage(url: URL, completion: SDExternalCompletionBlock? = nil) {
imageView.sd_imageTransition = .fade(duration: 0.2)
imageView.sd_setImage(with: url,
placeholderImage: fallbackImage,
options: [.delayPlaceholder, .decodeFirstFrameOnly, .scaleDownLargeImages],
completed: completion)
}

private func updateImageURL() {
imageView.sd_cancelCurrentImageLoad()

guard let imageURL = imageURL,
var url = URLComponents(url: imageURL, resolvingAgainstBaseURL: true) else {
imageView.image = fallbackImage
return
}

imageView.image = nil

// TODO: The retina scaling fallback is broken
let scale = window?.screen.scale ?? UIScreen.main.scale
if true||scale == 1 {
loadImage(url: imageURL)
} else {
// Try native scale first, falling back to original url.
var fileBaseName = (imageURL.lastPathComponent as NSString).deletingPathExtension
fileBaseName = fileBaseName.replacingOccurrences(regex: "@\\d+x$", with: "")

let numberFormatter = NumberFormatter()
numberFormatter.maximumFractionDigits = 1

var pathComponents = imageURL.pathComponents
pathComponents.removeLast()
pathComponents.append("\(fileBaseName)@\(numberFormatter.string(for: scale)!)x.\(imageURL.pathExtension)")
url.path = pathComponents.joined(separator: "/")
loadImage(url: url.url!) { image, _, _, _ in
if image == nil {
// Fall back to original url.
self.imageView.sd_setImage(with: imageURL)
}
}
}
func setImageURL(_ url: URL?, usingScale: Bool = true, fallbackImage: UIImage? = nil) {
imageView.load(url: url, usingScale: usingScale, fallbackImage: fallbackImage)
}

}
9 changes: 4 additions & 5 deletions Zebra/UI/Sources/ZBSourceAddViewController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#import "Zebra-Swift.h"

#import <Plains/Plains.h>
#import <SDWebImage/SDWebImage.h>

@interface ZBSourceAddViewController () {
UISearchController *searchController;
Expand Down Expand Up @@ -275,7 +274,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
cell.sourceLabel.hidden = NO;
cell.sourceLabel.text = clipboardSource.origin;
cell.urlLabel.text = NSLocalizedString(@"From your clipboard", @"");
[cell.iconImageView sd_setImageWithURL:clipboardSource.iconURL placeholderImage:[UIImage imageNamed:@"Unknown"]];
// [cell.iconImageView sd_setImageWithURL:clipboardSource.iconURL placeholderImage:[UIImage imageNamed:@"Unknown"]];
}
} else if (indexPath.section == 1 && searchTermIsEmpty) {
if (indexPath.row == 0) {
Expand All @@ -297,7 +296,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
cell.sourceLabel.hidden = NO;
cell.sourceLabel.text = manager[@"name"];
cell.urlLabel.text = manager[@"label"];
[cell.iconImageView sd_setImageWithURL:[NSURL URLWithString:manager[@"icon"]] placeholderImage:[UIImage imageNamed:@"Unknown"]];
// [cell.iconImageView sd_setImageWithURL:[NSURL URLWithString:manager[@"icon"]] placeholderImage:[UIImage imageNamed:@"Unknown"]];
}
} else if (indexPath.section == 2 && searchTermIsURL) {
if (enteredSource) {
Expand All @@ -323,7 +322,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
cell.sourceLabel.hidden = NO;
cell.sourceLabel.text = enteredSource.origin;
cell.urlLabel.text = enteredSource.repositoryURI;
[cell.iconImageView sd_setImageWithURL:enteredSource.iconURL placeholderImage:[UIImage imageNamed:@"Unknown"]];
// [cell.iconImageView sd_setImageWithURL:enteredSource.iconURL placeholderImage:[UIImage imageNamed:@"Unknown"]];
}
}
} else if (indexPath.section == 3) {
Expand All @@ -343,7 +342,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
cell.sourceLabel.text = source.origin;
cell.urlLabel.text = source.repositoryURI;

[cell.iconImageView sd_setImageWithURL:source.iconURL placeholderImage:[UIImage imageNamed:@"Unknown"]];
// [cell.iconImageView sd_setImageWithURL:source.iconURL placeholderImage:[UIImage imageNamed:@"Unknown"]];
}

return cell;
Expand Down
Loading

0 comments on commit 73fe5ad

Please sign in to comment.