diff --git a/Pods/CropViewController/Swift/CropViewController/CropViewController.swift b/Pods/CropViewController/Swift/CropViewController/CropViewController.swift index 6a57b4d..a8a3520 100644 --- a/Pods/CropViewController/Swift/CropViewController/CropViewController.swift +++ b/Pods/CropViewController/Swift/CropViewController/CropViewController.swift @@ -48,7 +48,7 @@ public typealias CropViewCroppingStyle = TOCropViewCroppingStyle @param angle The angle of the image when it was cropped */ @objc optional func cropViewController(_ cropViewController: CropViewController, didCropImageToRect rect: CGRect, angle: Int) - + /** Called when the user has committed the crop action, and provides both the original image with crop co-ordinates. @@ -58,7 +58,7 @@ public typealias CropViewCroppingStyle = TOCropViewCroppingStyle @param angle The angle of the image when it was cropped */ @objc optional func cropViewController(_ cropViewController: CropViewController, didCropToImage image: UIImage, withRect cropRect: CGRect, angle: Int) - + /** If the cropping style is set to circular, implementing this delegate will return a circle-cropped version of the selected image, as well as it's cropping co-ordinates @@ -68,7 +68,7 @@ public typealias CropViewCroppingStyle = TOCropViewCroppingStyle @param angle The angle of the image when it was cropped */ @objc optional func cropViewController(_ cropViewController: CropViewController, didCropToCircularImage image: UIImage, withRect cropRect: CGRect, angle: Int) - + /** If implemented, when the user hits cancel, or completes a UIActivityViewController operation, this delegate will be called, @@ -85,12 +85,12 @@ public typealias CropViewCroppingStyle = TOCropViewCroppingStyle ///------------------------------------------------ open class CropViewController: UIViewController, TOCropViewControllerDelegate { - + /** The original, uncropped image that was passed to this controller. */ public var image: UIImage { return self.toCropViewController.image } - + /** The view controller's delegate that will receive the resulting cropped image, as well as crop information. @@ -98,7 +98,7 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { public var delegate: CropViewControllerDelegate? { didSet { self.setUpDelegateHandlers() } } - + /** Set the title text that appears at the top of the view controller */ @@ -106,7 +106,7 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { set { toCropViewController.title = newValue } get { return toCropViewController.title } } - + /** If true, when the user hits 'Done', a UIActivityController will appear before the view controller ends. @@ -115,7 +115,7 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { set { toCropViewController.showActivitySheetOnDone = newValue } get { return toCropViewController.showActivitySheetOnDone } } - + /** In the coordinate space of the image itself, the region that is currently being highlighted by the crop box. @@ -127,7 +127,7 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { set { toCropViewController.imageCropFrame = newValue } get { return toCropViewController.imageCropFrame } } - + /** The angle in which the image is rotated in the crop view. This can only be in 90 degree increments (eg, 0, 90, 180, 270). @@ -139,14 +139,14 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { set { toCropViewController.angle = newValue } get { return toCropViewController.angle } } - + /** The cropping style of this particular crop view controller */ public var croppingStyle: CropViewCroppingStyle { return toCropViewController.croppingStyle } - + /** A choice from one of the pre-defined aspect ratio presets */ @@ -154,7 +154,7 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { set { toCropViewController.aspectRatioPreset = newValue } get { return toCropViewController.aspectRatioPreset } } - + /** A CGSize value representing a custom aspect ratio, not listed in the presets. E.g. A ratio of 4:3 would be represented as (CGSize){4.0f, 3.0f} @@ -163,14 +163,14 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { set { toCropViewController.customAspectRatio = newValue } get { return toCropViewController.customAspectRatio } } - + /** Title label which can be used to show instruction on the top of the crop view controller */ public var titleLabel: UILabel? { return toCropViewController.titleLabel } - + /** If true, while it can still be resized, the crop box will be locked to its current aspect ratio. @@ -183,7 +183,7 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { set { toCropViewController.aspectRatioLockEnabled = newValue } get { return toCropViewController.aspectRatioLockEnabled } } - + /** If true, a custom aspect ratio is set, and the aspectRatioLockEnabled is set to true, the crop box will swap it's dimensions depending on portrait or landscape sized images. This value also controls whether the dimensions can swap when the image is rotated. @@ -193,7 +193,7 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { set { toCropViewController.aspectRatioLockDimensionSwapEnabled = newValue } get { return toCropViewController.aspectRatioLockDimensionSwapEnabled } } - + /** If true, tapping the reset button will also reset the aspect ratio back to the image default ratio. Otherwise, the reset will just zoom out to the current aspect ratio. @@ -207,7 +207,7 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { set { toCropViewController.resetAspectRatioEnabled = newValue } get { return toCropViewController.resetAspectRatioEnabled } } - + /** The position of the Toolbar the default value is `TOCropViewControllerToolbarPositionBottom`. */ @@ -215,7 +215,7 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { set { toCropViewController.toolbarPosition = newValue } get { return toCropViewController.toolbarPosition } } - + /** When disabled, an additional rotation button that rotates the canvas in 90-degree segments in a clockwise direction is shown in the toolbar. @@ -226,7 +226,7 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { set { toCropViewController.rotateClockwiseButtonHidden = newValue } get { return toCropViewController.rotateClockwiseButtonHidden } } - + /** When enabled, hides the rotation button, as well as the alternative rotation button visible when `showClockwiseRotationButton` is set to true. @@ -246,7 +246,7 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { set { toCropViewController.resetButtonHidden = newValue } get { return toCropViewController.resetButtonHidden } } - + /** When enabled, hides the 'Aspect Ratio Picker' button on the toolbar. @@ -256,7 +256,7 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { set { toCropViewController.aspectRatioPickerButtonHidden = newValue } get { return toCropViewController.aspectRatioPickerButtonHidden } } - + /** If `showActivitySheetOnDone` is true, then these activity items will be supplied to that UIActivityViewController in addition to the @@ -266,7 +266,7 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { set { toCropViewController.activityItems = newValue } get { return toCropViewController.activityItems } } - + /** If `showActivitySheetOnDone` is true, then you may specify any custom activities your app implements in this array. If your activity requires @@ -277,7 +277,7 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { set { toCropViewController.applicationActivities = newValue } get { return toCropViewController.applicationActivities } } - + /** If `showActivitySheetOnDone` is true, then you may expliclty set activities that won't appear in the share sheet here. @@ -286,17 +286,17 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { set { toCropViewController.excludedActivityTypes = newValue } get { return toCropViewController.excludedActivityTypes } } - + /** When the user hits cancel, or completes a UIActivityViewController operation, this block will be called, giving you a chance to manually dismiss the view controller */ - public var onDidFinishCancelled: ((Bool) -> (Void))? { + public var onDidFinishCancelled: ((Bool) -> Void)? { set { toCropViewController.onDidFinishCancelled = newValue } get { return toCropViewController.onDidFinishCancelled } } - + /** Called when the user has committed the crop action, and provides just the cropping rectangle. @@ -304,11 +304,11 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { @param cropRect A rectangle indicating the crop region of the image the user chose (In the original image's local co-ordinate space) @param angle The angle of the image when it was cropped */ - public var onDidCropImageToRect: ((CGRect, Int) -> (Void))? { + public var onDidCropImageToRect: ((CGRect, Int) -> Void)? { set { toCropViewController.onDidCropImageToRect = newValue } get { return toCropViewController.onDidCropImageToRect } } - + /** Called when the user has committed the crop action, and provides both the cropped image with crop co-ordinates. @@ -317,11 +317,11 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { @param cropRect A rectangle indicating the crop region of the image the user chose (In the original image's local co-ordinate space) @param angle The angle of the image when it was cropped */ - public var onDidCropToRect: ((UIImage, CGRect, NSInteger) -> (Void))? { + public var onDidCropToRect: ((UIImage, CGRect, NSInteger) -> Void)? { set { toCropViewController.onDidCropToRect = newValue } get { return toCropViewController.onDidCropToRect } } - + /** If the cropping style is set to circular, this block will return a circle-cropped version of the selected image, as well as it's cropping co-ordinates @@ -330,7 +330,7 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { @param cropRect A rectangle indicating the crop region of the image the user chose (In the original image's local co-ordinate space) @param angle The angle of the image when it was cropped */ - public var onDidCropToCircleImage: ((UIImage, CGRect, NSInteger) -> (Void))? { + public var onDidCropToCircleImage: ((UIImage, CGRect, NSInteger) -> Void)? { set { toCropViewController.onDidCropToCircleImage = newValue } get { return toCropViewController.onDidCropToCircleImage } } @@ -341,7 +341,7 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { public var cropView: TOCropView { return toCropViewController.cropView } - + /** The toolbar managed by this view controller. */ @@ -356,7 +356,7 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { set { toCropViewController.hidesNavigationBar = newValue } get { return toCropViewController.hidesNavigationBar } } - + /** Title for the 'Done' button. Setting this will override the Default which is a localized string for "Done". @@ -365,7 +365,7 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { set { toCropViewController.doneButtonTitle = newValue } get { return toCropViewController.doneButtonTitle } } - + /** Title for the 'Cancel' button. Setting this will override the Default which is a localized string for "Cancel". @@ -374,13 +374,13 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { set { toCropViewController.cancelButtonTitle = newValue } get { return toCropViewController.cancelButtonTitle } } - + /** This class internally manages and abstracts access to a `TOCropViewController` instance :nodoc: */ internal let toCropViewController: TOCropViewController! - + /** Forward status bar status style changes to the crop view controller :nodoc: @@ -388,7 +388,7 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { open override var childForStatusBarStyle: UIViewController? { return toCropViewController } - + /** Forward status bar status visibility changes to the crop view controller :nodoc: @@ -396,27 +396,27 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { open override var childForStatusBarHidden: UIViewController? { return toCropViewController } - + open override var prefersStatusBarHidden: Bool { return false } - + open override var preferredStatusBarStyle: UIStatusBarStyle { return toCropViewController.preferredStatusBarStyle } - + open override var preferredScreenEdgesDeferringSystemGestures: UIRectEdge { if #available(iOS 11.0, *) { return toCropViewController.preferredScreenEdgesDeferringSystemGestures } - + return UIRectEdge.all } - + ///------------------------------------------------ /// @name Object Creation ///------------------------------------------------ - + /** Creates a new instance of a crop view controller with the supplied image @@ -427,7 +427,7 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { super.init(nibName: nil, bundle: nil) setUpCropController() } - + /** Creates a new instance of a crop view controller with the supplied image and cropping style @@ -439,26 +439,26 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { super.init(nibName: nil, bundle: nil) setUpCropController() } - + required public init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } - + open override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - + // Defer adding the view until we're about to be presented if toCropViewController.view.superview == nil { view.addSubview(toCropViewController.view) } } - + open override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() toCropViewController.view.frame = view.bounds toCropViewController.viewDidLayoutSubviews() } - + /** Resets object of TOCropViewController class as if user pressed reset button in the bottom bar themself */ @@ -476,7 +476,7 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { public func setAspectRatioPreset(_ aspectRatio: CropViewControllerAspectRatioPreset, animated: Bool) { toCropViewController.setAspectRatioPresent(aspectRatio, animated: animated) } - + /** Play a custom animation of the target image zooming to its position in the crop controller while the background fades in. @@ -488,11 +488,10 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { @param completion A block that is called once the transition animation is completed. */ public func presentAnimatedFrom(_ viewController: UIViewController, fromView view: UIView?, fromFrame frame: CGRect, - setup: (() -> (Void))?, completion: (() -> (Void))?) - { + setup: (() -> Void)?, completion: (() -> Void)?) { toCropViewController.presentAnimatedFrom(viewController, view: view, frame: frame, setup: setup, completion: completion) } - + /** Play a custom animation of the target image zooming to its position in the crop controller while the background fades in. Additionally, if you're @@ -511,13 +510,12 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { */ public func presentAnimatedFrom(_ viewController: UIViewController, fromImage image: UIImage?, fromView: UIView?, fromFrame: CGRect, angle: Int, toImageFrame toFrame: CGRect, - setup: (() -> (Void))?, completion:(() -> (Void))?) - { + setup: (() -> Void)?, completion:(() -> Void)?) { toCropViewController.presentAnimatedFrom(viewController, fromImage: image, fromView: fromView, fromFrame: fromFrame, angle: angle, toFrame: toFrame, setup: setup, completion: completion) } - + /** Play a custom animation of the supplied cropped image zooming out from the cropped frame to the specified frame as the rest of the content fades out. @@ -530,11 +528,10 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { @param completion A block that is called once the transition animation is completed. */ public func dismissAnimatedFrom(_ viewController: UIViewController, toView: UIView?, toFrame: CGRect, - setup: (() -> (Void))?, completion:(() -> (Void))?) - { + setup: (() -> Void)?, completion:(() -> Void)?) { toCropViewController.dismissAnimatedFrom(viewController, toView: toView, toFrame: toFrame, setup: setup, completion: completion) } - + /** Play a custom animation of the supplied cropped image zooming out from the cropped frame to the specified frame as the rest of the content fades out. @@ -548,8 +545,7 @@ open class CropViewController: UIViewController, TOCropViewControllerDelegate { @param completion A block that is called once the transition animation is completed. */ public func dismissAnimatedFrom(_ viewController: UIViewController, withCroppedImage croppedImage: UIImage?, toView: UIView?, - toFrame: CGRect, setup: (() -> (Void))?, completion:(() -> (Void))?) - { + toFrame: CGRect, setup: (() -> Void)?, completion:(() -> Void)?) { toCropViewController.dismissAnimatedFrom(viewController, croppedImage: croppedImage, toView: toView, toFrame: toFrame, setup: setup, completion: completion) } @@ -562,7 +558,7 @@ extension CropViewController { toCropViewController.delegate = self toCropViewController.didMove(toParent: self) } - + fileprivate func setUpDelegateHandlers() { guard let delegate = self.delegate else { onDidCropToRect = nil @@ -571,25 +567,25 @@ extension CropViewController { onDidFinishCancelled = nil return } - + if delegate.responds(to: #selector(CropViewControllerDelegate.cropViewController(_:didCropImageToRect:angle:))) { self.onDidCropImageToRect = {[unowned self] rect, angle in delegate.cropViewController!(self, didCropImageToRect: rect, angle: angle) } } - + if delegate.responds(to: #selector(CropViewControllerDelegate.cropViewController(_:didCropToImage:withRect:angle:))) { self.onDidCropToRect = {[unowned self] image, rect, angle in delegate.cropViewController!(self, didCropToImage: image, withRect: rect, angle: angle) } } - + if delegate.responds(to: #selector(CropViewControllerDelegate.cropViewController(_:didCropToCircularImage:withRect:angle:))) { self.onDidCropToCircleImage = {[unowned self] image, rect, angle in delegate.cropViewController!(self, didCropToCircularImage: image, withRect: rect, angle: angle) } } - + if delegate.responds(to: #selector(CropViewControllerDelegate.cropViewController(_:didFinishCancelled:))) { self.onDidFinishCancelled = {[unowned self] finished in delegate.cropViewController!(self, didFinishCancelled: finished) @@ -597,4 +593,3 @@ extension CropViewController { } } } - diff --git a/Pods/Kingfisher/Sources/Cache/CacheSerializer.swift b/Pods/Kingfisher/Sources/Cache/CacheSerializer.swift index ea72c72..e320047 100644 --- a/Pods/Kingfisher/Sources/Cache/CacheSerializer.swift +++ b/Pods/Kingfisher/Sources/Cache/CacheSerializer.swift @@ -30,7 +30,7 @@ import Foundation /// retrieving it from disk storage, and vice versa, to convert an image to data object /// for storing to the disk storage. public protocol CacheSerializer { - + /// Gets the serialized data from a provided image /// and optional original data for caching to disk. /// @@ -51,7 +51,7 @@ public protocol CacheSerializer { /// - Returns: An image deserialized or `nil` when no valid image /// could be deserialized. func image(with data: Data, options: KingfisherParsedOptionsInfo) -> Image? - + /// Gets an image deserialized from provided data. /// /// - Parameters: @@ -77,11 +77,11 @@ extension CacheSerializer { /// It could serialize and deserialize images in PNG, JPEG and GIF format. For /// image other than these formats, a normalized `pngRepresentation` will be used. public struct DefaultCacheSerializer: CacheSerializer { - + /// The default general cache serializer used across Kingfisher's cache. public static let `default` = DefaultCacheSerializer() private init() {} - + /// - Parameters: /// - image: The image needed to be serialized. /// - original: The original data which is just downloaded. @@ -99,7 +99,7 @@ public struct DefaultCacheSerializer: CacheSerializer { public func data(with image: Image, original: Data?) -> Data? { return image.kf.data(format: original?.kf.imageFormat ?? .unknown) } - + /// Gets an image deserialized from provided data. /// /// - Parameters: diff --git a/Pods/Kingfisher/Sources/Cache/DiskStorage.swift b/Pods/Kingfisher/Sources/Cache/DiskStorage.swift index c0c8d61..c540634 100644 --- a/Pods/Kingfisher/Sources/Cache/DiskStorage.swift +++ b/Pods/Kingfisher/Sources/Cache/DiskStorage.swift @@ -26,7 +26,6 @@ import Foundation - /// Represents a set of conception related to storage which stores a certain type of value in disk. /// This is a namespace for the disk storage types. A `Backend` with a certain `Config` will be used to describe the /// storage. See these composed types for more information. @@ -94,12 +93,11 @@ public enum DiskStorage { func store( value: T, forKey key: String, - expiration: StorageExpiration? = nil) throws - { + expiration: StorageExpiration? = nil) throws { let expiration = expiration ?? config.expiration // The expiration indicates that already expired, no need to store. guard !expiration.isExpired else { return } - + let data: Data do { data = try value.toData() @@ -110,7 +108,7 @@ public enum DiskStorage { let fileURL = cacheFileURL(forKey: key) let now = Date() - let attributes: [FileAttributeKey : Any] = [ + let attributes: [FileAttributeKey: Any] = [ // The last access date. .creationDate: now.fileAttributeDate, // The estimated expiration date. @@ -214,8 +212,7 @@ public enum DiskStorage { let fileManager = config.fileManager guard let directoryEnumerator = fileManager.enumerator( - at: directoryURL, includingPropertiesForKeys: propertyKeys, options: .skipsHiddenFiles) else - { + at: directoryURL, includingPropertiesForKeys: propertyKeys, options: .skipsHiddenFiles) else { throw KingfisherError.cacheError(reason: .fileEnumeratorCreationFailed(url: directoryURL)) } @@ -315,7 +312,7 @@ extension DiskStorage { /// The preferred extension of cache item. It will be appended to the file name as its extension. /// Default is `nil`, means that the cache file does not contain a file extension. - public var pathExtension: String? = nil + public var pathExtension: String? /// Default is `true`, means that the cache file name will be hashed before storing. public var usesHashedFileName = true @@ -344,8 +341,7 @@ extension DiskStorage { name: String, sizeLimit: UInt, fileManager: FileManager = .default, - directory: URL? = nil) - { + directory: URL? = nil) { self.name = name self.fileManager = fileManager self.directory = directory @@ -356,18 +352,18 @@ extension DiskStorage { extension DiskStorage { struct FileMeta { - + let url: URL - + let lastAccessDate: Date? let estimatedExpirationDate: Date? let isDirectory: Bool let fileSize: Int - + static func lastAccessDate(lhs: FileMeta, rhs: FileMeta) -> Bool { return lhs.lastAccessDate ?? .distantPast > rhs.lastAccessDate ?? .distantPast } - + init(fileURL: URL, resourceKeys: Set) throws { let meta = try fileURL.resourceValues(forKeys: resourceKeys) self.init( @@ -377,14 +373,13 @@ extension DiskStorage { isDirectory: meta.isDirectory ?? false, fileSize: meta.fileSize ?? 0) } - + init( fileURL: URL, lastAccessDate: Date?, estimatedExpirationDate: Date?, isDirectory: Bool, - fileSize: Int) - { + fileSize: Int) { self.url = fileURL self.lastAccessDate = lastAccessDate self.estimatedExpirationDate = estimatedExpirationDate @@ -395,17 +390,16 @@ extension DiskStorage { func expired(referenceDate: Date) -> Bool { return estimatedExpirationDate?.isPast(referenceDate: referenceDate) ?? true } - + func extendExpiration(with fileManager: FileManager) { guard let lastAccessDate = lastAccessDate, - let lastEstimatedExpiration = estimatedExpirationDate else - { + let lastEstimatedExpiration = estimatedExpirationDate else { return } - + let originalExpiration: StorageExpiration = .seconds(lastEstimatedExpiration.timeIntervalSince(lastAccessDate)) - let attributes: [FileAttributeKey : Any] = [ + let attributes: [FileAttributeKey: Any] = [ .creationDate: Date().fileAttributeDate, .modificationDate: originalExpiration.estimatedExpirationSinceNow.fileAttributeDate ] @@ -414,4 +408,3 @@ extension DiskStorage { } } } - diff --git a/Pods/Kingfisher/Sources/Cache/FormatIndicatedCacheSerializer.swift b/Pods/Kingfisher/Sources/Cache/FormatIndicatedCacheSerializer.swift index 442b82c..583af6a 100644 --- a/Pods/Kingfisher/Sources/Cache/FormatIndicatedCacheSerializer.swift +++ b/Pods/Kingfisher/Sources/Cache/FormatIndicatedCacheSerializer.swift @@ -52,25 +52,25 @@ import Foundation /// imageView.kf.setImage(with: url, options: optionsInfo) /// ```` public struct FormatIndicatedCacheSerializer: CacheSerializer { - + /// A `FormatIndicatedCacheSerializer` which converts image from and to PNG format. If the image cannot be /// represented by PNG format, it will fallback to its real format which is determined by `original` data. public static let png = FormatIndicatedCacheSerializer(imageFormat: .PNG) - + /// A `FormatIndicatedCacheSerializer` which converts image from and to JPEG format. If the image cannot be /// represented by JPEG format, it will fallback to its real format which is determined by `original` data. public static let jpeg = FormatIndicatedCacheSerializer(imageFormat: .JPEG) - + /// A `FormatIndicatedCacheSerializer` which converts image from and to GIF format. If the image cannot be /// represented by GIF format, it will fallback to its real format which is determined by `original` data. public static let gif = FormatIndicatedCacheSerializer(imageFormat: .GIF) - + /// The indicated image format. private let imageFormat: ImageFormat - + /// Creates data which represents the given `image` under a format. public func data(with image: Image, original: Data?) -> Data? { - + func imageData(withFormat imageFormat: ImageFormat) -> Data? { switch imageFormat { case .PNG: return image.kf.pngRepresentation() @@ -79,22 +79,22 @@ public struct FormatIndicatedCacheSerializer: CacheSerializer { case .unknown: return nil } } - + // generate data with indicated image format if let data = imageData(withFormat: imageFormat) { return data } - + let originalFormat = original?.kf.imageFormat ?? .unknown - + // generate data with original image's format if originalFormat != imageFormat, let data = imageData(withFormat: originalFormat) { return data } - + return original ?? image.kf.normalized.kf.pngRepresentation() } - + /// Same implementation as `DefaultCacheSerializer`. public func image(with data: Data, options: KingfisherParsedOptionsInfo) -> Image? { return KingfisherWrapper.image(data: data, options: options.imageCreatingOptions) diff --git a/Pods/Kingfisher/Sources/Cache/ImageCache.swift b/Pods/Kingfisher/Sources/Cache/ImageCache.swift index 595fe3d..cb6495a 100644 --- a/Pods/Kingfisher/Sources/Cache/ImageCache.swift +++ b/Pods/Kingfisher/Sources/Cache/ImageCache.swift @@ -57,7 +57,7 @@ public enum CacheType { case memory /// The image is cached in disk. case disk - + /// Whether the cache type represents the image is already cached or not. public var cached: Bool { switch self { @@ -69,10 +69,10 @@ public enum CacheType { /// Represents the caching operation result. public struct CacheStoreResult { - + /// The cache result for memory cache. Caching an image to memory will never fail. public let memoryCacheResult: Result<(), Never> - + /// The cache result for disk cache. If an error happens during caching operation, /// you can get it from `.failure` case of this `diskCacheResult`. public let diskCacheResult: Result<(), KingfisherError> @@ -95,23 +95,22 @@ extension Data: DataTransformable { public static let empty = Data() } - /// Represents the getting image operation from the cache. /// /// - disk: The image can be retrieved from disk cache. /// - memory: The image can be retrieved memory cache. /// - none: The image does not exist in the cache. public enum ImageCacheResult { - + /// The image can be retrieved from disk cache. case disk(Image) - + /// The image can be retrieved memory cache. case memory(Image) - + /// The image does not exist in the cache. case none - + /// Extracts the image from cache result. It returns the associated `Image` value for /// `.disk` and `.memory` case. For `.none` case, `nil` is returned. public var image: Image? { @@ -121,7 +120,7 @@ public enum ImageCacheResult { case .none: return nil } } - + /// Returns the corresponding `CacheType` value based on the result type of `self`. public var cacheType: CacheType { switch self { @@ -152,14 +151,14 @@ open class ImageCache { /// reasonable expire duration and a maximum memory usage. To modify the configuration of a storage, just set /// the storage `config` and its properties. public let memoryStorage: MemoryStorage.Backend - + /// The `DiskStorage.Backend` object used in this cache. This storage stores loaded images in disk with a /// reasonable expire duration and a maximum disk usage. To modify the configuration of a storage, just set /// the storage `config` and its properties. public let diskStorage: DiskStorage.Backend - + private let ioQueue: DispatchQueue - + /// Closure that defines the disk cache path from a given path and cacheName. public typealias DiskCachePathClosure = (URL, String) -> URL @@ -172,8 +171,7 @@ open class ImageCache { /// - diskStorage: The `DiskStorage.Backend` object to use in the image cache. public init( memoryStorage: MemoryStorage.Backend, - diskStorage: DiskStorage.Backend) - { + diskStorage: DiskStorage.Backend) { self.memoryStorage = memoryStorage self.diskStorage = diskStorage let ioQueueName = "com.onevcat.Kingfisher.ImageCache.ioQueue.\(UUID().uuidString)" @@ -196,7 +194,7 @@ open class ImageCache { #endif #elseif os(macOS) notifications = [ - (NSApplication.willResignActiveNotification, #selector(cleanExpiredDiskCache)), + (NSApplication.willResignActiveNotification, #selector(cleanExpiredDiskCache)) ] #else notifications = [] @@ -205,7 +203,7 @@ open class ImageCache { NotificationCenter.default.addObserver(self, selector: $0.1, name: $0.0, object: nil) } } - + /// Creates an `ImageCache` with a given `name`. Both `MemoryStorage` and `DiskStorage` will be created /// with a default config based on the `name`. /// @@ -233,8 +231,7 @@ open class ImageCache { public convenience init( name: String, cacheDirectoryURL: URL?, - diskCachePathClosure: DiskCachePathClosure? = nil) throws - { + diskCachePathClosure: DiskCachePathClosure? = nil) throws { if name.isEmpty { fatalError("[Kingfisher] You should specify a name for the cache. A cache with empty name is not permitted.") } @@ -257,7 +254,7 @@ open class ImageCache { self.init(memoryStorage: memoryStorage, diskStorage: diskStorage) } - + deinit { NotificationCenter.default.removeObserver(self) } @@ -269,15 +266,14 @@ open class ImageCache { forKey key: String, options: KingfisherParsedOptionsInfo, toDisk: Bool = true, - completionHandler: ((CacheStoreResult) -> Void)? = nil) - { + completionHandler: ((CacheStoreResult) -> Void)? = nil) { let identifier = options.processor.identifier let callbackQueue = options.callbackQueue - + let computedKey = key.computedKey(with: identifier) // Memory storage should not throw. memoryStorage.storeNoThrow(value: image, forKey: computedKey, expiration: options.memoryCacheExpiration) - + guard toDisk else { if let completionHandler = completionHandler { let result = CacheStoreResult(memoryCacheResult: .success(()), diskCacheResult: .success(())) @@ -285,7 +281,7 @@ open class ImageCache { } return } - + ioQueue.async { let serializer = options.cacheSerializer if let data = serializer.data(with: image, original: original) { @@ -298,7 +294,7 @@ open class ImageCache { completionHandler: completionHandler) } else { guard let completionHandler = completionHandler else { return } - + let diskError = KingfisherError.cacheError( reason: .cannotSerializeImage(image: image, original: original, serializer: serializer)) let result = CacheStoreResult( @@ -337,15 +333,14 @@ open class ImageCache { cacheSerializer serializer: CacheSerializer = DefaultCacheSerializer.default, toDisk: Bool = true, callbackQueue: CallbackQueue = .untouch, - completionHandler: ((CacheStoreResult) -> Void)? = nil) - { + completionHandler: ((CacheStoreResult) -> Void)? = nil) { struct TempProcessor: ImageProcessor { let identifier: String func process(item: ImageProcessItem, options: KingfisherParsedOptionsInfo) -> Image? { return nil } } - + let options = KingfisherParsedOptionsInfo([ .processor(TempProcessor(identifier: identifier)), .cacheSerializer(serializer), @@ -354,15 +349,14 @@ open class ImageCache { store(image, original: original, forKey: key, options: options, toDisk: toDisk, completionHandler: completionHandler) } - + open func storeToDisk( _ data: Data, forKey key: String, processorIdentifier identifier: String = "", expiration: StorageExpiration? = nil, callbackQueue: CallbackQueue = .untouch, - completionHandler: ((CacheStoreResult) -> Void)? = nil) - { + completionHandler: ((CacheStoreResult) -> Void)? = nil) { ioQueue.async { self.syncStoreToDisk( data, @@ -373,15 +367,14 @@ open class ImageCache { completionHandler: completionHandler) } } - + private func syncStoreToDisk( _ data: Data, forKey key: String, processorIdentifier identifier: String = "", callbackQueue: CallbackQueue = .untouch, expiration: StorageExpiration? = nil, - completionHandler: ((CacheStoreResult) -> Void)? = nil) - { + completionHandler: ((CacheStoreResult) -> Void)? = nil) { let computedKey = key.computedKey(with: identifier) let result: CacheStoreResult do { @@ -394,7 +387,7 @@ open class ImageCache { } else { diskError = .cacheError(reason: .cannotConvertToData(object: data, error: error)) } - + result = CacheStoreResult( memoryCacheResult: .success(()), diskCacheResult: .failure(diskError) @@ -424,16 +417,15 @@ open class ImageCache { fromMemory: Bool = true, fromDisk: Bool = true, callbackQueue: CallbackQueue = .untouch, - completionHandler: (() -> Void)? = nil) - { + completionHandler: (() -> Void)? = nil) { let computedKey = key.computedKey(with: identifier) if fromMemory { try? memoryStorage.remove(forKey: computedKey) } - + if fromDisk { - ioQueue.async{ + ioQueue.async { try? self.diskStorage.remove(forKey: computedKey) if let completionHandler = completionHandler { callbackQueue.execute { completionHandler() } @@ -449,8 +441,7 @@ open class ImageCache { func retrieveImage(forKey key: String, options: KingfisherParsedOptionsInfo, callbackQueue: CallbackQueue = .untouch, - completionHandler: ((Result) -> Void)?) - { + completionHandler: ((Result) -> Void)?) { // No completion handler. No need to start working and early return. guard let completionHandler = completionHandler else { return } @@ -484,8 +475,7 @@ open class ImageCache { finalImage, forKey: key, options: cacheOptions, - toDisk: false) - { + toDisk: false) { _ in completionHandler(.success(.disk(finalImage))) } @@ -511,8 +501,7 @@ open class ImageCache { open func retrieveImage(forKey key: String, options: KingfisherOptionsInfo? = nil, callbackQueue: CallbackQueue = .untouch, - completionHandler: ((Result) -> Void)?) - { + completionHandler: ((Result) -> Void)?) { retrieveImage( forKey: key, options: KingfisherParsedOptionsInfo(options), @@ -522,8 +511,7 @@ open class ImageCache { func retrieveImageInMemoryCache( forKey key: String, - options: KingfisherParsedOptionsInfo) -> Image? - { + options: KingfisherParsedOptionsInfo) -> Image? { let computedKey = key.computedKey(with: options.processor.identifier) do { return try memoryStorage.value(forKey: computedKey) @@ -541,8 +529,7 @@ open class ImageCache { /// has already expired, `nil` is returned. open func retrieveImageInMemoryCache( forKey key: String, - options: KingfisherOptionsInfo? = nil) -> Image? - { + options: KingfisherOptionsInfo? = nil) -> Image? { return retrieveImageInMemoryCache(forKey: key, options: KingfisherParsedOptionsInfo(options)) } @@ -550,13 +537,12 @@ open class ImageCache { forKey key: String, options: KingfisherParsedOptionsInfo, callbackQueue: CallbackQueue = .untouch, - completionHandler: @escaping (Result) -> Void) - { + completionHandler: @escaping (Result) -> Void) { let computedKey = key.computedKey(with: options.processor.identifier) let loadingQueue: CallbackQueue = options.loadDiskFileSynchronously ? .untouch : .dispatch(ioQueue) loadingQueue.execute { do { - var image: Image? = nil + var image: Image? if let data = try self.diskStorage.value(forKey: computedKey) { image = options.cacheSerializer.image(with: data, options: options) } @@ -570,7 +556,7 @@ open class ImageCache { } } } - + /// Gets an image for a given key from the disk storage. /// /// - Parameters: @@ -582,8 +568,7 @@ open class ImageCache { forKey key: String, options: KingfisherOptionsInfo? = nil, callbackQueue: CallbackQueue = .untouch, - completionHandler: @escaping (Result) -> Void) - { + completionHandler: @escaping (Result) -> Void) { retrieveImageInDiskCache( forKey: key, options: KingfisherParsedOptionsInfo(options), @@ -596,12 +581,12 @@ open class ImageCache { @objc public func clearMemoryCache() { try? memoryStorage.removeAll() } - + /// Clears the disk storage of this cache. This is an async operation. /// /// - Parameter handler: A closure which is invoked when the cache clearing operation finishes. /// This `handler` will be called from the main queue. - open func clearDiskCache(completion handler: (()->())? = nil) { + open func clearDiskCache(completion handler: (() -> Void)? = nil) { ioQueue.async { do { try self.diskStorage.removeAll() @@ -616,7 +601,7 @@ open class ImageCache { open func cleanExpiredMemoryCache() { memoryStorage.removeExpired() } - + /// Clears the expired images from disk storage. This is an async operation. @objc func cleanExpiredDiskCache() { cleanExpiredDiskCache(completion: nil) @@ -669,12 +654,12 @@ open class ImageCache { task = UIBackgroundTaskInvalid #endif } - + var backgroundTask: UIBackgroundTaskIdentifier! backgroundTask = sharedApplication.beginBackgroundTask { endBackgroundTask(&backgroundTask!) } - + cleanExpiredDiskCache { endBackgroundTask(&backgroundTask!) } @@ -702,7 +687,7 @@ open class ImageCache { if diskStorage.isCached(forKey: computedKey) { return .disk } return .none } - + /// Returns whether the file exists in cache for a given `key` and `identifier` combination. /// /// - Parameters: @@ -717,11 +702,10 @@ open class ImageCache { /// use `imageCachedType(forKey:processorIdentifier:)` instead. public func isCached( forKey key: String, - processorIdentifier identifier: String = DefaultImageProcessor.default.identifier) -> Bool - { + processorIdentifier identifier: String = DefaultImageProcessor.default.identifier) -> Bool { return imageCachedType(forKey: key, processorIdentifier: identifier).cached } - + /// Gets the hash used as cache file name for the key. /// /// - Parameters: @@ -736,12 +720,11 @@ open class ImageCache { /// if you need. open func hash( forKey key: String, - processorIdentifier identifier: String = DefaultImageProcessor.default.identifier) -> String - { + processorIdentifier identifier: String = DefaultImageProcessor.default.identifier) -> String { let computedKey = key.computedKey(with: identifier) return diskStorage.cacheFileName(forKey: computedKey) } - + /// Calculates the size taken by the disk storage. /// It is the total file size of all cached files in the `diskStorage` on disk in bytes. /// @@ -757,11 +740,11 @@ open class ImageCache { } else { assertionFailure("The internal thrown error should be a `KingfisherError`.") } - + } } } - + /// Gets the cache path for the key. /// It is useful for projects with web view or anyone that needs access to the local file path. /// @@ -780,8 +763,7 @@ open class ImageCache { /// You could use `isCached(forKey:)` method to check whether the image is cached under that key in disk. open func cachePath( forKey key: String, - processorIdentifier identifier: String = DefaultImageProcessor.default.identifier) -> String - { + processorIdentifier identifier: String = DefaultImageProcessor.default.identifier) -> String { let computedKey = key.computedKey(with: identifier) return diskStorage.cacheFileURL(forKey: computedKey).path } @@ -789,7 +771,7 @@ open class ImageCache { extension Dictionary { func keysSortedByValue(_ isOrderedBefore: (Value, Value) -> Bool) -> [Key] { - return Array(self).sorted{ isOrderedBefore($0.1, $1.1) }.map{ $0.0 } + return Array(self).sorted { isOrderedBefore($0.1, $1.1) }.map { $0.0 } } } @@ -835,8 +817,7 @@ extension ImageCache { public convenience init( name: String, path: String?, - diskCachePathClosure: DiskCachePathClosure? = nil) throws - { + diskCachePathClosure: DiskCachePathClosure? = nil) throws { let directoryURL = path.flatMap { URL(string: $0) } try self.init(name: name, cacheDirectoryURL: directoryURL, diskCachePathClosure: diskCachePathClosure) } diff --git a/Pods/Kingfisher/Sources/Cache/MemoryStorage.swift b/Pods/Kingfisher/Sources/Cache/MemoryStorage.swift index 85b1033..bdb6375 100644 --- a/Pods/Kingfisher/Sources/Cache/MemoryStorage.swift +++ b/Pods/Kingfisher/Sources/Cache/MemoryStorage.swift @@ -45,7 +45,7 @@ public enum MemoryStorage { let storage = NSCache>() var keys = Set() - var cleanTimer: Timer? = nil + var cleanTimer: Timer? let lock = NSLock() let cacheDelegate = CacheDelegate>() @@ -99,8 +99,7 @@ public enum MemoryStorage { func store( value: T, forKey key: String, - expiration: StorageExpiration? = nil) throws - { + expiration: StorageExpiration? = nil) throws { storeNoThrow(value: value, forKey: key, expiration: expiration) } @@ -109,14 +108,13 @@ public enum MemoryStorage { func storeNoThrow( value: T, forKey key: String, - expiration: StorageExpiration? = nil) - { + expiration: StorageExpiration? = nil) { lock.lock() defer { lock.unlock() } let expiration = expiration ?? config.expiration // The expiration indicates that already expired, no need to store. guard !expiration.isExpired else { return } - + let object = StorageObject(value, key: key, expiration: expiration) storage.setObject(object, forKey: key as NSString, cost: value.cacheCost) keys.insert(key) @@ -209,21 +207,21 @@ extension MemoryStorage { let value: T let expiration: StorageExpiration let key: String - + private(set) var estimatedExpiration: Date - + init(_ value: T, key: String, expiration: StorageExpiration) { self.value = value self.key = key self.expiration = expiration - + self.estimatedExpiration = expiration.estimatedExpirationSinceNow } - + func extendExpiration() { self.estimatedExpiration = expiration.estimatedExpirationSinceNow } - + var expired: Bool { return estimatedExpiration.isPast } diff --git a/Pods/Kingfisher/Sources/Cache/Storage.swift b/Pods/Kingfisher/Sources/Cache/Storage.swift index 2e96f3f..54003ea 100644 --- a/Pods/Kingfisher/Sources/Cache/Storage.swift +++ b/Pods/Kingfisher/Sources/Cache/Storage.swift @@ -53,11 +53,11 @@ public enum StorageExpiration { case .expired: return .distantPast } } - + var estimatedExpirationSinceNow: Date { return estimatedExpirationSince(Date()) } - + var isExpired: Bool { return timeInterval <= 0 } diff --git a/Pods/Kingfisher/Sources/Extensions/ImageView+Kingfisher.swift b/Pods/Kingfisher/Sources/Extensions/ImageView+Kingfisher.swift index 1793d89..b1e4960 100644 --- a/Pods/Kingfisher/Sources/Extensions/ImageView+Kingfisher.swift +++ b/Pods/Kingfisher/Sources/Extensions/ImageView+Kingfisher.swift @@ -24,7 +24,6 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. - #if os(macOS) import AppKit #else @@ -78,8 +77,7 @@ extension KingfisherWrapper where Base: ImageView { placeholder: Placeholder? = nil, options: KingfisherOptionsInfo? = nil, progressBlock: DownloadProgressBlock? = nil, - completionHandler: ((Result) -> Void)? = nil) -> DownloadTask? - { + completionHandler: ((Result) -> Void)? = nil) -> DownloadTask? { var mutatingSelf = self guard let source = source else { mutatingSelf.placeholder = placeholder @@ -187,8 +185,7 @@ extension KingfisherWrapper where Base: ImageView { placeholder: Placeholder? = nil, options: KingfisherOptionsInfo? = nil, progressBlock: DownloadProgressBlock? = nil, - completionHandler: ((Result) -> Void)? = nil) -> DownloadTask? - { + completionHandler: ((Result) -> Void)? = nil) -> DownloadTask? { return setImage( with: resource.map { .network($0) }, placeholder: placeholder, @@ -218,8 +215,7 @@ extension KingfisherWrapper where Base: ImageView { placeholder: Placeholder? = nil, options: KingfisherOptionsInfo? = nil, progressBlock: DownloadProgressBlock? = nil, - completionHandler: ((Result) -> Void)? = nil) -> DownloadTask? - { + completionHandler: ((Result) -> Void)? = nil) -> DownloadTask? { return setImage( with: provider.map { .provider($0) }, placeholder: placeholder, @@ -305,7 +301,7 @@ extension KingfisherWrapper where Base: ImageView { get { return getAssociatedObject(base, &indicatorTypeKey) ?? .none } - + set { switch newValue { case .none: indicator = nil @@ -317,7 +313,7 @@ extension KingfisherWrapper where Base: ImageView { setRetainedAssociatedObject(base, &indicatorTypeKey, newValue) } } - + /// Holds any type that conforms to the protocol `Indicator`. /// The protocol `Indicator` has a `view` property that will be shown when loading an image. /// It will be `nil` if `indicatorType` is `.none`. @@ -326,25 +322,25 @@ extension KingfisherWrapper where Base: ImageView { let box: Box? = getAssociatedObject(base, &indicatorKey) return box?.value } - + set { // Remove previous if let previousIndicator = indicator { previousIndicator.view.removeFromSuperview() } - + // Add new if let newIndicator = newValue { // Set default indicator layout let view = newIndicator.view - + base.addSubview(view) view.translatesAutoresizingMaskIntoConstraints = false view.centerXAnchor.constraint( equalTo: base.centerXAnchor, constant: newIndicator.centerOffset.x).isActive = true view.centerYAnchor.constraint( equalTo: base.centerYAnchor, constant: newIndicator.centerOffset.y).isActive = true - + newIndicator.view.isHidden = true } @@ -354,7 +350,7 @@ extension KingfisherWrapper where Base: ImageView { setRetainedAssociatedObject(base, &indicatorKey, newValue.map(Box.init)) } } - + private var imageTask: DownloadTask? { get { return getAssociatedObject(base, &imageTaskKey) } set { setRetainedAssociatedObject(base, &imageTaskKey, newValue)} @@ -368,7 +364,7 @@ extension KingfisherWrapper where Base: ImageView { if let previousPlaceholder = placeholder { previousPlaceholder.remove(from: base) } - + if let newPlaceholder = newValue { newPlaceholder.add(to: base) } else { @@ -379,7 +375,6 @@ extension KingfisherWrapper where Base: ImageView { } } - @objc extension ImageView { func shouldPreloadAllAnimation() -> Bool { return true } } diff --git a/Pods/Kingfisher/Sources/Extensions/UIButton+Kingfisher.swift b/Pods/Kingfisher/Sources/Extensions/UIButton+Kingfisher.swift index b2feb70..2894990 100644 --- a/Pods/Kingfisher/Sources/Extensions/UIButton+Kingfisher.swift +++ b/Pods/Kingfisher/Sources/Extensions/UIButton+Kingfisher.swift @@ -53,20 +53,19 @@ extension KingfisherWrapper where Base: UIButton { placeholder: UIImage? = nil, options: KingfisherOptionsInfo? = nil, progressBlock: DownloadProgressBlock? = nil, - completionHandler: ((Result) -> Void)? = nil) -> DownloadTask? - { + completionHandler: ((Result) -> Void)? = nil) -> DownloadTask? { guard let source = source else { base.setImage(placeholder, for: state) setTaskIdentifier(nil, for: state) completionHandler?(.failure(KingfisherError.imageSettingError(reason: .emptySource))) return nil } - + let options = KingfisherParsedOptionsInfo(KingfisherManager.shared.defaultOptions + (options ?? .empty)) if !options.keepCurrentImageWhileLoading { base.setImage(placeholder, for: state) } - + var mutatingSelf = self let issuedTaskIdentifier = Source.Identifier.next() setTaskIdentifier(issuedTaskIdentifier, for: state) @@ -91,9 +90,9 @@ extension KingfisherWrapper where Base: UIButton { completionHandler?(.failure(error)) return } - + mutatingSelf.imageTask = nil - + switch result { case .success(let value): self.base.setImage(value.image, for: state) @@ -106,11 +105,11 @@ extension KingfisherWrapper where Base: UIButton { } } }) - + mutatingSelf.imageTask = task return task } - + /// Sets an image to the button for a specified state with a requested resource. /// /// - Parameters: @@ -135,8 +134,7 @@ extension KingfisherWrapper where Base: UIButton { placeholder: UIImage? = nil, options: KingfisherOptionsInfo? = nil, progressBlock: DownloadProgressBlock? = nil, - completionHandler: ((Result) -> Void)? = nil) -> DownloadTask? - { + completionHandler: ((Result) -> Void)? = nil) -> DownloadTask? { return setImage( with: resource.map { Source.network($0) }, for: state, @@ -147,7 +145,7 @@ extension KingfisherWrapper where Base: UIButton { } // MARK: Cancelling Downloading Task - + /// Cancels the image download task of the button if it is running. /// Nothing will happen if the downloading has already finished. public func cancelImageDownloadTask() { @@ -180,8 +178,7 @@ extension KingfisherWrapper where Base: UIButton { placeholder: UIImage? = nil, options: KingfisherOptionsInfo? = nil, progressBlock: DownloadProgressBlock? = nil, - completionHandler: ((Result) -> Void)? = nil) -> DownloadTask? - { + completionHandler: ((Result) -> Void)? = nil) -> DownloadTask? { guard let source = source else { base.setBackgroundImage(placeholder, for: state) setBackgroundTaskIdentifier(nil, for: state) @@ -193,7 +190,7 @@ extension KingfisherWrapper where Base: UIButton { if !options.keepCurrentImageWhileLoading { base.setBackgroundImage(placeholder, for: state) } - + var mutatingSelf = self let issuedTaskIdentifier = Source.Identifier.next() setBackgroundTaskIdentifier(issuedTaskIdentifier, for: state) @@ -265,8 +262,7 @@ extension KingfisherWrapper where Base: UIButton { placeholder: UIImage? = nil, options: KingfisherOptionsInfo? = nil, progressBlock: DownloadProgressBlock? = nil, - completionHandler: ((Result) -> Void)? = nil) -> DownloadTask? - { + completionHandler: ((Result) -> Void)? = nil) -> DownloadTask? { return setBackgroundImage( with: resource.map { .network($0) }, for: state, @@ -277,7 +273,7 @@ extension KingfisherWrapper where Base: UIButton { } // MARK: Cancelling Background Downloading Task - + /// Cancels the background image download task of the button if it is running. /// Nothing will happen if the downloading has already finished. public func cancelBackgroundImageDownloadTask() { @@ -293,13 +289,13 @@ private var imageTaskKey: Void? extension KingfisherWrapper where Base: UIButton { public func taskIdentifier(for state: UIControl.State) -> Source.Identifier.Value? { - return (taskIdentifierInfo[NSNumber(value:state.rawValue)] as? Box)?.value + return (taskIdentifierInfo[NSNumber(value: state.rawValue)] as? Box)?.value } private func setTaskIdentifier(_ identifier: Source.Identifier.Value?, for state: UIControl.State) { - taskIdentifierInfo[NSNumber(value:state.rawValue)] = identifier.map { Box($0) } + taskIdentifierInfo[NSNumber(value: state.rawValue)] = identifier.map { Box($0) } } - + private var taskIdentifierInfo: NSMutableDictionary { get { guard let dictionary: NSMutableDictionary = getAssociatedObject(base, &taskIdentifierKey) else { @@ -314,14 +310,13 @@ extension KingfisherWrapper where Base: UIButton { setRetainedAssociatedObject(base, &taskIdentifierKey, newValue) } } - + private var imageTask: DownloadTask? { get { return getAssociatedObject(base, &imageTaskKey) } set { setRetainedAssociatedObject(base, &imageTaskKey, newValue)} } } - private var backgroundTaskIdentifierKey: Void? private var backgroundImageTaskKey: Void? @@ -329,13 +324,13 @@ private var backgroundImageTaskKey: Void? extension KingfisherWrapper where Base: UIButton { public func backgroundTaskIdentifier(for state: UIControl.State) -> Source.Identifier.Value? { - return (backgroundTaskIdentifierInfo[NSNumber(value:state.rawValue)] as? Box)?.value + return (backgroundTaskIdentifierInfo[NSNumber(value: state.rawValue)] as? Box)?.value } - + private func setBackgroundTaskIdentifier(_ identifier: Source.Identifier.Value?, for state: UIControl.State) { - backgroundTaskIdentifierInfo[NSNumber(value:state.rawValue)] = identifier.map { Box($0) } + backgroundTaskIdentifierInfo[NSNumber(value: state.rawValue)] = identifier.map { Box($0) } } - + private var backgroundTaskIdentifierInfo: NSMutableDictionary { get { guard let dictionary: NSMutableDictionary = getAssociatedObject(base, &backgroundTaskIdentifierKey) else { @@ -350,7 +345,7 @@ extension KingfisherWrapper where Base: UIButton { setRetainedAssociatedObject(base, &backgroundTaskIdentifierKey, newValue) } } - + private var backgroundImageTask: DownloadTask? { get { return getAssociatedObject(base, &backgroundImageTaskKey) } mutating set { setRetainedAssociatedObject(base, &backgroundImageTaskKey, newValue) } diff --git a/Pods/Kingfisher/Sources/General/Deprecated.swift b/Pods/Kingfisher/Sources/General/Deprecated.swift index fa47a33..0fe3f90 100644 --- a/Pods/Kingfisher/Sources/General/Deprecated.swift +++ b/Pods/Kingfisher/Sources/General/Deprecated.swift @@ -38,8 +38,7 @@ extension KingfisherWrapper where Base: Image { data: Data, scale: CGFloat, preloadAllAnimationData: Bool, - onlyFirstFrame: Bool) -> Image? - { + onlyFirstFrame: Bool) -> Image? { let options = ImageCreatingOptions( scale: scale, duration: 0.0, @@ -47,7 +46,7 @@ extension KingfisherWrapper where Base: Image { onlyFirstFrame: onlyFirstFrame) return KingfisherWrapper.image(data: data, options: options) } - + @available(*, deprecated, message: "Will be removed soon. Pass parameters with `ImageCreatingOptions`, use `animatedImage(with:options:)` instead.") public static func animated( @@ -55,8 +54,7 @@ extension KingfisherWrapper where Base: Image { scale: CGFloat = 1.0, duration: TimeInterval = 0.0, preloadAll: Bool, - onlyFirstFrame: Bool = false) -> Image? - { + onlyFirstFrame: Bool = false) -> Image? { let options = ImageCreatingOptions( scale: scale, duration: duration, preloadAll: preloadAll, onlyFirstFrame: onlyFirstFrame) return animatedImage(data: data, options: options) @@ -96,8 +94,7 @@ extension KingfisherManager { public func retrieveImage(with resource: Resource, options: KingfisherOptionsInfo?, progressBlock: DownloadProgressBlock?, - completionHandler: CompletionHandler?) -> DownloadTask? - { + completionHandler: CompletionHandler?) -> DownloadTask? { return retrieveImage(with: resource, options: options, progressBlock: progressBlock) { result in switch result { @@ -116,8 +113,7 @@ extension ImageDownloader { retrieveImageTask: RetrieveImageTask? = nil, options: KingfisherOptionsInfo? = nil, progressBlock: ImageDownloaderProgressBlock? = nil, - completionHandler: ImageDownloaderCompletionHandler?) -> DownloadTask? - { + completionHandler: ImageDownloaderCompletionHandler?) -> DownloadTask? { return downloadImage(with: url, options: options, progressBlock: progressBlock) { result in switch result { @@ -148,8 +144,7 @@ extension KingfisherWrapper where Base: ImageView { placeholder: Placeholder? = nil, options: KingfisherOptionsInfo? = nil, progressBlock: DownloadProgressBlock? = nil, - completionHandler: CompletionHandler?) -> DownloadTask? - { + completionHandler: CompletionHandler?) -> DownloadTask? { return setImage(with: resource, placeholder: placeholder, options: options, progressBlock: progressBlock) { result in switch result { @@ -174,15 +169,13 @@ extension KingfisherWrapper where Base: UIButton { placeholder: UIImage? = nil, options: KingfisherOptionsInfo? = nil, progressBlock: DownloadProgressBlock? = nil, - completionHandler: CompletionHandler?) -> DownloadTask? - { + completionHandler: CompletionHandler?) -> DownloadTask? { return setImage( with: resource, for: state, placeholder: placeholder, options: options, - progressBlock: progressBlock) - { + progressBlock: progressBlock) { result in switch result { case .success(let value): @@ -192,7 +185,7 @@ extension KingfisherWrapper where Base: UIButton { } } } - + @available(*, deprecated, message: "Use `Result` based callback instead.") @discardableResult public func setBackgroundImage( @@ -201,15 +194,13 @@ extension KingfisherWrapper where Base: UIButton { placeholder: UIImage? = nil, options: KingfisherOptionsInfo? = nil, progressBlock: DownloadProgressBlock? = nil, - completionHandler: CompletionHandler?) -> DownloadTask? - { + completionHandler: CompletionHandler?) -> DownloadTask? { return setBackgroundImage( with: resource, for: state, placeholder: placeholder, options: options, - progressBlock: progressBlock) - { + progressBlock: progressBlock) { result in switch result { case .success(let value): @@ -232,14 +223,12 @@ extension KingfisherWrapper where Base: WKInterfaceImage { placeholder: Image? = nil, options: KingfisherOptionsInfo? = nil, progressBlock: DownloadProgressBlock? = nil, - completionHandler: CompletionHandler?) -> DownloadTask? - { + completionHandler: CompletionHandler?) -> DownloadTask? { return setImage( with: resource, placeholder: placeholder, options: options, - progressBlock: progressBlock) - { + progressBlock: progressBlock) { result in switch result { case .success(let value): @@ -261,14 +250,12 @@ extension KingfisherWrapper where Base: NSButton { placeholder: Image? = nil, options: KingfisherOptionsInfo? = nil, progressBlock: DownloadProgressBlock? = nil, - completionHandler: CompletionHandler?) -> DownloadTask? - { + completionHandler: CompletionHandler?) -> DownloadTask? { return setImage( with: resource, placeholder: placeholder, options: options, - progressBlock: progressBlock) - { + progressBlock: progressBlock) { result in switch result { case .success(let value): @@ -278,21 +265,19 @@ extension KingfisherWrapper where Base: NSButton { } } } - + @discardableResult @available(*, deprecated, message: "Use `Result` based callback instead.") public func setAlternateImage(with resource: Resource?, placeholder: Image? = nil, options: KingfisherOptionsInfo? = nil, progressBlock: DownloadProgressBlock? = nil, - completionHandler: CompletionHandler?) -> DownloadTask? - { + completionHandler: CompletionHandler?) -> DownloadTask? { return setAlternateImage( with: resource, placeholder: placeholder, options: options, - progressBlock: progressBlock) - { + progressBlock: progressBlock) { result in switch result { case .success(let value): @@ -332,14 +317,14 @@ extension ImageCache { get { return diskStorage.config.pathExtension } set { diskStorage.config.pathExtension = newValue } } - + ///The disk cache location. @available(*, deprecated, message: "Use `diskStorage.directoryURL.absoluteString` instead.", renamed: "diskStorage.directoryURL.absoluteString") public var diskCachePath: String { return diskStorage.directoryURL.absoluteString } - + /// The largest disk size can be taken for the cache. It is the total /// allocated size of cached files in bytes. /// Default is no limit. @@ -349,13 +334,13 @@ extension ImageCache { get { return UInt(diskStorage.config.sizeLimit) } set { diskStorage.config.sizeLimit = newValue } } - + @available(*, deprecated, message: "Use `diskStorage.cacheFileURL(forKey:).path` instead.", renamed: "diskStorage.cacheFileURL(forKey:)") open func cachePath(forComputedKey key: String) -> String { return diskStorage.cacheFileURL(forKey: key).path } - + /** Get an image for a key from disk. @@ -384,13 +369,11 @@ extension ImageCache { renamed: "retrieveImage(forKey:options:callbackQueue:completionHandler:)") open func retrieveImage(forKey key: String, options: KingfisherOptionsInfo?, - completionHandler: ((Image?, CacheType) -> Void)?) - { + completionHandler: ((Image?, CacheType) -> Void)?) { retrieveImage( forKey: key, options: options, - callbackQueue: .dispatch((options ?? .empty).callbackDispatchQueue)) - { + callbackQueue: .dispatch((options ?? .empty).callbackDispatchQueue)) { result in do { let value = try result.get() @@ -417,16 +400,14 @@ extension ImageCache { processorIdentifier identifier: String = "", cacheSerializer serializer: CacheSerializer = DefaultCacheSerializer.default, toDisk: Bool = true, - completionHandler: (() -> Void)?) - { + completionHandler: (() -> Void)?) { store( image, original: original, forKey: key, processorIdentifier: identifier, cacheSerializer: serializer, - toDisk: toDisk) - { + toDisk: toDisk) { _ in completionHandler?() } diff --git a/Pods/Kingfisher/Sources/General/ImageSource/ImageDataProvider.swift b/Pods/Kingfisher/Sources/General/ImageSource/ImageDataProvider.swift index c387409..3042616 100644 --- a/Pods/Kingfisher/Sources/General/ImageSource/ImageDataProvider.swift +++ b/Pods/Kingfisher/Sources/General/ImageSource/ImageDataProvider.swift @@ -31,10 +31,10 @@ import Foundation /// to load some image data in your own way, as long as you can provide the data /// representation for the image. public protocol ImageDataProvider { - + /// The key used in cache. var cacheKey: String { get } - + /// Provides the data which represents image. Kingfisher uses the data you pass in the /// handler to process images and caches it for later use. /// @@ -135,7 +135,7 @@ public struct RawImageDataProvider: ImageDataProvider { } // MARK: Protocol Conforming - + /// The key used in cache. public var cacheKey: String diff --git a/Pods/Kingfisher/Sources/General/ImageSource/Resource.swift b/Pods/Kingfisher/Sources/General/ImageSource/Resource.swift index f12d8a9..c2dd15d 100644 --- a/Pods/Kingfisher/Sources/General/ImageSource/Resource.swift +++ b/Pods/Kingfisher/Sources/General/ImageSource/Resource.swift @@ -30,10 +30,10 @@ import Foundation /// Kingfisher will use a `Resource` to download a resource from network and cache it with the cache key when /// using `Source.network` as its image setting source. public protocol Resource { - + /// The key used in cache. var cacheKey: String { get } - + /// The target image URL. var downloadURL: URL { get } } @@ -57,7 +57,7 @@ public struct ImageResource: Resource { } // MARK: Protocol Conforming - + /// The key used in cache. public let cacheKey: String diff --git a/Pods/Kingfisher/Sources/General/ImageSource/Source.swift b/Pods/Kingfisher/Sources/General/ImageSource/Source.swift index dd922a2..3cd90fd 100644 --- a/Pods/Kingfisher/Sources/General/ImageSource/Source.swift +++ b/Pods/Kingfisher/Sources/General/ImageSource/Source.swift @@ -53,7 +53,7 @@ public enum Source { /// The target image should be got from network remotely. The associated `Resource` /// value defines detail information like image URL and cache key. case network(Resource) - + /// The target image should be provided in a data format. Normally, it can be an image /// from local storage or in any other encoding format (like Base64). case provider(ImageDataProvider) @@ -76,7 +76,7 @@ public enum Source { switch self { case .network(let resource): return resource.downloadURL // `ImageDataProvider` does not provide a URL. All it cares is how to get the data back. - case .provider(_): return nil + case .provider: return nil } } } diff --git a/Pods/Kingfisher/Sources/General/KingfisherError.swift b/Pods/Kingfisher/Sources/General/KingfisherError.swift index 2add785..3cf5a03 100644 --- a/Pods/Kingfisher/Sources/General/KingfisherError.swift +++ b/Pods/Kingfisher/Sources/General/KingfisherError.swift @@ -42,20 +42,20 @@ public enum KingfisherError: Error { /// - invalidURL: The URL of request is invalid. Code 1002. /// - taskCancelled: The downloading task is cancelled by user. Code 1003. public enum RequestErrorReason { - + /// The request is empty. Code 1001. case emptyRequest - + /// The URL of request is invalid. Code 1002. /// - request: The request is tend to be sent but its URL is invalid. case invalidURL(request: URLRequest) - + /// The downloading task is cancelled by user. Code 1003. /// - task: The session data task which is cancelled. /// - token: The cancel token which is used for cancelling the task. case taskCancelled(task: SessionDataTask, token: SessionDataTask.CancelToken) } - + /// Represents the error reason during networking response phase. /// /// - invalidURLResponse: The response is not a valid URL response. Code 2001. @@ -64,32 +64,32 @@ public enum KingfisherError: Error { /// - dataModifyingFailed: Data modifying fails on returning a valid data. Code 2004. /// - noURLResponse: The task is done but no URL response found. Code 2005. public enum ResponseErrorReason { - + /// The response is not a valid URL response. Code 2001. /// - response: The received invalid URL response. /// The response is expected to be an HTTP response, but it is not. case invalidURLResponse(response: URLResponse) - + /// The response contains an invalid HTTP status code. Code 2002. /// - Note: /// By default, status code 200..<400 is recognized as valid. You can override /// this behavior by conforming to the `ImageDownloaderDelegate`. /// - response: The received response. case invalidHTTPStatusCode(response: HTTPURLResponse) - + /// An error happens in the system URL session. Code 2003. /// - error: The underlying URLSession error object. case URLSessionError(error: Error) - + /// Data modifying fails on returning a valid data. Code 2004. /// - task: The failed task. case dataModifyingFailed(task: SessionDataTask) - + /// The task is done but no URL response found. Code 2005. /// - task: The failed task. case noURLResponse(task: SessionDataTask) } - + /// Represents the error reason during Kingfisher caching system. /// /// - fileEnumeratorCreationFailed: Cannot create a file enumerator for a certain disk URL. Code 3001. @@ -101,47 +101,46 @@ public enum KingfisherError: Error { /// - cannotConvertToData: Cannot convert an object to data for storing. Code 3007. /// - cannotSerializeImage: Cannot serialize an image to data for storing. Code 3008. public enum CacheErrorReason { - + /// Cannot create a file enumerator for a certain disk URL. Code 3001. /// - url: The target disk URL from which the file enumerator should be created. case fileEnumeratorCreationFailed(url: URL) - + /// Cannot get correct file contents from a file enumerator. Code 3002. /// - url: The target disk URL from which the content of a file enumerator should be got. case invalidFileEnumeratorContent(url: URL) - + /// The file at target URL exists, but its URL resource is unavailable. Code 3003. /// - error: The underlying error thrown by file manager. /// - key: The key used to getting the resource from cache. /// - url: The disk URL where the target cached file exists. case invalidURLResource(error: Error, key: String, url: URL) - + /// The file at target URL exists, but the data cannot be loaded from it. Code 3004. /// - url: The disk URL where the target cached file exists. /// - error: The underlying error which describes why this error happens. case cannotLoadDataFromDisk(url: URL, error: Error) - + /// Cannot create a folder at a given path. Code 3005. /// - path: The disk path where the directory creating operation fails. /// - error: The underlying error which describes why this error happens. case cannotCreateDirectory(path: String, error: Error) - + /// The requested image does not exist in cache. Code 3006. /// - key: Key of the requested image in cache. case imageNotExisting(key: String) - + /// Cannot convert an object to data for storing. Code 3007. /// - object: The object which needs be convert to data. case cannotConvertToData(object: Any, error: Error) - + /// Cannot serialize an image to data for storing. Code 3008. /// - image: The input image needs to be serialized to cache. /// - original: The original image data, if exists. /// - serializer: The `CacheSerializer` used for the image serializing. case cannotSerializeImage(image: Image?, original: Data?, serializer: CacheSerializer) } - - + /// Represents the error reason during image processing phase. /// /// - processingFailed: Image processing fails. There is no valid output image from the processor. Code 4001. @@ -158,10 +157,10 @@ public enum KingfisherError: Error { /// - notCurrentSourceTask: The source task is finished, but it is not the one expected now. Code 5002. /// - dataProviderError: An error happens during getting data from an `ImageDataProvider`. Code 5003. public enum ImageSettingErrorReason { - + /// The input resource is empty or `nil`. Code 5001. case emptySource - + /// The resource task is finished, but it is not the one expected now. This usually happens when you set another /// resource on the view without cancelling the current on-going one. The previous setting task will fail with /// this `.notCurrentSourceTask` error when a result got, regardless of it being successful or not for that task. @@ -179,7 +178,7 @@ public enum KingfisherError: Error { } // MARK: Member Cases - + /// Represents the error reason during networking request phase. case requestError(reason: RequestErrorReason) /// Represents the error reason during networking response phase. @@ -235,7 +234,7 @@ public enum KingfisherError: Error { // MARK: - LocalizedError Conforming extension KingfisherError: LocalizedError { - + /// A localized message describing what error occurred. public var errorDescription: String? { switch self { @@ -248,7 +247,6 @@ extension KingfisherError: LocalizedError { } } - // MARK: - CustomNSError Conforming extension KingfisherError: CustomNSError { @@ -278,7 +276,7 @@ extension KingfisherError.RequestErrorReason { return "The session task was cancelled. Task: \(task), cancel token: \(token)." } } - + var errorCode: Int { switch self { case .emptyRequest: return 1001 @@ -303,7 +301,7 @@ extension KingfisherError.ResponseErrorReason { return "No URL response received. Task: \(task)," } } - + var errorCode: Int { switch self { case .invalidURLResponse: return 2001 @@ -337,10 +335,10 @@ extension KingfisherError.CacheErrorReason { "Object: \(object). Underlying error: \(error)" case .cannotSerializeImage(let image, let originalData, let serializer): return "Cannot serialize an image due to the cache serializer returning `nil`. " + - "Image: \(String(describing:image)), original data: \(String(describing: originalData)), serializer: \(serializer)." + "Image: \(String(describing: image)), original data: \(String(describing: originalData)), serializer: \(serializer)." } } - + var errorCode: Int { switch self { case .fileEnumeratorCreationFailed: return 3001 @@ -362,7 +360,7 @@ extension KingfisherError.ProcessorErrorReason { return "Processing image failed. Processor: \(processor). Processing item: \(item)." } } - + var errorCode: Int { switch self { case .processingFailed: return 4001 @@ -389,7 +387,7 @@ extension KingfisherError.ImageSettingErrorReason { return "Image data provider fails to provide data. Provider: \(provider), error: \(error)" } } - + var errorCode: Int { switch self { case .emptySource: return 5001 diff --git a/Pods/Kingfisher/Sources/General/KingfisherManager.swift b/Pods/Kingfisher/Sources/General/KingfisherManager.swift index f6b3798..461d881 100644 --- a/Pods/Kingfisher/Sources/General/KingfisherManager.swift +++ b/Pods/Kingfisher/Sources/General/KingfisherManager.swift @@ -24,7 +24,6 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. - import Foundation /// The downloading progress block type. @@ -56,35 +55,35 @@ public class KingfisherManager { /// Use this instance for getting or storing images with Kingfisher. public static let shared = KingfisherManager() - // Mark: Public Properties + // MARK: Public Properties /// The `ImageCache` used by this manager. It is `ImageCache.default` by default. /// If a cache is specified in `KingfisherManager.defaultOptions`, the value in `defaultOptions` will be /// used instead. public var cache: ImageCache - + /// The `ImageDownloader` used by this manager. It is `ImageDownloader.default` by default. /// If a downloader is specified in `KingfisherManager.defaultOptions`, the value in `defaultOptions` will be /// used instead. public var downloader: ImageDownloader - + /// Default options used by the manager. This option will be used in /// Kingfisher manager related methods, as well as all view extension methods. /// You can also passing other options for each image task by sending an `options` parameter /// to Kingfisher's APIs. The per image options will overwrite the default ones, /// if the option exists in both. public var defaultOptions = KingfisherOptionsInfo.empty - + // Use `defaultOptions` to overwrite the `downloader` and `cache`. private var currentDefaultOptions: KingfisherOptionsInfo { return [.downloader(downloader), .targetCache(cache)] + defaultOptions } private let processingQueue: CallbackQueue - + private convenience init() { self.init(downloader: .default, cache: .default) } - + init(downloader: ImageDownloader, cache: ImageCache) { self.downloader = downloader self.cache = cache @@ -93,7 +92,7 @@ public class KingfisherManager { processingQueue = .dispatch(DispatchQueue(label: processQueueName)) } - // Mark: Getting Images + // MARK: Getting Images /// Gets an image from a given resource. /// @@ -118,8 +117,7 @@ public class KingfisherManager { with resource: Resource, options: KingfisherOptionsInfo? = nil, progressBlock: DownloadProgressBlock? = nil, - completionHandler: ((Result) -> Void)?) -> DownloadTask? - { + completionHandler: ((Result) -> Void)?) -> DownloadTask? { let source = Source.network(resource) return retrieveImage( with: source, options: options, progressBlock: progressBlock, completionHandler: completionHandler @@ -148,8 +146,7 @@ public class KingfisherManager { with source: Source, options: KingfisherOptionsInfo? = nil, progressBlock: DownloadProgressBlock? = nil, - completionHandler: ((Result) -> Void)?) -> DownloadTask? - { + completionHandler: ((Result) -> Void)?) -> DownloadTask? { let options = currentDefaultOptions + (options ?? .empty) return retrieveImage( with: source, @@ -157,13 +154,12 @@ public class KingfisherManager { progressBlock: progressBlock, completionHandler: completionHandler) } - + func retrieveImage( with source: Source, options: KingfisherParsedOptionsInfo, progressBlock: DownloadProgressBlock? = nil, - completionHandler: ((Result) -> Void)?) -> DownloadTask? - { + completionHandler: ((Result) -> Void)?) -> DownloadTask? { if options.forceRefresh { return loadAndCacheImage( source: source, @@ -175,17 +171,17 @@ public class KingfisherManager { source: source, options: options, completionHandler: completionHandler) - + if loadedFromCache { return nil } - + if options.onlyFromCache { let error = KingfisherError.cacheError(reason: .imageNotExisting(key: source.cacheKey)) completionHandler?(.failure(error)) return nil } - + return loadAndCacheImage( source: source, options: options, @@ -197,8 +193,7 @@ public class KingfisherManager { func provideImage( provider: ImageDataProvider, options: KingfisherParsedOptionsInfo, - completionHandler: ((Result) -> Void)?) - { + completionHandler: ((Result) -> Void)?) { guard let completionHandler = completionHandler else { return } provider.data { result in switch result { @@ -236,10 +231,8 @@ public class KingfisherManager { source: Source, options: KingfisherParsedOptionsInfo, progressBlock: DownloadProgressBlock? = nil, - completionHandler: ((Result) -> Void)?) -> DownloadTask.WrappedTask? - { - func cacheImage(_ result: Result) - { + completionHandler: ((Result) -> Void)?) -> DownloadTask.WrappedTask? { + func cacheImage(_ result: Result) { switch result { case .success(let value): // Add image to cache. @@ -249,8 +242,7 @@ public class KingfisherManager { original: value.originalData, forKey: source.cacheKey, options: options, - toDisk: !options.cacheMemoryOnly) - { + toDisk: !options.cacheMemoryOnly) { _ in if options.waitForCache { let result = RetrieveImageResult(image: value.image, cacheType: .none, source: source) @@ -286,8 +278,7 @@ public class KingfisherManager { with: resource.downloadURL, options: options, progressBlock: progressBlock, - completionHandler: cacheImage) else - { + completionHandler: cacheImage) else { return nil } return .download(task) @@ -296,7 +287,7 @@ public class KingfisherManager { return .dataProviding } } - + /// Retrieves image from memory or disk cache. /// /// - Parameters: @@ -319,14 +310,13 @@ public class KingfisherManager { func retrieveImageFromCache( source: Source, options: KingfisherParsedOptionsInfo, - completionHandler: ((Result) -> Void)?) -> Bool - { + completionHandler: ((Result) -> Void)?) -> Bool { // 1. Check whether the image was already in target cache. If so, just get it. let targetCache = options.targetCache ?? cache let key = source.cacheKey let targetImageCached = targetCache.imageCachedType( forKey: key, processorIdentifier: options.processor.identifier) - + let validCache = targetImageCached.cached && (options.fromMemoryCacheOrRefresh == false || targetImageCached == .memory) if validCache { @@ -393,8 +383,7 @@ public class KingfisherManager { processedImage, forKey: key, options: cacheOptions, - toDisk: !options.cacheMemoryOnly) - { + toDisk: !options.cacheMemoryOnly) { _ in if options.waitForCache { let value = RetrieveImageResult(image: processedImage, cacheType: .none, source: source) diff --git a/Pods/Kingfisher/Sources/General/KingfisherOptionsInfo.swift b/Pods/Kingfisher/Sources/General/KingfisherOptionsInfo.swift index df07974..18b55c1 100644 --- a/Pods/Kingfisher/Sources/General/KingfisherOptionsInfo.swift +++ b/Pods/Kingfisher/Sources/General/KingfisherOptionsInfo.swift @@ -29,7 +29,6 @@ import AppKit #else import UIKit #endif - /// KingfisherOptionsInfo is a typealias for [KingfisherOptionsInfoItem]. /// You can use the enum of option item with value to control some behaviors of Kingfisher. @@ -41,11 +40,11 @@ extension Array where Element == KingfisherOptionsInfoItem { /// Represents the available option items could be used in `KingfisherOptionsInfo`. public enum KingfisherOptionsInfoItem { - + /// Kingfisher will use the associated `ImageCache` object when handling related operations, /// including trying to retrieve the cached images and store the downloaded image to it. case targetCache(ImageCache) - + /// The `ImageCache` for storing and retrieving original images. If `originalCache` is /// contained in the options, it will be preferred for storing and retrieving original images. /// If there is no `.originalCache` in the options, `.targetCache` will be used to store original images. @@ -57,7 +56,7 @@ public enum KingfisherOptionsInfoItem { /// it will be used and applied with the given processor. It is an optimization for not downloading /// the same image for multiple times. case originalCache(ImageCache) - + /// Kingfisher will use the associated `ImageDownloader` object to download the requested images. case downloader(ImageDownloader) @@ -66,11 +65,11 @@ public enum KingfisherOptionsInfoItem { /// image is retrieved from either memory or disk cache by default. If you need to do the transition even when /// the image being retrieved from cache, set `.forceRefresh` as well. case transition(ImageTransition) - + /// Associated `Float` value will be set as the priority of image download task. The value for it should be /// between 0.0~1.0. If this option not set, the default value (`URLSessionTask.defaultPriority`) will be used. case downloadPriority(Float) - + /// If set, Kingfisher will ignore the cache and try to fire a download task for the resource. case forceRefresh @@ -79,26 +78,26 @@ public enum KingfisherOptionsInfoItem { /// you want to display a changeable image behind the same url at the same app session, while avoiding download /// it for multiple times. case fromMemoryCacheOrRefresh - + /// If set, setting the image to an image view will happen with transition even when retrieved from cache. /// See `.transition` option for more. case forceTransition - + /// If set, Kingfisher will only cache the value in memory but not in disk. case cacheMemoryOnly - + /// If set, Kingfisher will wait for caching operation to be completed before calling the completion block. case waitForCache - + /// If set, Kingfisher will only try to retrieve the image from cache, but not from network. If the image is /// not in cache, the image retrieving will fail with an error. case onlyFromCache - + /// Decode the image in background thread before using. It will decode the downloaded image data and do a off-screen /// rendering to extract pixel information in background. This can speed up display, but will cost more time to /// prepare the image for using. case backgroundDecode - + /// The associated value of this member will be used as the target queue of dispatch callbacks when /// retrieving images from cache. If not set, Kingfisher will use main queue for callbacks. @available(*, deprecated, message: "Use `.callbackQueue(CallbackQueue)` instead.") @@ -111,7 +110,7 @@ public enum KingfisherOptionsInfoItem { /// This option does not affect the callbacks for UI related extension methods. You will always get the /// callbacks called from main queue. case callbackQueue(CallbackQueue) - + /// The associated value will be used as the scale factor when converting retrieved data to an image. /// Specify the image scale, instead of your screen scale. You may need to set the correct scale when you dealing /// with 2x or 3x retina images. Otherwise, Kingfisher will convert the data to image object at `scale` 1.0. @@ -126,26 +125,26 @@ public enum KingfisherOptionsInfoItem { /// uses more CPU when display. While a normal image view (`UIImageView` or `NSImageView`) loads all data at once, /// which uses more memory but only decode image frames once. case preloadAllAnimationData - + /// The `ImageDownloadRequestModifier` contained will be used to change the request before it being sent. /// This is the last chance you can modify the image download request. You can modify the request for some /// customizing purpose, such as adding auth token to the header, do basic HTTP auth or something like url mapping. /// The original request will be sent without any modification by default. case requestModifier(ImageDownloadRequestModifier) - + /// The `ImageDownloadRedirectHandler` contained will be used to change the request before redirection. /// This is the posibility you can modify the image download request during redirect. You can modify the request for /// some customizing purpose, such as adding auth token to the header, do basic HTTP auth or something like url /// mapping. /// The original redirection request will be sent without any modification by default. case redirectHandler(ImageDownloadRedirectHandler) - + /// Processor for processing when the downloading finishes, a processor will convert the downloaded data to an image /// and/or apply some filter on it. If a cache is connected to the downloader (it happens when you are using /// KingfisherManager or any of the view extension methods), the converted image will also be sent to cache as well. /// If not set, the `DefaultImageProcessor.default` will be used. case processor(ImageProcessor) - + /// Supplies a `CacheSerializer` to convert some data to an image object for /// retrieving from disk cache or vice versa for storing to disk cache. /// If not set, the `DefaultCacheSerializer.default` will be used. @@ -158,19 +157,19 @@ public enum KingfisherOptionsInfoItem { /// Use `ImageModifier` when you need to set properties that do not persist when caching the image on a concrete /// type of `Image`, such as the `renderingMode` or the `alignmentInsets` of `UIImage`. case imageModifier(ImageModifier) - + /// Keep the existing image of image view while setting another image to it. /// By setting this option, the placeholder image parameter of image view extension method /// will be ignored and the current image will be kept while loading or downloading the new image. case keepCurrentImageWhileLoading - + /// If set, Kingfisher will only load the first frame from an animated image file as a single image. /// Loading an animated images may take too much memory. It will be useful when you want to display a /// static preview of the first frame from a animated image. /// /// This option will be ignored if the target image is not animated image data. case onlyLoadFirstFrame - + /// If set and an `ImageProcessor` is used, Kingfisher will try to cache both the final result and original /// image. Kingfisher will have a chance to use the original image when another processor is applied to the same /// resource, instead of downloading it again. You can use `.originalCache` to specify a cache or the original @@ -178,17 +177,17 @@ public enum KingfisherOptionsInfoItem { /// /// The original image will be only cached to disk storage. case cacheOriginalImage - + /// If set and a downloading error occurred Kingfisher will set provided image (or empty) /// in place of requested one. It's useful when you don't want to show placeholder /// during loading time but wants to use some default image when requests will be failed. case onFailureImage(Image?) - + /// If set and used in `ImagePrefetcher`, the prefetching operation will load the images into memory storage /// aggressively. By default this is not contained in the options, that means if the requested image is already /// in disk cache, Kingfisher will not try to load it to memory. case alsoPrefetchToMemory - + /// If set, the disk storage loading will happen in the same calling queue. By default, disk storage file loading /// happens in its own queue with an asynchronous dispatch behavior. Although it provides better non-blocking disk /// loading performance, it also causes a flickering when you reload an image from disk, if the image view already @@ -197,17 +196,17 @@ public enum KingfisherOptionsInfoItem { /// Set this options will stop that flickering by keeping all loading in the same queue (typically the UI queue /// if you are using Kingfisher's extension methods to set an image), with a tradeoff of loading performance. case loadDiskFileSynchronously - + /// The expiration setting for memory cache. By default, the underlying `MemoryStorage.Backend` uses the /// expiration in its config for all items. If set, the `MemoryStorage.Backend` will use this associated /// value to overwrite the config setting for this caching item. case memoryCacheExpiration(StorageExpiration) - + /// The expiration setting for memory cache. By default, the underlying `DiskStorage.Backend` uses the /// expiration in its config for all items. If set, the `DiskStorage.Backend` will use this associated /// value to overwrite the config setting for this caching item. case diskCacheExpiration(StorageExpiration) - + /// Decides on which queue the image processing should happen. By default, Kingfisher uses a pre-defined serial /// queue to process images. Use this option to change this behavior. For example, specify a `.mainCurrentOrAsync` /// to let the image be processed in main queue to prevent a possible flickering (but with a possibility of @@ -222,9 +221,9 @@ public enum KingfisherOptionsInfoItem { /// parsed and converted to a `KingfisherParsedOptionsInfo` first, and pass through the internal methods. public struct KingfisherParsedOptionsInfo { - public var targetCache: ImageCache? = nil - public var originalCache: ImageCache? = nil - public var downloader: ImageDownloader? = nil + public var targetCache: ImageCache? + public var originalCache: ImageCache? + public var downloader: ImageDownloader? public var transition: ImageTransition = .none public var downloadPriority: Float = URLSessionTask.defaultPriority public var forceRefresh = false @@ -237,10 +236,10 @@ public struct KingfisherParsedOptionsInfo { public var preloadAllAnimationData = false public var callbackQueue: CallbackQueue = .mainCurrentOrAsync public var scaleFactor: CGFloat = 1.0 - public var requestModifier: ImageDownloadRequestModifier? = nil - public var redirectHandler: ImageDownloadRedirectHandler? = nil + public var requestModifier: ImageDownloadRequestModifier? + public var redirectHandler: ImageDownloadRedirectHandler? public var processor: ImageProcessor = DefaultImageProcessor.default - public var imageModifier: ImageModifier? = nil + public var imageModifier: ImageModifier? public var cacheSerializer: CacheSerializer = DefaultCacheSerializer.default public var keepCurrentImageWhileLoading = false public var onlyLoadFirstFrame = false @@ -248,9 +247,9 @@ public struct KingfisherParsedOptionsInfo { public var onFailureImage: Optional = .none public var alsoPrefetchToMemory = false public var loadDiskFileSynchronously = false - public var memoryCacheExpiration: StorageExpiration? = nil - public var diskCacheExpiration: StorageExpiration? = nil - public var processingQueue: CallbackQueue? = nil + public var memoryCacheExpiration: StorageExpiration? + public var diskCacheExpiration: StorageExpiration? + public var processingQueue: CallbackQueue? public init(_ info: KingfisherOptionsInfo?) { guard let info = info else { return } diff --git a/Pods/Kingfisher/Sources/Image/Filter.swift b/Pods/Kingfisher/Sources/Image/Filter.swift index e93bc8b..2505e8e 100644 --- a/Pods/Kingfisher/Sources/Image/Filter.swift +++ b/Pods/Kingfisher/Sources/Image/Filter.swift @@ -39,7 +39,7 @@ public protocol CIImageProcessor: ImageProcessor { } extension CIImageProcessor { - + /// Processes the input `ImageProcessItem` with this processor. /// /// - Parameters: @@ -61,36 +61,36 @@ extension CIImageProcessor { /// A wrapper struct for a `Transformer` of CIImage filters. A `Filter` /// value could be used to create a `CIImage` processor. public struct Filter { - + let transform: Transformer public init(transform: @escaping Transformer) { self.transform = transform } - + /// Tint filter which will apply a tint color to images. public static var tint: (Color) -> Filter = { color in Filter { input in - + let colorFilter = CIFilter(name: "CIConstantColorGenerator")! colorFilter.setValue(CIColor(color: color), forKey: kCIInputColorKey) - + let filter = CIFilter(name: "CISourceOverCompositing")! - + let colorImage = colorFilter.outputImage filter.setValue(colorImage, forKey: kCIInputImageKey) filter.setValue(input, forKey: kCIInputBackgroundImageKey) - + return filter.outputImage?.cropped(to: input.extent) } } - + /// Represents color control elements. It is a tuple of /// `(brightness, contrast, saturation, inputEV)` public typealias ColorElement = (CGFloat, CGFloat, CGFloat, CGFloat) - + /// Color control filter which will apply color control change to images. public static var colorControl: (ColorElement) -> Filter = { arg -> Filter in let (brightness, contrast, saturation, inputEV) = arg @@ -116,12 +116,12 @@ extension KingfisherWrapper where Base: Image { /// Only CG-based images are supported. If any error happens /// during transforming, `self` will be returned. public func apply(_ filter: Filter) -> Image { - + guard let cgImage = cgImage else { assertionFailure("[Kingfisher] Tint image only works for CG-based image.") return base } - + let inputImage = CIImage(cgImage: cgImage) guard let outputImage = filter.transform(inputImage) else { return base @@ -131,7 +131,7 @@ extension KingfisherWrapper where Base: Image { assertionFailure("[Kingfisher] Can not make an tint image within context.") return base } - + #if os(macOS) return fixedForRetinaPixel(cgImage: result, to: size) #else diff --git a/Pods/Kingfisher/Sources/Image/GIFAnimatedImage.swift b/Pods/Kingfisher/Sources/Image/GIFAnimatedImage.swift index fd2f443..302fb03 100644 --- a/Pods/Kingfisher/Sources/Image/GIFAnimatedImage.swift +++ b/Pods/Kingfisher/Sources/Image/GIFAnimatedImage.swift @@ -42,7 +42,7 @@ public struct ImageCreatingOptions { /// For an animated image, whether or not only the first image should be /// loaded as a static image. It is useful for preview purpose of an animated image. public let onlyFirstFrame: Bool - + /// Creates an `ImageCreatingOptions` object. /// /// - Parameters: @@ -59,8 +59,7 @@ public struct ImageCreatingOptions { scale: CGFloat = 1.0, duration: TimeInterval = 0.0, preloadAll: Bool = false, - onlyFirstFrame: Bool = false) - { + onlyFirstFrame: Bool = false) { self.scale = scale self.duration = duration self.preloadAll = preloadAll @@ -73,17 +72,17 @@ public struct ImageCreatingOptions { class GIFAnimatedImage { let images: [Image] let duration: TimeInterval - + init?(from imageSource: CGImageSource, for info: [String: Any], options: ImageCreatingOptions) { let frameCount = CGImageSourceGetCount(imageSource) var images = [Image]() var gifDuration = 0.0 - + for i in 0 ..< frameCount { guard let imageRef = CGImageSourceCreateImageAtIndex(imageSource, i, info as CFDictionary) else { return nil } - + if frameCount == 1 { gifDuration = .infinity } else { @@ -96,16 +95,16 @@ class GIFAnimatedImage { self.images = images self.duration = gifDuration } - + // Calculates frame duration for a gif frame out of the kCGImagePropertyGIFDictionary dictionary. static func getFrameDuration(from gifInfo: [String: Any]?) -> TimeInterval { let defaultFrameDuration = 0.1 guard let gifInfo = gifInfo else { return defaultFrameDuration } - + let unclampedDelayTime = gifInfo[kCGImagePropertyGIFUnclampedDelayTime as String] as? NSNumber let delayTime = gifInfo[kCGImagePropertyGIFDelayTime as String] as? NSNumber let duration = unclampedDelayTime ?? delayTime - + guard let frameDuration = duration else { return defaultFrameDuration } return frameDuration.doubleValue > 0.011 ? frameDuration.doubleValue : defaultFrameDuration } diff --git a/Pods/Kingfisher/Sources/Image/Image.swift b/Pods/Kingfisher/Sources/Image/Image.swift index d1ae4f7..19e5028 100644 --- a/Pods/Kingfisher/Sources/Image/Image.swift +++ b/Pods/Kingfisher/Sources/Image/Image.swift @@ -24,7 +24,6 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. - #if os(macOS) import AppKit private var imagesKey: Void? @@ -50,26 +49,26 @@ extension KingfisherWrapper where Base: Image { get { return getAssociatedObject(base, &animatedImageDataKey) } set { setRetainedAssociatedObject(base, &animatedImageDataKey, newValue) } } - + #if os(macOS) var cgImage: CGImage? { return base.cgImage(forProposedRect: nil, context: nil, hints: nil) } - + var scale: CGFloat { return 1.0 } - + private(set) var images: [Image]? { get { return getAssociatedObject(base, &imagesKey) } set { setRetainedAssociatedObject(base, &imagesKey, newValue) } } - + private(set) var duration: TimeInterval { get { return getAssociatedObject(base, &durationKey) ?? 0.0 } set { setRetainedAssociatedObject(base, &durationKey, newValue) } } - + var size: CGSize { return base.representations.reduce(.zero) { size, rep in let width = max(size.width, CGFloat(rep.pixelsWide)) @@ -83,7 +82,7 @@ extension KingfisherWrapper where Base: Image { var images: [Image]? { return base.images } var duration: TimeInterval { return base.duration } var size: CGSize { return base.size } - + private(set) var imageSource: CGImageSource? { get { return getAssociatedObject(base, &imageSourceKey) } set { setRetainedAssociatedObject(base, &imageSourceKey, newValue) } @@ -106,7 +105,7 @@ extension KingfisherWrapper where Base: Image { static func image(cgImage: CGImage, scale: CGFloat, refImage: Image?) -> Image { return Image(cgImage: cgImage, size: .zero) } - + /// Normalize the image. This getter does nothing on macOS but return the image itself. public var normalized: Image { return base } @@ -116,7 +115,7 @@ extension KingfisherWrapper where Base: Image { static func image(cgImage: CGImage, scale: CGFloat, refImage: Image?) -> Image { return Image(cgImage: cgImage, scale: scale, orientation: refImage?.imageOrientation ?? .up) } - + /// Returns normalized image for current `base` image. /// This method will try to redraw an image with orientation and scale considered. public var normalized: Image { @@ -212,7 +211,7 @@ extension KingfisherWrapper where Base: Image { return nil } let rep = NSBitmapImageRep(cgImage: cgImage) - return rep.representation(using:.jpeg, properties: [.compressionFactor: compressionQuality]) + return rep.representation(using: .jpeg, properties: [.compressionFactor: compressionQuality]) #else #if swift(>=4.2) return base.jpegData(compressionQuality: compressionQuality) @@ -262,11 +261,11 @@ extension KingfisherWrapper where Base: Image { kCGImageSourceShouldCache as String: true, kCGImageSourceTypeIdentifierHint as String: kUTTypeGIF ] - + guard let imageSource = CGImageSourceCreateWithData(data as CFData, info as CFDictionary) else { return nil } - + #if os(macOS) guard let animatedImage = GIFAnimatedImage(from: imageSource, for: info, options: options) else { return nil @@ -283,7 +282,7 @@ extension KingfisherWrapper where Base: Image { image?.kf.animatedImageData = data return image #else - + var image: Image? if options.preloadAll || options.onlyFirstFrame { // Use `images` image if you want to preload all animated data @@ -303,7 +302,7 @@ extension KingfisherWrapper where Base: Image { kf?.imageSource = imageSource kf?.animatedImageData = data } - + return image #endif } @@ -331,7 +330,7 @@ extension KingfisherWrapper where Base: Image { } return image } - + /// Creates a downsampled image from given data to a certain size and scale. /// /// - Parameters: @@ -352,7 +351,7 @@ extension KingfisherWrapper where Base: Image { guard let imageSource = CGImageSourceCreateWithData(data as CFData, imageSourceOptions) else { return nil } - + let maxDimensionInPixels = max(pointSize.width, pointSize.height) * scale let downsampleOptions = [ kCGImageSourceCreateThumbnailFromImageAlways: true, diff --git a/Pods/Kingfisher/Sources/Image/ImageDrawing.swift b/Pods/Kingfisher/Sources/Image/ImageDrawing.swift index 7c42632..ab9246c 100644 --- a/Pods/Kingfisher/Sources/Image/ImageDrawing.swift +++ b/Pods/Kingfisher/Sources/Image/ImageDrawing.swift @@ -48,25 +48,24 @@ extension KingfisherWrapper where Base: Image { #if !os(macOS) public func image(withBlendMode blendMode: CGBlendMode, alpha: CGFloat = 1.0, - backgroundColor: Color? = nil) -> Image - { + backgroundColor: Color? = nil) -> Image { guard let _ = cgImage else { assertionFailure("[Kingfisher] Blend mode image only works for CG-based image.") return base } - + let rect = CGRect(origin: .zero, size: size) return draw(to: rect.size) { _ in if let backgroundColor = backgroundColor { backgroundColor.setFill() UIRectFill(rect) } - + base.draw(in: rect, blendMode: blendMode, alpha: alpha) } } #endif - + #if os(macOS) // MARK: Compositing /// Creates image from `base` image and apply compositing operation. @@ -86,7 +85,7 @@ extension KingfisherWrapper where Base: Image { assertionFailure("[Kingfisher] Compositing Operation image only works for CG-based image.") return base } - + let rect = CGRect(origin: .zero, size: size) return draw(to: rect.size) { _ in if let backgroundColor = backgroundColor { @@ -97,7 +96,7 @@ extension KingfisherWrapper where Base: Image { } } #endif - + // MARK: Round Corner /// Creates a round corner image from on `base` image. /// @@ -119,7 +118,7 @@ extension KingfisherWrapper where Base: Image { assertionFailure("[Kingfisher] Round corner image only works for CG-based image.") return base } - + let rect = CGRect(origin: CGPoint(x: 0, y: 0), size: size) return draw(to: size) { _ in #if os(macOS) @@ -128,7 +127,7 @@ extension KingfisherWrapper where Base: Image { backgroundColor.setFill() rectPath.fill() } - + let path = NSBezierPath(roundedRect: rect, byRoundingCorners: corners, radius: radius) #if swift(>=4.2) path.windingRule = .evenOdd @@ -142,13 +141,13 @@ extension KingfisherWrapper where Base: Image { assertionFailure("[Kingfisher] Failed to create CG context for image.") return } - + if let backgroundColor = backgroundColor { let rectPath = UIBezierPath(rect: rect) backgroundColor.setFill() rectPath.fill() } - + let path = UIBezierPath(roundedRect: rect, byRoundingCorners: corners.uiRectCorner, cornerRadii: CGSize(width: radius, height: radius)).cgPath @@ -158,7 +157,7 @@ extension KingfisherWrapper where Base: Image { #endif } } - + #if os(iOS) || os(tvOS) func resize(to size: CGSize, for contentMode: UIView.ContentMode) -> Image { switch contentMode { @@ -171,7 +170,7 @@ extension KingfisherWrapper where Base: Image { } } #endif - + // MARK: Resizing /// Resizes `base` image to an image with new size. /// @@ -184,7 +183,7 @@ extension KingfisherWrapper where Base: Image { assertionFailure("[Kingfisher] Resize only works for CG-based image.") return base } - + let rect = CGRect(origin: CGPoint(x: 0, y: 0), size: size) return draw(to: size) { _ in #if os(macOS) @@ -194,7 +193,7 @@ extension KingfisherWrapper where Base: Image { #endif } } - + /// Resizes `base` image to an image of new size, respecting the given content mode. /// /// - Parameters: @@ -224,16 +223,16 @@ extension KingfisherWrapper where Base: Image { assertionFailure("[Kingfisher] Crop only works for CG-based image.") return base } - + let rect = self.size.kf.constrainedRect(for: size, anchor: anchor) guard let image = cgImage.cropping(to: rect.scaled(scale)) else { assertionFailure("[Kingfisher] Cropping image failed.") return base } - + return KingfisherWrapper.image(cgImage: image, scale: scale, refImage: base) } - + // MARK: Blur /// Creates an image with blur effect based on `base` image. /// @@ -243,24 +242,24 @@ extension KingfisherWrapper where Base: Image { /// - Note: This method only works for CG-based image. The current image scale is kept. /// For any non-CG-based image, `base` itself is returned. public func blurred(withRadius radius: CGFloat) -> Image { - + guard let cgImage = cgImage else { assertionFailure("[Kingfisher] Blur only works for CG-based image.") return base } - + // http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement // let d = floor(s * 3*sqrt(2*pi)/4 + 0.5) // if d is odd, use three box-blurs of size 'd', centered on the output pixel. let s = Float(max(radius, 2.0)) // We will do blur on a resized image (*0.5), so the blur radius could be half as well. - + // Fix the slow compiling time for Swift 3. // See https://github.com/onevcat/Kingfisher/issues/611 let pi2 = 2 * Float.pi let sqrtPi2 = sqrt(pi2) var targetRadius = floor(s * 3.0 * sqrtPi2 / 4.0 + 0.5) - + if targetRadius.isEven { targetRadius += 1 } // Determine necessary iteration count by blur radius. @@ -272,36 +271,36 @@ extension KingfisherWrapper where Base: Image { } else { iterations = 3 } - + let w = Int(size.width) let h = Int(size.height) let rowBytes = Int(CGFloat(cgImage.bytesPerRow)) - + func createEffectBuffer(_ context: CGContext) -> vImage_Buffer { let data = context.data let width = vImagePixelCount(context.width) let height = vImagePixelCount(context.height) let rowBytes = context.bytesPerRow - + return vImage_Buffer(data: data, height: height, width: width, rowBytes: rowBytes) } - + guard let context = beginContext(size: size, scale: scale, inverting: true) else { assertionFailure("[Kingfisher] Failed to create CG context for blurring image.") return base } context.draw(cgImage, in: CGRect(x: 0, y: 0, width: w, height: h)) endContext() - + var inBuffer = createEffectBuffer(context) - + guard let outContext = beginContext(size: size, scale: scale, inverting: true) else { assertionFailure("[Kingfisher] Failed to create CG context for blurring image.") return base } defer { endContext() } var outBuffer = createEffectBuffer(outContext) - + for _ in 0 ..< iterations { let flag = vImage_Flags(kvImageEdgeExtend) vImageBoxConvolve_ARGB8888( @@ -309,7 +308,7 @@ extension KingfisherWrapper where Base: Image { // Next inBuffer should be the outButter of current iteration (inBuffer, outBuffer) = (outBuffer, inBuffer) } - + #if os(macOS) let result = outContext.makeImage().flatMap { fixedForRetinaPixel(cgImage: $0, to: size) @@ -323,10 +322,10 @@ extension KingfisherWrapper where Base: Image { assertionFailure("[Kingfisher] Can not make an blurred image within this context.") return base } - + return blurredImage } - + // MARK: Overlay /// Creates an image from `base` image with a color overlay layer. /// @@ -339,14 +338,14 @@ extension KingfisherWrapper where Base: Image { /// - Note: This method only works for CG-based image. The current image scale is kept. /// For any non-CG-based image, `base` itself is returned. public func overlaying(with color: Color, fraction: CGFloat) -> Image { - + guard let _ = cgImage else { assertionFailure("[Kingfisher] Overlaying only works for CG-based image.") return base } - + let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height) - return draw(to: rect.size) { context in + return draw(to: rect.size) { _ in #if os(macOS) base.draw(in: rect) if fraction > 0 { @@ -357,14 +356,14 @@ extension KingfisherWrapper where Base: Image { color.set() UIRectFill(rect) base.draw(in: rect, blendMode: .destinationIn, alpha: 1.0) - + if fraction > 0 { base.draw(in: rect, blendMode: .sourceAtop, alpha: fraction) } #endif } } - + // MARK: Tint /// Creates an image from `base` image with a color tint. /// @@ -377,9 +376,9 @@ extension KingfisherWrapper where Base: Image { return apply(.tint(color)) #endif } - + // MARK: Color Control - + /// Create an image from `self` with color control. /// /// - Parameters: @@ -395,7 +394,7 @@ extension KingfisherWrapper where Base: Image { return apply(.colorControl((brightness, contrast, saturation, inputEV))) #endif } - + /// Return an image with given scale. /// /// - Parameter scale: Target scale factor the new image should have. @@ -414,7 +413,7 @@ extension KingfisherWrapper where Base: Image { // MARK: - Decoding Image extension KingfisherWrapper where Base: Image { - + /// Returns the decoded image of the `base` image. It will draw the image in a plain context and return the data /// from it. This could improve the drawing performance when an image is just created from data but not yet /// displayed for the first time. @@ -422,7 +421,7 @@ extension KingfisherWrapper where Base: Image { /// - Note: This method only works for CG-based image. The current image scale is kept. /// For any non-CG-based image or animated image, `base` itself is returned. public var decoded: Image { return decoded(scale: scale) } - + /// Returns decoded image of the `base` image at a given scale. It will draw the image in a plain context and /// return the data from it. This could improve the drawing performance when an image is just created from /// data but not yet displayed for the first time. @@ -453,7 +452,7 @@ extension KingfisherWrapper where Base: Image { } extension KingfisherWrapper where Base: Image { - + func beginContext(size: CGSize, scale: CGFloat, inverting: Bool = false) -> CGContext? { #if os(macOS) guard let rep = NSBitmapImageRep( @@ -466,8 +465,7 @@ extension KingfisherWrapper where Base: Image { isPlanar: false, colorSpaceName: .calibratedRGB, bytesPerRow: 0, - bitsPerPixel: 0) else - { + bitsPerPixel: 0) else { assertionFailure("[Kingfisher] Image representation cannot be created.") return nil } @@ -477,7 +475,7 @@ extension KingfisherWrapper where Base: Image { assertionFailure("[Kingfisher] Image context cannot be created.") return nil } - + NSGraphicsContext.current = context return context.cgContext #else @@ -490,7 +488,7 @@ extension KingfisherWrapper where Base: Image { return context #endif } - + func endContext() { #if os(macOS) NSGraphicsContext.restoreGraphicsState() @@ -498,7 +496,7 @@ extension KingfisherWrapper where Base: Image { UIGraphicsEndImageContext() #endif } - + func draw(to size: CGSize, inverting: Bool = false, scale: CGFloat? = nil, refImage: Image? = nil, draw: (CGContext) -> Void) -> Image { let targetScale = scale ?? self.scale guard let context = beginContext(size: size, scale: targetScale, inverting: inverting) else { @@ -512,14 +510,14 @@ extension KingfisherWrapper where Base: Image { } return KingfisherWrapper.image(cgImage: cgImage, scale: targetScale, refImage: refImage ?? base) } - + #if os(macOS) func fixedForRetinaPixel(cgImage: CGImage, to size: CGSize) -> Image { - + let image = Image(cgImage: cgImage, size: base.size) let rect = CGRect(origin: CGPoint(x: 0, y: 0), size: size) - - return draw(to: self.size) { context in + + return draw(to: self.size) { _ in image.draw(in: rect, from: .zero, operation: .copy, fraction: 1.0) } } @@ -577,8 +575,7 @@ extension KingfisherWrapper where Base: CGImage { bitsPerComponent: base.bitsPerComponent, bytesPerRow: base.bytesPerRow, space: base.colorSpace ?? CGColorSpaceCreateDeviceRGB(), - bitmapInfo: bitmapInfo) else - { + bitmapInfo: bitmapInfo) else { return base } diff --git a/Pods/Kingfisher/Sources/Image/ImageFormat.swift b/Pods/Kingfisher/Sources/Image/ImageFormat.swift index dcd1f7f..b0c684e 100644 --- a/Pods/Kingfisher/Sources/Image/ImageFormat.swift +++ b/Pods/Kingfisher/Sources/Image/ImageFormat.swift @@ -41,7 +41,7 @@ public enum ImageFormat { case JPEG /// GIF image format. case GIF - + struct HeaderData { static var PNG: [UInt8] = [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A] static var JPEG_SOI: [UInt8] = [0xFF, 0xD8] @@ -50,7 +50,6 @@ public enum ImageFormat { } } - extension Data: KingfisherCompatibleValue {} // MARK: - Misc Helpers @@ -63,16 +62,14 @@ extension KingfisherWrapper where Base == Data { return .PNG } else if buffer[0] == ImageFormat.HeaderData.JPEG_SOI[0] && buffer[1] == ImageFormat.HeaderData.JPEG_SOI[1] && - buffer[2] == ImageFormat.HeaderData.JPEG_IF[0] - { + buffer[2] == ImageFormat.HeaderData.JPEG_IF[0] { return .JPEG } else if buffer[0] == ImageFormat.HeaderData.GIF[0] && buffer[1] == ImageFormat.HeaderData.GIF[1] && - buffer[2] == ImageFormat.HeaderData.GIF[2] - { + buffer[2] == ImageFormat.HeaderData.GIF[2] { return .GIF } - + return .unknown } } diff --git a/Pods/Kingfisher/Sources/Image/ImageProcessor.swift b/Pods/Kingfisher/Sources/Image/ImageProcessor.swift index d21d137..d1dfd1d 100644 --- a/Pods/Kingfisher/Sources/Image/ImageProcessor.swift +++ b/Pods/Kingfisher/Sources/Image/ImageProcessor.swift @@ -38,11 +38,11 @@ import AppKit /// - data: Input data. The processor should provide a way to apply /// processing on this `image` and return the result image. public enum ImageProcessItem { - + /// Input image. The processor should provide a way to apply /// processing on this `image` and return the result image. case image(Image) - + /// Input data. The processor should provide a way to apply /// processing on this `image` and return the result image. case data(Data) @@ -59,7 +59,7 @@ public protocol ImageProcessor { /// the `DefaultImageProcessor`. It is recommended to use a reverse domain name notation string of /// your own for the identifier. var identifier: String { get } - + /// Processes the input `ImageProcessItem` with this processor. /// /// - Parameters: @@ -105,7 +105,7 @@ extension ImageProcessor { } extension ImageProcessor { - + /// Appends an `ImageProcessor` to another. The identifier of the new `ImageProcessor` /// will be "\(self.identifier)|>\(another.identifier)". /// @@ -147,18 +147,18 @@ struct GeneralProcessor: ImageProcessor { /// If an image item is given as `.image` case, `DefaultImageProcessor` will /// do nothing on it and return the associated image. public struct DefaultImageProcessor: ImageProcessor { - + /// A default `DefaultImageProcessor` could be used across. public static let `default` = DefaultImageProcessor() - + /// Identifier of the processor. /// - Note: See documentation of `ImageProcessor` protocol for more. public let identifier = "" - + /// Creates a `DefaultImageProcessor`. Use `DefaultImageProcessor.default` to get an instance, /// if you do not have a good reason to create your own `DefaultImageProcessor`. public init() {} - + /// Processes the input `ImageProcessItem` with this processor. /// /// - Parameters: @@ -179,32 +179,32 @@ public struct DefaultImageProcessor: ImageProcessor { /// Represents the rect corner setting when processing a round corner image. public struct RectCorner: OptionSet { - + /// Raw value of the rect corner. public let rawValue: Int - + /// Represents the top left corner. public static let topLeft = RectCorner(rawValue: 1 << 0) - + /// Represents the top right corner. public static let topRight = RectCorner(rawValue: 1 << 1) - + /// Represents the bottom left corner. public static let bottomLeft = RectCorner(rawValue: 1 << 2) - + /// Represents the bottom right corner. public static let bottomRight = RectCorner(rawValue: 1 << 3) - + /// Represents all corners. public static let all: RectCorner = [.topLeft, .topRight, .bottomLeft, .bottomRight] - + /// Creates a `RectCorner` option set with a given value. /// /// - Parameter rawValue: The value represents a certain corner option. public init(rawValue: Int) { self.rawValue = rawValue } - + var cornerIdentifier: String { if self == .all { return "" @@ -295,8 +295,7 @@ public struct CompositingImageProcessor: ImageProcessor { /// - backgroundColor: Background color to apply for the output image. Default is `nil`. public init(compositingOperation: NSCompositingOperation, alpha: CGFloat = 1.0, - backgroundColor: Color? = nil) - { + backgroundColor: Color? = nil) { self.compositingOperation = compositingOperation self.alpha = alpha self.backgroundColor = backgroundColor @@ -340,17 +339,17 @@ public struct CompositingImageProcessor: ImageProcessor { /// You could use `FormatIndicatedCacheSerializer.png` to force Kingfisher to serialize the image to PNG format in this /// case. public struct RoundCornerImageProcessor: ImageProcessor { - + /// Identifier of the processor. /// - Note: See documentation of `ImageProcessor` protocol for more. public let identifier: String /// Corner radius will be applied in processing. public let cornerRadius: CGFloat - + /// The target corners which will be applied rounding. public let roundingCorners: RectCorner - + /// Target size of output image should be. If `nil`, the image will keep its original size after processing. public let targetSize: CGSize? @@ -370,8 +369,7 @@ public struct RoundCornerImageProcessor: ImageProcessor { cornerRadius: CGFloat, targetSize: CGSize? = nil, roundingCorners corners: RectCorner = .all, - backgroundColor: Color? = nil) - { + backgroundColor: Color? = nil) { self.cornerRadius = cornerRadius self.targetSize = targetSize self.roundingCorners = corners @@ -394,7 +392,7 @@ public struct RoundCornerImageProcessor: ImageProcessor { return identifier }() } - + /// Processes the input `ImageProcessItem` with this processor. /// /// - Parameters: @@ -419,7 +417,6 @@ public struct RoundCornerImageProcessor: ImageProcessor { } } - /// Represents how a size adjusts itself to fit a target size. /// /// - none: Not scale the content. @@ -438,18 +435,18 @@ public enum ContentMode { /// If you need to resize a data represented image to a smaller size, use `DownsamplingImageProcessor` /// instead, which is more efficient and takes less memory. public struct ResizingImageProcessor: ImageProcessor { - + /// Identifier of the processor. /// - Note: See documentation of `ImageProcessor` protocol for more. public let identifier: String - + /// The reference size for resizing operation in point. public let referenceSize: CGSize - + /// Target content mode of output image should be. /// Default is `.none`. public let targetContentMode: ContentMode - + /// Creates a `ResizingImageProcessor`. /// /// - Parameters: @@ -472,14 +469,14 @@ public struct ResizingImageProcessor: ImageProcessor { public init(referenceSize: CGSize, mode: ContentMode = .none) { self.referenceSize = referenceSize self.targetContentMode = mode - + if mode == .none { self.identifier = "com.onevcat.Kingfisher.ResizingImageProcessor(\(referenceSize))" } else { self.identifier = "com.onevcat.Kingfisher.ResizingImageProcessor(\(referenceSize), \(mode))" } } - + /// Processes the input `ImageProcessItem` with this processor. /// /// - Parameters: @@ -502,11 +499,11 @@ public struct ResizingImageProcessor: ImageProcessor { /// Processor for adding blur effect to images. `Accelerate.framework` is used underhood for /// a better performance. A simulated Gaussian blur with specified blur radius will be applied. public struct BlurImageProcessor: ImageProcessor { - + /// Identifier of the processor. /// - Note: See documentation of `ImageProcessor` protocol for more. public let identifier: String - + /// Blur radius for the simulated Gaussian blur. public let blurRadius: CGFloat @@ -517,7 +514,7 @@ public struct BlurImageProcessor: ImageProcessor { self.blurRadius = blurRadius self.identifier = "com.onevcat.Kingfisher.BlurImageProcessor(\(blurRadius))" } - + /// Processes the input `ImageProcessItem` with this processor. /// /// - Parameters: @@ -540,17 +537,17 @@ public struct BlurImageProcessor: ImageProcessor { /// Processor for adding an overlay to images. Only CG-based images are supported in macOS. public struct OverlayImageProcessor: ImageProcessor { - + /// Identifier of the processor. /// - Note: See documentation of `ImageProcessor` protocol for more. public let identifier: String - + /// Overlay color will be used to overlay the input image. public let overlay: Color - + /// Fraction will be used when overlay the color to image. public let fraction: CGFloat - + /// Creates an `OverlayImageProcessor` /// /// - parameter overlay: Overlay color will be used to overlay the input image. @@ -561,7 +558,7 @@ public struct OverlayImageProcessor: ImageProcessor { self.fraction = fraction self.identifier = "com.onevcat.Kingfisher.OverlayImageProcessor(\(overlay.hex)_\(fraction))" } - + /// Processes the input `ImageProcessItem` with this processor. /// /// - Parameters: @@ -583,14 +580,14 @@ public struct OverlayImageProcessor: ImageProcessor { /// Processor for tint images with color. Only CG-based images are supported. public struct TintImageProcessor: ImageProcessor { - + /// Identifier of the processor. /// - Note: See documentation of `ImageProcessor` protocol for more. public let identifier: String - + /// Tint color will be used to tint the input image. public let tint: Color - + /// Creates a `TintImageProcessor` /// /// - parameter tint: Tint color will be used to tint the input image. @@ -598,7 +595,7 @@ public struct TintImageProcessor: ImageProcessor { self.tint = tint self.identifier = "com.onevcat.Kingfisher.TintImageProcessor(\(tint.hex))" } - + /// Processes the input `ImageProcessItem` with this processor. /// /// - Parameters: @@ -621,23 +618,23 @@ public struct TintImageProcessor: ImageProcessor { /// Processor for applying some color control to images. Only CG-based images are supported. /// watchOS is not supported. public struct ColorControlsProcessor: ImageProcessor { - + /// Identifier of the processor. /// - Note: See documentation of `ImageProcessor` protocol for more. public let identifier: String - + /// Brightness changing to image. public let brightness: CGFloat - + /// Contrast changing to image. public let contrast: CGFloat - + /// Saturation changing to image. public let saturation: CGFloat - + /// InputEV changing to image. public let inputEV: CGFloat - + /// Creates a `ColorControlsProcessor` /// /// - Parameters: @@ -652,7 +649,7 @@ public struct ColorControlsProcessor: ImageProcessor { self.inputEV = inputEV self.identifier = "com.onevcat.Kingfisher.ColorControlsProcessor(\(brightness)_\(contrast)_\(saturation)_\(inputEV))" } - + /// Processes the input `ImageProcessItem` with this processor. /// /// - Parameters: @@ -675,14 +672,14 @@ public struct ColorControlsProcessor: ImageProcessor { /// Processor for applying black and white effect to images. Only CG-based images are supported. /// watchOS is not supported. public struct BlackWhiteProcessor: ImageProcessor { - + /// Identifier of the processor. /// - Note: See documentation of `ImageProcessor` protocol for more. public let identifier = "com.onevcat.Kingfisher.BlackWhiteProcessor" - + /// Creates a `BlackWhiteProcessor` public init() {} - + /// Processes the input `ImageProcessItem` with this processor. /// /// - Parameters: @@ -700,20 +697,20 @@ public struct BlackWhiteProcessor: ImageProcessor { /// Processor for cropping an image. Only CG-based images are supported. /// watchOS is not supported. public struct CroppingImageProcessor: ImageProcessor { - + /// Identifier of the processor. /// - Note: See documentation of `ImageProcessor` protocol for more. public let identifier: String - + /// Target size of output image should be. public let size: CGSize - + /// Anchor point from which the output size should be calculate. /// The anchor point is consisted by two values between 0.0 and 1.0. /// It indicates a related point in current image. /// See `CroppingImageProcessor.init(size:anchor:)` for more. public let anchor: CGPoint - + /// Creates a `CroppingImageProcessor`. /// /// - Parameters: @@ -738,7 +735,7 @@ public struct CroppingImageProcessor: ImageProcessor { self.anchor = anchor self.identifier = "com.onevcat.Kingfisher.CroppingImageProcessor(\(size)_\(anchor))" } - + /// Processes the input `ImageProcessItem` with this processor. /// /// - Parameters: @@ -763,16 +760,16 @@ public struct CroppingImageProcessor: ImageProcessor { /// /// Only CG-based images are supported. Animated images (like GIF) is not supported. public struct DownsamplingImageProcessor: ImageProcessor { - + /// Target size of output image should be. It should be smaller than the size of /// input image. If it is larger, the result image will be the same size of input /// data without downsampling. public let size: CGSize - + /// Identifier of the processor. /// - Note: See documentation of `ImageProcessor` protocol for more. public let identifier: String - + /// Creates a `DownsamplingImageProcessor`. /// /// - Parameter size: The target size of the downsample operation. @@ -780,7 +777,7 @@ public struct DownsamplingImageProcessor: ImageProcessor { self.size = size self.identifier = "com.onevcat.Kingfisher.DownsamplingImageProcessor(\(size))" } - + /// Processes the input `ImageProcessItem` with this processor. /// /// - Parameters: @@ -829,9 +826,9 @@ extension Color { let gInt = Int(g * 255) << 16 let bInt = Int(b * 255) << 8 let aInt = Int(a * 255) - + let rgba = rInt | gInt | bInt | aInt - - return String(format:"#%08x", rgba) + + return String(format: "#%08x", rgba) } } diff --git a/Pods/Kingfisher/Sources/Image/ImageTransition.swift b/Pods/Kingfisher/Sources/Image/ImageTransition.swift index c13a9d2..c932262 100644 --- a/Pods/Kingfisher/Sources/Image/ImageTransition.swift +++ b/Pods/Kingfisher/Sources/Image/ImageTransition.swift @@ -64,42 +64,42 @@ public enum ImageTransition { options: UIView.AnimationOptions, animations: ((UIImageView, UIImage) -> Void)?, completion: ((Bool) -> Void)?) - + var duration: TimeInterval { switch self { case .none: return 0 case .fade(let duration): return duration - + case .flipFromLeft(let duration): return duration case .flipFromRight(let duration): return duration case .flipFromTop(let duration): return duration case .flipFromBottom(let duration): return duration - + case .custom(let duration, _, _, _): return duration } } - + var animationOptions: UIView.AnimationOptions { switch self { case .none: return [] case .fade: return .transitionCrossDissolve - + case .flipFromLeft: return .transitionFlipFromLeft case .flipFromRight: return .transitionFlipFromRight case .flipFromTop: return .transitionFlipFromTop case .flipFromBottom: return .transitionFlipFromBottom - + case .custom(_, let options, _, _): return options } } - + var animations: ((UIImageView, UIImage) -> Void)? { switch self { case .custom(_, _, let animations, _): return animations default: return { $0.image = $1 } } } - + var completion: ((Bool) -> Void)? { switch self { case .custom(_, _, _, let completion): return completion diff --git a/Pods/Kingfisher/Sources/Image/Placeholder.swift b/Pods/Kingfisher/Sources/Image/Placeholder.swift index 78b0aef..ac302e2 100644 --- a/Pods/Kingfisher/Sources/Image/Placeholder.swift +++ b/Pods/Kingfisher/Sources/Image/Placeholder.swift @@ -33,10 +33,10 @@ import UIKit /// Represents a placeholder type which could be set while loading as well as /// loading finished without getting an image. public protocol Placeholder { - + /// How the placeholder should be added to a given image view. func add(to imageView: ImageView) - + /// How the placeholder should be removed from a given image view. func remove(from imageView: ImageView) } @@ -57,7 +57,7 @@ extension Image: Placeholder { /// To use your customize View type as placeholder, simply let it conforming to /// `Placeholder` by `extension MyView: Placeholder {}`. extension Placeholder where Self: View { - + /// How the placeholder should be added to a given image view. public func add(to imageView: ImageView) { imageView.addSubview(self) diff --git a/Pods/Kingfisher/Sources/Networking/AuthenticationChallengeResponsable.swift b/Pods/Kingfisher/Sources/Networking/AuthenticationChallengeResponsable.swift index 5f6fc57..c9d4861 100644 --- a/Pods/Kingfisher/Sources/Networking/AuthenticationChallengeResponsable.swift +++ b/Pods/Kingfisher/Sources/Networking/AuthenticationChallengeResponsable.swift @@ -66,8 +66,7 @@ extension AuthenticationChallengeResponsable { public func downloader( _ downloader: ImageDownloader, didReceive challenge: URLAuthenticationChallenge, - completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) - { + completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust { if let trustedHosts = downloader.trustedHosts, trustedHosts.contains(challenge.protectionSpace.host) { let credential = URLCredential(trust: challenge.protectionSpace.serverTrust!) @@ -83,8 +82,7 @@ extension AuthenticationChallengeResponsable { _ downloader: ImageDownloader, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, - completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) - { + completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { completionHandler(.performDefaultHandling, nil) } diff --git a/Pods/Kingfisher/Sources/Networking/ImageDownloader.swift b/Pods/Kingfisher/Sources/Networking/ImageDownloader.swift index 4c77355..fff890a 100644 --- a/Pods/Kingfisher/Sources/Networking/ImageDownloader.swift +++ b/Pods/Kingfisher/Sources/Networking/ImageDownloader.swift @@ -105,7 +105,7 @@ open class ImageDownloader { // MARK: Public Properties /// The duration before the downloading is timeout. Default is 15 seconds. open var downloadTimeout: TimeInterval = 15.0 - + /// A set of trusted hosts when receiving server trust challenges. A challenge with host name contained in this /// set will be ignored. You can use this set to specify the self-signed site. It only will be used if you don't /// specify the `authenticationChallengeResponder`. @@ -113,7 +113,7 @@ open class ImageDownloader { /// If `authenticationChallengeResponder` is set, this property will be ignored and the implementation of /// `authenticationChallengeResponder` will be used instead. open var trustedHosts: Set? - + /// Use this to set supply a configuration for the downloader. By default, /// NSURLSessionConfiguration.ephemeralSessionConfiguration() will be used. /// @@ -125,13 +125,13 @@ open class ImageDownloader { session = URLSession(configuration: sessionConfiguration, delegate: sessionDelegate, delegateQueue: nil) } } - + /// Whether the download requests should use pipeline or not. Default is false. open var requestsUsePipelining = false /// Delegate of this `ImageDownloader` object. See `ImageDownloaderDelegate` protocol for more. open weak var delegate: ImageDownloaderDelegate? - + /// A responder for authentication challenge. /// Downloader will forward the received authentication challenge for the downloading session to this responder. open weak var authenticationChallengeResponder: AuthenticationChallengeResponsable? @@ -198,8 +198,7 @@ open class ImageDownloader { with url: URL, options: KingfisherParsedOptionsInfo, progressBlock: DownloadProgressBlock? = nil, - completionHandler: ((Result) -> Void)? = nil) -> DownloadTask? - { + completionHandler: ((Result) -> Void)? = nil) -> DownloadTask? { // Creates default request. var request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: downloadTimeout) request.httpShouldUsePipelining = requestsUsePipelining @@ -214,7 +213,7 @@ open class ImageDownloader { } request = r } - + // There is a possibility that request modifier changed the url to `nil` or empty. // In this case, throw an error. guard let url = request.url, !url.absoluteString.isEmpty else { @@ -333,8 +332,7 @@ open class ImageDownloader { with url: URL, options: KingfisherOptionsInfo? = nil, progressBlock: DownloadProgressBlock? = nil, - completionHandler: ((Result) -> Void)? = nil) -> DownloadTask? - { + completionHandler: ((Result) -> Void)? = nil) -> DownloadTask? { return downloadImage( with: url, options: KingfisherParsedOptionsInfo(options), diff --git a/Pods/Kingfisher/Sources/Networking/ImagePrefetcher.swift b/Pods/Kingfisher/Sources/Networking/ImagePrefetcher.swift index f83b352..453e341 100644 --- a/Pods/Kingfisher/Sources/Networking/ImagePrefetcher.swift +++ b/Pods/Kingfisher/Sources/Networking/ImagePrefetcher.swift @@ -24,7 +24,6 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. - #if os(macOS) import AppKit #else @@ -74,7 +73,7 @@ public class ImagePrefetcher: CustomStringConvertible { public var description: String { return "\(Unmanaged.passUnretained(self).toOpaque())" } - + /// The maximum concurrent downloads to use when prefetching images. Default is 5. public var maxConcurrentDownloads = 5 @@ -86,16 +85,16 @@ public class ImagePrefetcher: CustomStringConvertible { private var progressSourceBlock: PrefetcherSourceProgressBlock? private var completionSourceHandler: PrefetcherSourceCompletionHandler? - + private var tasks = [String: DownloadTask.WrappedTask]() - + private var pendingSources: ArraySlice private var skippedSources = [Source]() private var completedSources = [Source]() private var failedSources = [Source]() - + private var stopped = false - + // A manager used for prefetching. We will use the helper methods in manager. private let manager: KingfisherManager @@ -128,8 +127,7 @@ public class ImagePrefetcher: CustomStringConvertible { urls: [URL], options: KingfisherOptionsInfo? = nil, progressBlock: PrefetcherProgressBlock? = nil, - completionHandler: PrefetcherCompletionHandler? = nil) - { + completionHandler: PrefetcherCompletionHandler? = nil) { let resources: [Resource] = urls.map { $0 } self.init( resources: resources, @@ -155,8 +153,7 @@ public class ImagePrefetcher: CustomStringConvertible { resources: [Resource], options: KingfisherOptionsInfo? = nil, progressBlock: PrefetcherProgressBlock? = nil, - completionHandler: PrefetcherCompletionHandler? = nil) - { + completionHandler: PrefetcherCompletionHandler? = nil) { self.init(sources: resources.map { .network($0) }, options: options) self.progressBlock = progressBlock self.completionHandler = completionHandler @@ -178,8 +175,7 @@ public class ImagePrefetcher: CustomStringConvertible { public convenience init(sources: [Source], options: KingfisherOptionsInfo? = nil, progressBlock: PrefetcherSourceProgressBlock? = nil, - completionHandler: PrefetcherSourceCompletionHandler? = nil) - { + completionHandler: PrefetcherSourceCompletionHandler? = nil) { self.init(sources: sources, options: options) self.progressSourceBlock = progressBlock self.completionSourceHandler = completionHandler @@ -241,18 +237,18 @@ public class ImagePrefetcher: CustomStringConvertible { self.tasks.values.forEach { $0.cancel() } } } - + private func downloadAndCache(_ source: Source) { let downloadTaskCompletionHandler: ((Result) -> Void) = { result in self.tasks.removeValue(forKey: source.cacheKey) do { - let _ = try result.get() + _ = try result.get() self.completedSources.append(source) } catch { self.failedSources.append(source) } - + self.reportProgress() if self.stopped { if self.tasks.isEmpty { @@ -276,21 +272,20 @@ public class ImagePrefetcher: CustomStringConvertible { tasks[source.cacheKey] = downloadTask } } - + private func append(cached source: Source) { skippedSources.append(source) - + reportProgress() reportCompletionOrStartNext() } - - private func startPrefetching(_ source: Source) - { + + private func startPrefetching(_ source: Source) { if optionsInfo.forceRefresh { downloadAndCache(source) return } - + let cacheType = manager.cache.imageCachedType( forKey: source.cacheKey, processorIdentifier: optionsInfo.processor.identifier) @@ -301,8 +296,7 @@ public class ImagePrefetcher: CustomStringConvertible { if optionsInfo.alsoPrefetchToMemory { _ = manager.retrieveImageFromCache( source: source, - options: optionsInfo) - { + options: optionsInfo) { _ in self.append(cached: source) } @@ -313,7 +307,7 @@ public class ImagePrefetcher: CustomStringConvertible { downloadAndCache(source) } } - + private func reportProgress() { if progressBlock == nil && progressSourceBlock == nil { @@ -332,7 +326,7 @@ public class ImagePrefetcher: CustomStringConvertible { ) } } - + private func reportCompletionOrStartNext() { if let resource = self.pendingSources.popFirst() { // Loose call stack for huge ammount of sources. @@ -346,13 +340,13 @@ public class ImagePrefetcher: CustomStringConvertible { var allFinished: Bool { return skippedSources.count + failedSources.count + completedSources.count == prefetchSources.count } - + private func handleComplete() { if completionHandler == nil && completionSourceHandler == nil { return } - + // The completion handler should be called on the main thread CallbackQueue.mainCurrentOrAsync.execute { self.completionSourceHandler?(self.skippedSources, self.failedSources, self.completedSources) diff --git a/Pods/Kingfisher/Sources/Networking/RedirectHandler.swift b/Pods/Kingfisher/Sources/Networking/RedirectHandler.swift index c5ca276..d4910dd 100644 --- a/Pods/Kingfisher/Sources/Networking/RedirectHandler.swift +++ b/Pods/Kingfisher/Sources/Networking/RedirectHandler.swift @@ -54,18 +54,17 @@ public protocol ImageDownloadRedirectHandler { /// A wrapper for creating an `ImageDownloadRedirectHandler` easier. /// This type conforms to `ImageDownloadRedirectHandler` and wraps an redirect request modify block. public struct AnyRedirectHandler: ImageDownloadRedirectHandler { - + let block: (SessionDataTask, HTTPURLResponse, URLRequest, (URLRequest?) -> Void) -> Void public func handleHTTPRedirection( for task: SessionDataTask, response: HTTPURLResponse, newRequest: URLRequest, - completionHandler: @escaping (URLRequest?) -> Void) - { + completionHandler: @escaping (URLRequest?) -> Void) { block(task, response, newRequest, completionHandler) } - + /// Creates a value of `ImageDownloadRedirectHandler` which runs `modify` block. /// /// - Parameter modify: The request modifying block runs when a request modifying task comes. diff --git a/Pods/Kingfisher/Sources/Networking/RequestModifier.swift b/Pods/Kingfisher/Sources/Networking/RequestModifier.swift index 06b062a..4695e2a 100644 --- a/Pods/Kingfisher/Sources/Networking/RequestModifier.swift +++ b/Pods/Kingfisher/Sources/Networking/RequestModifier.swift @@ -49,14 +49,14 @@ public protocol ImageDownloadRequestModifier { /// A wrapper for creating an `ImageDownloadRequestModifier` easier. /// This type conforms to `ImageDownloadRequestModifier` and wraps an image modify block. public struct AnyModifier: ImageDownloadRequestModifier { - + let block: (URLRequest) -> URLRequest? /// For `ImageDownloadRequestModifier` conformation. public func modified(for request: URLRequest) -> URLRequest? { return block(request) } - + /// Creates a value of `ImageDownloadRequestModifier` which runs `modify` block. /// /// - Parameter modify: The request modifying block runs when a request modifying task comes. diff --git a/Pods/Kingfisher/Sources/Networking/SessionDelegate.swift b/Pods/Kingfisher/Sources/Networking/SessionDelegate.swift index 1c26a51..ee2ed58 100644 --- a/Pods/Kingfisher/Sources/Networking/SessionDelegate.swift +++ b/Pods/Kingfisher/Sources/Networking/SessionDelegate.swift @@ -55,8 +55,7 @@ class SessionDelegate: NSObject { func add( _ dataTask: URLSessionDataTask, url: URL, - callback: SessionDataTask.TaskCallback) -> DownloadTask - { + callback: SessionDataTask.TaskCallback) -> DownloadTask { lock.lock() defer { lock.unlock() } @@ -81,8 +80,7 @@ class SessionDelegate: NSObject { func append( _ task: SessionDataTask, url: URL, - callback: SessionDataTask.TaskCallback) -> DownloadTask - { + callback: SessionDataTask.TaskCallback) -> DownloadTask { let token = task.addCallback(callback) return DownloadTask(sessionTask: task, cancelToken: token) } @@ -142,8 +140,7 @@ extension SessionDelegate: URLSessionDataDelegate { _ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, - completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) - { + completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) { guard let httpResponse = response as? HTTPURLResponse else { let error = KingfisherError.responseError(reason: .invalidURLResponse(response: response)) onCompleted(task: dataTask, result: .failure(error)) @@ -208,8 +205,7 @@ extension SessionDelegate: URLSessionDataDelegate { func urlSession( _ session: URLSession, didReceive challenge: URLAuthenticationChallenge, - completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) - { + completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { onReceiveSessionChallenge.call((session, challenge, completionHandler)) } @@ -217,25 +213,22 @@ extension SessionDelegate: URLSessionDataDelegate { _ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, - completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) - { + completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { onReceiveSessionTaskChallenge.call((session, task, challenge, completionHandler)) } - + func urlSession( _ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest, - completionHandler: @escaping (URLRequest?) -> Void) - { + completionHandler: @escaping (URLRequest?) -> Void) { guard let sessionDataTask = self.task(for: task), - let redirectHandler = Array(sessionDataTask.callbacks).last?.options.redirectHandler else - { + let redirectHandler = Array(sessionDataTask.callbacks).last?.options.redirectHandler else { completionHandler(request) return } - + redirectHandler.handleHTTPRedirection( for: sessionDataTask, response: response, diff --git a/Pods/Kingfisher/Sources/Utility/Box.swift b/Pods/Kingfisher/Sources/Utility/Box.swift index b72e4a2..17e7b9d 100644 --- a/Pods/Kingfisher/Sources/Utility/Box.swift +++ b/Pods/Kingfisher/Sources/Utility/Box.swift @@ -27,7 +27,7 @@ import Foundation class Box { let value: T - + init(_ value: T) { self.value = value } diff --git a/Pods/Kingfisher/Sources/Utility/CallbackQueue.swift b/Pods/Kingfisher/Sources/Utility/CallbackQueue.swift index fa67f14..d0c3b2d 100644 --- a/Pods/Kingfisher/Sources/Utility/CallbackQueue.swift +++ b/Pods/Kingfisher/Sources/Utility/CallbackQueue.swift @@ -43,7 +43,7 @@ public enum CallbackQueue { case untouch /// Dispatches to a specified `DispatchQueue`. case dispatch(DispatchQueue) - + public func execute(_ block: @escaping () -> Void) { switch self { case .mainAsync: @@ -71,7 +71,7 @@ extension DispatchQueue { // This method will dispatch the `block` to self. // If `self` is the main queue, and current thread is main thread, the block // will be invoked immediately instead of being dispatched. - func safeAsync(_ block: @escaping ()->()) { + func safeAsync(_ block: @escaping () -> Void) { if self === DispatchQueue.main && Thread.isMainThread { block() } else { diff --git a/Pods/Kingfisher/Sources/Utility/Delegate.swift b/Pods/Kingfisher/Sources/Utility/Delegate.swift index 15915c9..61fe77f 100644 --- a/Pods/Kingfisher/Sources/Utility/Delegate.swift +++ b/Pods/Kingfisher/Sources/Utility/Delegate.swift @@ -29,9 +29,9 @@ import Foundation /// A delegate helper type to "shadow" weak `self`, to prevent creating an unexpected retain cycle. class Delegate { init() {} - + private var block: ((Input) -> Output?)? - + func delegate(on target: T, block: ((T, Input) -> Output)?) { // The `target` is weak inside block, so you do not need to worry about it in the caller side. self.block = { [weak target] input in @@ -39,7 +39,7 @@ class Delegate { return block?(target, input) } } - + func call(_ input: Input) -> Output? { return block?(input) } diff --git a/Pods/Kingfisher/Sources/Utility/ExtensionHelpers.swift b/Pods/Kingfisher/Sources/Utility/ExtensionHelpers.swift index 147ce01..066e26d 100644 --- a/Pods/Kingfisher/Sources/Utility/ExtensionHelpers.swift +++ b/Pods/Kingfisher/Sources/Utility/ExtensionHelpers.swift @@ -36,25 +36,24 @@ extension Float { import AppKit extension NSBezierPath { convenience init(roundedRect rect: NSRect, topLeftRadius: CGFloat, topRightRadius: CGFloat, - bottomLeftRadius: CGFloat, bottomRightRadius: CGFloat) - { + bottomLeftRadius: CGFloat, bottomRightRadius: CGFloat) { self.init() - + let maxCorner = min(rect.width, rect.height) / 2 - + let radiusTopLeft = min(maxCorner, max(0, topLeftRadius)) let radiusTopRight = min(maxCorner, max(0, topRightRadius)) let radiusBottomLeft = min(maxCorner, max(0, bottomLeftRadius)) let radiusBottomRight = min(maxCorner, max(0, bottomRightRadius)) - + guard !rect.isEmpty else { return } - + let topLeft = NSPoint(x: rect.minX, y: rect.maxY) let topRight = NSPoint(x: rect.maxX, y: rect.maxY) let bottomRight = NSPoint(x: rect.maxX, y: rect.minY) - + move(to: NSPoint(x: rect.midX, y: rect.maxY)) appendArc(from: topLeft, to: rect.origin, radius: radiusTopLeft) appendArc(from: rect.origin, to: bottomRight, radius: radiusBottomLeft) @@ -62,13 +61,13 @@ extension NSBezierPath { appendArc(from: topRight, to: topLeft, radius: radiusTopRight) close() } - + convenience init(roundedRect rect: NSRect, byRoundingCorners corners: RectCorner, radius: CGFloat) { let radiusTopLeft = corners.contains(.topLeft) ? radius : 0 let radiusTopRight = corners.contains(.topRight) ? radius : 0 let radiusBottomLeft = corners.contains(.bottomLeft) ? radius : 0 let radiusBottomRight = corners.contains(.bottomRight) ? radius : 0 - + self.init(roundedRect: rect, topLeftRadius: radiusTopLeft, topRightRadius: radiusTopRight, bottomLeftRadius: radiusBottomLeft, bottomRightRadius: radiusBottomRight) } @@ -86,14 +85,14 @@ extension Image { import UIKit extension RectCorner { var uiRectCorner: UIRectCorner { - + var result: UIRectCorner = [] - + if contains(.topLeft) { result.insert(.topLeft) } if contains(.topRight) { result.insert(.topRight) } if contains(.bottomLeft) { result.insert(.bottomLeft) } if contains(.bottomRight) { result.insert(.bottomRight) } - + return result } } diff --git a/Pods/Kingfisher/Sources/Utility/Result.swift b/Pods/Kingfisher/Sources/Utility/Result.swift index 9b1bc86..0b3e2b6 100644 --- a/Pods/Kingfisher/Sources/Utility/Result.swift +++ b/Pods/Kingfisher/Sources/Utility/Result.swift @@ -169,11 +169,11 @@ extension Result where Failure == Swift.Error { } } -extension Result : Equatable where Success : Equatable, Failure: Equatable { } +extension Result: Equatable where Success: Equatable, Failure: Equatable { } -extension Result : Hashable where Success : Hashable, Failure : Hashable { } +extension Result: Hashable where Success: Hashable, Failure: Hashable { } -extension Result : CustomDebugStringConvertible { +extension Result: CustomDebugStringConvertible { public var debugDescription: String { var output = "Result." switch self { @@ -239,8 +239,7 @@ extension Result where Failure: Error { /// - Returns: A single `Output` value. func match( onSuccess: (Success) -> Output, - onFailure: (Failure) -> Output) -> Output - { + onFailure: (Failure) -> Output) -> Output { switch self { case let .success(value): return onSuccess(value) diff --git a/Pods/Kingfisher/Sources/Utility/SizeExtensions.swift b/Pods/Kingfisher/Sources/Utility/SizeExtensions.swift index 19d05d6..a84bb09 100644 --- a/Pods/Kingfisher/Sources/Utility/SizeExtensions.swift +++ b/Pods/Kingfisher/Sources/Utility/SizeExtensions.swift @@ -28,7 +28,7 @@ import CoreGraphics extension CGSize: KingfisherCompatibleValue {} extension KingfisherWrapper where Base == CGSize { - + /// Returns a size by resizing the `base` size to a target size under a given content mode. /// /// - Parameters: @@ -45,7 +45,7 @@ extension KingfisherWrapper where Base == CGSize { return size } } - + /// Returns a size by resizing the `base` size by making it aspect fitting the given `size`. /// /// - Parameter size: The size in which the `base` should fit in. @@ -53,12 +53,12 @@ extension KingfisherWrapper where Base == CGSize { public func constrained(_ size: CGSize) -> CGSize { let aspectWidth = round(aspectRatio * size.height) let aspectHeight = round(size.width / aspectRatio) - + return aspectWidth > size.width ? CGSize(width: size.width, height: aspectHeight) : CGSize(width: aspectWidth, height: size.height) } - + /// Returns a size by resizing the `base` size by making it aspect filling the given `size`. /// /// - Parameter size: The size in which the `base` should fill. @@ -66,12 +66,12 @@ extension KingfisherWrapper where Base == CGSize { public func filling(_ size: CGSize) -> CGSize { let aspectWidth = round(aspectRatio * size.height) let aspectHeight = round(size.width / aspectRatio) - + return aspectWidth < size.width ? CGSize(width: size.width, height: aspectHeight) : CGSize(width: aspectWidth, height: size.height) } - + /// Returns a `CGRect` for which the `base` size is constrained to an input `size` at a given `anchor` point. /// /// - Parameters: @@ -79,18 +79,18 @@ extension KingfisherWrapper where Base == CGSize { /// - anchor: An anchor point in which the size constraint should happen. /// - Returns: The result `CGRect` for the constraint operation. public func constrainedRect(for size: CGSize, anchor: CGPoint) -> CGRect { - + let unifiedAnchor = CGPoint(x: anchor.x.clamped(to: 0.0...1.0), y: anchor.y.clamped(to: 0.0...1.0)) - + let x = unifiedAnchor.x * base.width - unifiedAnchor.x * size.width let y = unifiedAnchor.y * base.height - unifiedAnchor.y * size.height let r = CGRect(x: x, y: y, width: size.width, height: size.height) - + let ori = CGRect(origin: .zero, size: base) return ori.intersection(r) } - + private var aspectRatio: CGFloat { return base.height == 0.0 ? 1.0 : base.width / base.height } diff --git a/Pods/Kingfisher/Sources/Utility/String+MD5.swift b/Pods/Kingfisher/Sources/Utility/String+MD5.swift index d523cb4..a71b4fe 100644 --- a/Pods/Kingfisher/Sources/Utility/String+MD5.swift +++ b/Pods/Kingfisher/Sources/Utility/String+MD5.swift @@ -43,7 +43,7 @@ extension KingfisherWrapper where Base == String { return CC_MD5(bytes, CC_LONG(data.count), &digest) } #endif - + return digest.map { String(format: "%02x", $0) }.joined() } } diff --git a/Pods/Kingfisher/Sources/Views/AnimatedImageView.swift b/Pods/Kingfisher/Sources/Views/AnimatedImageView.swift index 8db3d49..c0a7168 100644 --- a/Pods/Kingfisher/Sources/Views/AnimatedImageView.swift +++ b/Pods/Kingfisher/Sources/Views/AnimatedImageView.swift @@ -70,15 +70,15 @@ let KFRunLoopModeCommon = RunLoopMode.commonModes /// Kingfisher supports setting GIF animated data to either `UIImageView` and `AnimatedImageView` out of box. So /// it would be fairly easy to switch between them. open class AnimatedImageView: UIImageView { - + /// Proxy object for preventing a reference cycle between the `CADDisplayLink` and `AnimatedImageView`. class TargetProxy { private weak var target: AnimatedImageView? - + init(target: AnimatedImageView) { self.target = target } - + @objc func onScreenUpdate() { target?.updateFrameIfNeeded() } @@ -107,14 +107,14 @@ open class AnimatedImageView: UIImageView { } } } - + // MARK: - Public property /// Whether automatically play the animation when the view become visible. Default is `true`. public var autoPlayAnimatedImage = true - + /// The count of the frames should be preloaded before shown. public var framePreloadCount = 10 - + /// Specifies whether the GIF frames should be pre-scaled to the image view's size or not. /// If the downloaded image is larger than the image view's size, it will help to reduce some memory use. /// Default is `true`. @@ -131,7 +131,7 @@ open class AnimatedImageView: UIImageView { startAnimating() } } - + /// The repeat count. The animated image will keep animate until it the loop count reaches this value. /// Setting this value to another one will reset current animation. /// @@ -148,7 +148,7 @@ open class AnimatedImageView: UIImageView { /// Delegate of this `AnimatedImageView` object. See `AnimatedImageViewDelegate` protocol for more. public weak var delegate: AnimatedImageViewDelegate? - + // MARK: - Private property /// `Animator` instance that holds the frames of a specific image in memory. private var animator: Animator? @@ -157,10 +157,10 @@ open class AnimatedImageView: UIImageView { private lazy var preloadQueue: DispatchQueue = { return DispatchQueue(label: "com.onevcat.Kingfisher.Animator.preloadQueue") }() - + // A flag to avoid invalidating the displayLink on deinit if it was never created, because displayLink is so lazy. private var isDisplayLinkInitialized: Bool = false - + // A display link that keeps calling the `updateFrame` method on every screen refresh. private lazy var displayLink: CADisplayLink = { isDisplayLinkInitialized = true @@ -170,7 +170,7 @@ open class AnimatedImageView: UIImageView { displayLink.isPaused = true return displayLink }() - + // MARK: - Override override open var image: Image? { didSet { @@ -181,13 +181,13 @@ open class AnimatedImageView: UIImageView { layer.setNeedsDisplay() } } - + deinit { if isDisplayLinkInitialized { displayLink.invalidate() } } - + override open var isAnimating: Bool { if isDisplayLinkInitialized { return !displayLink.isPaused @@ -195,7 +195,7 @@ open class AnimatedImageView: UIImageView { return super.isAnimating } } - + /// Starts the animation. override open func startAnimating() { guard !isAnimating else { return } @@ -205,7 +205,7 @@ open class AnimatedImageView: UIImageView { displayLink.isPaused = false } - + /// Stops the animation. override open func stopAnimating() { super.stopAnimating() @@ -213,7 +213,7 @@ open class AnimatedImageView: UIImageView { displayLink.isPaused = true } } - + override open func display(_ layer: CALayer) { if let currentFrame = animator?.currentFrameImage { layer.contents = currentFrame.cgImage @@ -221,12 +221,12 @@ open class AnimatedImageView: UIImageView { layer.contents = image?.cgImage } } - + override open func didMoveToWindow() { super.didMoveToWindow() didMove() } - + override open func didMoveToSuperview() { super.didMoveToSuperview() didMove() @@ -256,7 +256,7 @@ open class AnimatedImageView: UIImageView { } didMove() } - + private func didMove() { if autoPlayAnimatedImage && animator != nil { if let _ = superview, let _ = window { @@ -266,7 +266,7 @@ open class AnimatedImageView: UIImageView { } } } - + /// Update the current frame with the displayLink duration. private func updateFrameIfNeeded() { guard let animator = animator else { @@ -501,7 +501,7 @@ extension AnimatedImageView { return Image(cgImage: scaledImage) } - + private func updatePreloadedFrames() { guard preloadingIsNeeded else { return diff --git a/Pods/Kingfisher/Sources/Views/Indicator.swift b/Pods/Kingfisher/Sources/Views/Indicator.swift index fa72a75..df06b74 100644 --- a/Pods/Kingfisher/Sources/Views/Indicator.swift +++ b/Pods/Kingfisher/Sources/Views/Indicator.swift @@ -52,23 +52,23 @@ public enum IndicatorType { /// An indicator type which can be used to show the download task is in progress. public protocol Indicator { - + /// Called when the indicator should start animating. func startAnimatingView() - + /// Called when the indicator should stop animating. func stopAnimatingView() /// Center offset of the indicator. Kingfisher will use this value to determine the position of /// indicator in the super view. var centerOffset: CGPoint { get } - + /// The indicator view which would be added to the super view. var view: IndicatorView { get } } extension Indicator { - + /// Default implementation of `centerOffset` of `Indicator`. The default value is `.zero`, means that there is /// no offset for the indicator view. public var centerOffset: CGPoint { return .zero } @@ -144,21 +144,20 @@ final class ImageIndicator: Indicator { init?( imageData data: Data, processor: ImageProcessor = DefaultImageProcessor.default, - options: KingfisherParsedOptionsInfo? = nil) - { + options: KingfisherParsedOptionsInfo? = nil) { var options = options ?? KingfisherParsedOptionsInfo(nil) // Use normal image view to show animations, so we need to preload all animation data. if !options.preloadAllAnimationData { options.preloadAllAnimationData = true } - + guard let image = processor.process(item: .data(data), options: options) else { return nil } animatedImageIndicatorView = ImageView() animatedImageIndicatorView.image = image - + #if os(macOS) // Need for gif to animate on macOS animatedImageIndicatorView.imageScaling = .scaleNone diff --git a/Pods/MessageInputBar/Sources/Controls/InputBarButtonItem.swift b/Pods/MessageInputBar/Sources/Controls/InputBarButtonItem.swift index 154e03f..f339b50 100644 --- a/Pods/MessageInputBar/Sources/Controls/InputBarButtonItem.swift +++ b/Pods/MessageInputBar/Sources/Controls/InputBarButtonItem.swift @@ -31,7 +31,7 @@ import UIKit 1. Intended to be used in an `InputStackView` */ open class InputBarButtonItem: UIButton, InputItem { - + /// The spacing properties of the InputBarButtonItem /// /// - fixed: The spacing is fixed @@ -42,14 +42,14 @@ open class InputBarButtonItem: UIButton, InputItem { case flexible case none } - + public typealias InputBarButtonItemAction = ((InputBarButtonItem) -> Void) - + // MARK: - Properties - + /// A weak reference to the MessageInputBar that the InputBarButtonItem used in open weak var messageInputBar: MessageInputBar? - + /// The spacing property of the InputBarButtonItem that determines the contentHuggingPriority and any /// additional space to the intrinsicContentSize open var spacing: Spacing = .none { @@ -64,14 +64,14 @@ open class InputBarButtonItem: UIButton, InputItem { } } } - + /// When not nil this size overrides the intrinsicContentSize private var size: CGSize? = CGSize(width: 20, height: 20) { didSet { invalidateIntrinsicContentSize() } } - + open override var intrinsicContentSize: CGSize { var contentSize = size ?? super.intrinsicContentSize switch spacing { @@ -82,10 +82,10 @@ open class InputBarButtonItem: UIButton, InputItem { } return contentSize } - + /// A reference to the stack view position that the InputBarButtonItem is held in open var parentStackViewPosition: InputStackView.Position? - + /// The title for the UIControlState.normal open var title: String? { get { @@ -95,7 +95,7 @@ open class InputBarButtonItem: UIButton, InputItem { setTitle(newValue, for: .normal) } } - + /// The image for the UIControlState.normal open var image: UIImage? { get { @@ -105,7 +105,7 @@ open class InputBarButtonItem: UIButton, InputItem { setImage(newValue, for: .normal) } } - + /// Calls the onSelectedAction or onDeselectedAction when set open override var isHighlighted: Bool { get { @@ -119,10 +119,10 @@ open class InputBarButtonItem: UIButton, InputItem { } else { onDeselectedAction?(self) } - + } } - + /// Calls the onEnabledAction or onDisabledAction when set open override var isEnabled: Bool { didSet { @@ -133,9 +133,9 @@ open class InputBarButtonItem: UIButton, InputItem { } } } - + // MARK: - Reactive Hooks - + private var onTouchUpInsideAction: InputBarButtonItemAction? private var onKeyboardEditingBeginsAction: InputBarButtonItemAction? private var onKeyboardEditingEndsAction: InputBarButtonItemAction? @@ -144,25 +144,25 @@ open class InputBarButtonItem: UIButton, InputItem { private var onDeselectedAction: InputBarButtonItemAction? private var onEnabledAction: InputBarButtonItemAction? private var onDisabledAction: InputBarButtonItemAction? - + // MARK: - Initialization - + public convenience init() { self.init(frame: .zero) } - + public override init(frame: CGRect) { super.init(frame: frame) setup() } - + required public init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) setup() } - + // MARK: - Setup - + /// Sets up the default properties open func setup() { contentVerticalAlignment = .center @@ -176,9 +176,9 @@ open class InputBarButtonItem: UIButton, InputItem { adjustsImageWhenHighlighted = false addTarget(self, action: #selector(InputBarButtonItem.touchUpInsideAction), for: .touchUpInside) } - + // MARK: - Size Adjustment - + /// Sets the size of the InputBarButtonItem which overrides the intrinsicContentSize. When set to nil /// the default intrinsicContentSize is used. The new size will be laid out in the UIStackView that /// the InputBarButtonItem is held in @@ -194,9 +194,9 @@ open class InputBarButtonItem: UIButton, InputItem { } } } - + // MARK: - Hook Setup Methods - + /// Used to setup your own initial properties /// /// - Parameter item: A reference to Self @@ -206,7 +206,7 @@ open class InputBarButtonItem: UIButton, InputItem { item(self) return self } - + /// Sets the onKeyboardEditingBeginsAction /// /// - Parameter action: The new onKeyboardEditingBeginsAction @@ -216,7 +216,7 @@ open class InputBarButtonItem: UIButton, InputItem { onKeyboardEditingBeginsAction = action return self } - + /// Sets the onKeyboardEditingEndsAction /// /// - Parameter action: The new onKeyboardEditingEndsAction @@ -226,7 +226,7 @@ open class InputBarButtonItem: UIButton, InputItem { onKeyboardEditingEndsAction = action return self } - + /// Sets the onTextViewDidChangeAction /// /// - Parameter action: The new onTextViewDidChangeAction @@ -236,7 +236,7 @@ open class InputBarButtonItem: UIButton, InputItem { onTextViewDidChangeAction = action return self } - + /// Sets the onTouchUpInsideAction /// /// - Parameter action: The new onTouchUpInsideAction @@ -246,7 +246,7 @@ open class InputBarButtonItem: UIButton, InputItem { onTouchUpInsideAction = action return self } - + /// Sets the onSelectedAction /// /// - Parameter action: The new onSelectedAction @@ -256,7 +256,7 @@ open class InputBarButtonItem: UIButton, InputItem { onSelectedAction = action return self } - + /// Sets the onDeselectedAction /// /// - Parameter action: The new onDeselectedAction @@ -266,7 +266,7 @@ open class InputBarButtonItem: UIButton, InputItem { onDeselectedAction = action return self } - + /// Sets the onEnabledAction /// /// - Parameter action: The new onEnabledAction @@ -276,7 +276,7 @@ open class InputBarButtonItem: UIButton, InputItem { onEnabledAction = action return self } - + /// Sets the onDisabledAction /// /// - Parameter action: The new onDisabledAction @@ -286,34 +286,34 @@ open class InputBarButtonItem: UIButton, InputItem { onDisabledAction = action return self } - + // MARK: - InputItem Protocol - + /// Executes the onTextViewDidChangeAction with the given textView /// /// - Parameter textView: A reference to the InputTextView open func textViewDidChangeAction(with textView: InputTextView) { onTextViewDidChangeAction?(self, textView) } - + /// Executes the onKeyboardEditingEndsAction open func keyboardEditingEndsAction() { onKeyboardEditingEndsAction?(self) } - + /// Executes the onKeyboardEditingBeginsAction open func keyboardEditingBeginsAction() { onKeyboardEditingBeginsAction?(self) } - + /// Executes the onTouchUpInsideAction @objc open func touchUpInsideAction() { onTouchUpInsideAction?(self) } - + // MARK: - Static Spacers - + /// An InputBarButtonItem that's spacing property is set to be .flexible public static var flexibleSpace: InputBarButtonItem { let item = InputBarButtonItem() @@ -321,7 +321,7 @@ open class InputBarButtonItem: UIButton, InputItem { item.spacing = .flexible return item } - + /// An InputBarButtonItem that's spacing property is set to be .fixed with the width arguement public static func fixedSpace(_ width: CGFloat) -> InputBarButtonItem { let item = InputBarButtonItem() diff --git a/Pods/MessageInputBar/Sources/Extensions/NSMutableAttributedString+Extensions.swift b/Pods/MessageInputBar/Sources/Extensions/NSMutableAttributedString+Extensions.swift index 85cd508..69f42f0 100755 --- a/Pods/MessageInputBar/Sources/Extensions/NSMutableAttributedString+Extensions.swift +++ b/Pods/MessageInputBar/Sources/Extensions/NSMutableAttributedString+Extensions.swift @@ -25,23 +25,23 @@ import UIKit extension NSMutableAttributedString { - + @discardableResult internal func bold(_ text: String, fontSize: CGFloat = UIFont.preferredFont(forTextStyle: .body).pointSize, textColor: UIColor = .black) -> NSMutableAttributedString { - let attrs: [NSAttributedString.Key:AnyObject] = [ - NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: fontSize), - NSAttributedString.Key.foregroundColor : textColor + let attrs: [NSAttributedString.Key: AnyObject] = [ + NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: fontSize), + NSAttributedString.Key.foregroundColor: textColor ] let boldString = NSMutableAttributedString(string: text, attributes: attrs) self.append(boldString) return self } - + @discardableResult internal func normal(_ text: String, fontSize: CGFloat = UIFont.preferredFont(forTextStyle: .body).pointSize, textColor: UIColor = .black) -> NSMutableAttributedString { - let attrs:[NSAttributedString.Key:AnyObject] = [ - NSAttributedString.Key.font : UIFont.systemFont(ofSize: fontSize), - NSAttributedString.Key.foregroundColor : textColor + let attrs: [NSAttributedString.Key: AnyObject] = [ + NSAttributedString.Key.font: UIFont.systemFont(ofSize: fontSize), + NSAttributedString.Key.foregroundColor: textColor ] let normal = NSMutableAttributedString(string: text, attributes: attrs) self.append(normal) @@ -57,17 +57,17 @@ extension NSAttributedString { ns.replaceCharacters(in: range, with: attributedString) return ns } - + internal static func += (lhs: inout NSAttributedString, rhs: NSAttributedString) { let ns = NSMutableAttributedString(attributedString: lhs) ns.append(rhs) lhs = ns } - + internal static func + (lhs: NSAttributedString, rhs: NSAttributedString) -> NSAttributedString { let ns = NSMutableAttributedString(attributedString: lhs) ns.append(rhs) return NSAttributedString(attributedString: ns) } - + } diff --git a/Pods/MessageInputBar/Sources/Extensions/UIView+Extensions.swift b/Pods/MessageInputBar/Sources/Extensions/UIView+Extensions.swift index b38d39a..bbb0886 100644 --- a/Pods/MessageInputBar/Sources/Extensions/UIView+Extensions.swift +++ b/Pods/MessageInputBar/Sources/Extensions/UIView+Extensions.swift @@ -25,7 +25,7 @@ import UIKit extension UIView { - + internal func fillSuperview() { guard let superview = self.superview else { return @@ -52,7 +52,7 @@ extension UIView { ] NSLayoutConstraint.activate(constraints) } - + internal func constraint(equalTo size: CGSize) { guard superview != nil else { return } translatesAutoresizingMaskIntoConstraints = false @@ -61,55 +61,55 @@ extension UIView { heightAnchor.constraint(equalToConstant: size.height) ] NSLayoutConstraint.activate(constraints) - + } @discardableResult internal func addConstraints(_ top: NSLayoutYAxisAnchor? = nil, left: NSLayoutXAxisAnchor? = nil, bottom: NSLayoutYAxisAnchor? = nil, right: NSLayoutXAxisAnchor? = nil, topConstant: CGFloat = 0, leftConstant: CGFloat = 0, bottomConstant: CGFloat = 0, rightConstant: CGFloat = 0, widthConstant: CGFloat = 0, heightConstant: CGFloat = 0) -> [NSLayoutConstraint] { - + if self.superview == nil { return [] } translatesAutoresizingMaskIntoConstraints = false - + var constraints = [NSLayoutConstraint]() - + if let top = top { let constraint = topAnchor.constraint(equalTo: top, constant: topConstant) constraint.identifier = "top" constraints.append(constraint) } - + if let left = left { let constraint = leftAnchor.constraint(equalTo: left, constant: leftConstant) constraint.identifier = "left" constraints.append(constraint) } - + if let bottom = bottom { let constraint = bottomAnchor.constraint(equalTo: bottom, constant: -bottomConstant) constraint.identifier = "bottom" constraints.append(constraint) } - + if let right = right { let constraint = rightAnchor.constraint(equalTo: right, constant: -rightConstant) constraint.identifier = "right" constraints.append(constraint) } - + if widthConstant > 0 { let constraint = widthAnchor.constraint(equalToConstant: widthConstant) constraint.identifier = "width" constraints.append(constraint) } - + if heightConstant > 0 { let constraint = heightAnchor.constraint(equalToConstant: heightConstant) constraint.identifier = "height" constraints.append(constraint) } - + NSLayoutConstraint.activate(constraints) return constraints } diff --git a/Pods/MessageInputBar/Sources/MessageInputBar.swift b/Pods/MessageInputBar/Sources/MessageInputBar.swift index e1b80f7..61f4d97 100644 --- a/Pods/MessageInputBar/Sources/MessageInputBar.swift +++ b/Pods/MessageInputBar/Sources/MessageInputBar.swift @@ -26,12 +26,12 @@ import UIKit /// A powerful InputAccessoryView ideal for messaging applications open class MessageInputBar: UIView { - + // MARK: - Properties - + /// A delegate to broadcast notifications from the `MessageInputBar` open weak var delegate: MessageInputBarDelegate? - + /// The background UIView anchored to the bottom, left, and right of the MessageInputBar /// with a top anchor equal to the bottom of the top InputStackView open var backgroundView: UIView = { @@ -40,7 +40,7 @@ open class MessageInputBar: UIView { view.backgroundColor = UIColor(red: 247/255, green: 247/255, blue: 247/255, alpha: 1.0) return view }() - + /// A content UIView that holds the left/right/bottom InputStackViews and InputTextView. Anchored to the bottom of the /// topStackView and inset by the padding UIEdgeInsets open var contentView: UIView = { @@ -48,7 +48,7 @@ open class MessageInputBar: UIView { view.translatesAutoresizingMaskIntoConstraints = false return view }() - + /** A UIVisualEffectView that adds a blur effect to make the view appear transparent. @@ -61,7 +61,7 @@ open class MessageInputBar: UIView { view.translatesAutoresizingMaskIntoConstraints = false return view }() - + /// Determines if the MessageInputBar should have a translucent effect open var isTranslucent: Bool = false { didSet { @@ -74,10 +74,10 @@ open class MessageInputBar: UIView { backgroundView.backgroundColor = isTranslucent ? color.withAlphaComponent(0.75) : color.withAlphaComponent(1.0) } } - + /// A SeparatorLine that is anchored at the top of the MessageInputBar with a height of 1 public let separatorLine = SeparatorLine() - + /** The InputStackView at the InputStackView.top position @@ -90,7 +90,7 @@ open class MessageInputBar: UIView { stackView.alignment = .fill return stackView }() - + /** The InputStackView at the InputStackView.left position @@ -98,7 +98,7 @@ open class MessageInputBar: UIView { 1. It's axis is initially set to .horizontal */ public let leftStackView = InputStackView(axis: .horizontal, spacing: 0) - + /** The InputStackView at the InputStackView.right position @@ -106,7 +106,7 @@ open class MessageInputBar: UIView { 1. It's axis is initially set to .horizontal */ public let rightStackView = InputStackView(axis: .horizontal, spacing: 0) - + /** The InputStackView at the InputStackView.bottom position @@ -115,7 +115,7 @@ open class MessageInputBar: UIView { 2. It's spacing is initially set to 15 */ public let bottomStackView = InputStackView(axis: .horizontal, spacing: 15) - + /// The InputTextView a user can input a message in open lazy var inputTextView: InputTextView = { [weak self] in let inputTextView = InputTextView() @@ -136,7 +136,7 @@ open class MessageInputBar: UIView { $0.messageInputBar?.didSelectSendButton() } }() - + /** The anchor contants used by the InputStackView's and InputTextView to create padding within the MessageInputBar @@ -155,7 +155,7 @@ open class MessageInputBar: UIView { updatePadding() } } - + /** The anchor constants used by the top InputStackView @@ -174,7 +174,7 @@ open class MessageInputBar: UIView { updateTopStackViewPadding() } } - + /** The anchor constants used by the InputStackView @@ -190,33 +190,33 @@ open class MessageInputBar: UIView { updateTextViewPadding() } } - + /// Returns the most recent size calculated by `calculateIntrinsicContentSize()` open override var intrinsicContentSize: CGSize { return cachedIntrinsicContentSize } - + /// The intrinsicContentSize can change a lot so the delegate method /// `inputBar(self, didChangeIntrinsicContentTo: size)` only needs to be called /// when it's different public private(set) var previousIntrinsicContentSize: CGSize? - + /// The most recent calculation of the intrinsicContentSize private lazy var cachedIntrinsicContentSize: CGSize = calculateIntrinsicContentSize() - + /// A boolean that indicates if the maxTextViewHeight has been met. Keeping track of this /// improves the performance public private(set) var isOverMaxTextViewHeight = false - + /// A boolean that when set as `TRUE` will always enable the `InputTextView` to be anchored to the /// height of `maxTextViewHeight` /// The default value is `FALSE` public private(set) var shouldForceTextViewMaxHeight = false - + /// A boolean that determines if the `maxTextViewHeight` should be maintained automatically. /// To control the maximum height of the view yourself, set this to `false`. open var shouldAutoUpdateMaxTextViewHeight = true - + /// The maximum height that the InputTextView can reach. /// This is set automatically when `shouldAutoUpdateMaxTextViewHeight` is true. /// To control the height yourself, make sure to set `shouldAutoUpdateMaxTextViewHeight` to false. @@ -226,55 +226,55 @@ open class MessageInputBar: UIView { invalidateIntrinsicContentSize() } } - + /// A boolean that determines whether the sendButton's `isEnabled` state should be managed automatically. open var shouldManageSendButtonEnabledState = true - + /// The height that will fit the current text in the InputTextView based on its current bounds public var requiredInputTextViewHeight: CGFloat { let maxTextViewSize = CGSize(width: inputTextView.bounds.width, height: .greatestFiniteMagnitude) return inputTextView.sizeThatFits(maxTextViewSize).height.rounded(.down) } - + /// The fixed widthAnchor constant of the leftStackView public private(set) var leftStackViewWidthConstant: CGFloat = 0 { didSet { leftStackViewLayoutSet?.width?.constant = leftStackViewWidthConstant } } - + /// The fixed widthAnchor constant of the rightStackView public private(set) var rightStackViewWidthConstant: CGFloat = 52 { didSet { rightStackViewLayoutSet?.width?.constant = rightStackViewWidthConstant } } - + /// Holds the InputPlugin plugins that can be used to extend the functionality of the MessageInputBar open var plugins = [InputPlugin]() - + /// The InputBarItems held in the leftStackView public private(set) var leftStackViewItems: [InputItem] = [] - + /// The InputBarItems held in the rightStackView public private(set) var rightStackViewItems: [InputItem] = [] - + /// The InputBarItems held in the bottomStackView public private(set) var bottomStackViewItems: [InputItem] = [] - + /// The InputBarItems held in the topStackView public private(set) var topStackViewItems: [InputItem] = [] - + /// The InputBarItems held to make use of their hooks but they are not automatically added to a UIStackView open var nonStackViewItems: [InputItem] = [] - + /// Returns a flatMap of all the items in each of the UIStackViews public var items: [InputItem] { return [leftStackViewItems, rightStackViewItems, bottomStackViewItems, topStackViewItems, nonStackViewItems].flatMap { $0 } } - + // MARK: - Auto-Layout Constraint Sets - + private var textViewLayoutSet: NSLayoutConstraintSet? private var textViewHeightAnchor: NSLayoutConstraint? private var topStackViewLayoutSet: NSLayoutConstraintSet? @@ -284,43 +284,43 @@ open class MessageInputBar: UIView { private var contentViewLayoutSet: NSLayoutConstraintSet? private var windowAnchor: NSLayoutConstraint? private var backgroundViewBottomAnchor: NSLayoutConstraint? - + // MARK: - Initialization - + public convenience init() { self.init(frame: .zero) } - + public override init(frame: CGRect) { super.init(frame: frame) setup() } - + required public init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) setup() } - + deinit { NotificationCenter.default.removeObserver(self) } - + open override func didMoveToWindow() { super.didMoveToWindow() setupConstraints(to: window) } - + // MARK: - Setup - + /// Sets up the default properties open func setup() { - + autoresizingMask = [.flexibleHeight] setupSubviews() setupConstraints() setupObservers() } - + /// Adds the required notification observers private func setupObservers() { NotificationCenter.default.addObserver(self, @@ -336,10 +336,10 @@ open class MessageInputBar: UIView { selector: #selector(MessageInputBar.inputTextViewDidEndEditing), name: UITextView.textDidEndEditingNotification, object: inputTextView) } - + /// Adds all of the subviews private func setupSubviews() { - + addSubview(backgroundView) addSubview(topStackView) addSubview(contentView) @@ -350,73 +350,73 @@ open class MessageInputBar: UIView { contentView.addSubview(bottomStackView) setStackViewItems([sendButton], forStack: .right, animated: false) } - + /// Sets up the initial constraints of each subview private func setupConstraints() { - + // The constraints within the MessageInputBar separatorLine.addConstraints(topAnchor, left: leftAnchor, right: rightAnchor, heightConstant: separatorLine.height) backgroundViewBottomAnchor = backgroundView.bottomAnchor.constraint(equalTo: bottomAnchor) backgroundViewBottomAnchor?.isActive = true backgroundView.addConstraints(topStackView.bottomAnchor, left: leftAnchor, right: rightAnchor) - + topStackViewLayoutSet = NSLayoutConstraintSet( - top: topStackView.topAnchor.constraint(equalTo: topAnchor, constant: topStackViewPadding.top), + top: topStackView.topAnchor.constraint(equalTo: topAnchor, constant: topStackViewPadding.top), bottom: topStackView.bottomAnchor.constraint(equalTo: contentView.topAnchor, constant: -padding.top), - left: topStackView.leftAnchor.constraint(equalTo: leftAnchor, constant: topStackViewPadding.left), - right: topStackView.rightAnchor.constraint(equalTo: rightAnchor, constant: -topStackViewPadding.right) + left: topStackView.leftAnchor.constraint(equalTo: leftAnchor, constant: topStackViewPadding.left), + right: topStackView.rightAnchor.constraint(equalTo: rightAnchor, constant: -topStackViewPadding.right) ) - + contentViewLayoutSet = NSLayoutConstraintSet( - top: contentView.topAnchor.constraint(equalTo: topStackView.bottomAnchor, constant: padding.top), + top: contentView.topAnchor.constraint(equalTo: topStackView.bottomAnchor, constant: padding.top), bottom: contentView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -padding.bottom), - left: contentView.leftAnchor.constraint(equalTo: leftAnchor, constant: padding.left), - right: contentView.rightAnchor.constraint(equalTo: rightAnchor, constant: -padding.right) + left: contentView.leftAnchor.constraint(equalTo: leftAnchor, constant: padding.left), + right: contentView.rightAnchor.constraint(equalTo: rightAnchor, constant: -padding.right) ) - + if #available(iOS 11.0, *) { // Switch to safeAreaLayoutGuide contentViewLayoutSet?.bottom = contentView.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor, constant: -padding.bottom) contentViewLayoutSet?.left = contentView.leftAnchor.constraint(equalTo: safeAreaLayoutGuide.leftAnchor, constant: padding.left) contentViewLayoutSet?.right = contentView.rightAnchor.constraint(equalTo: safeAreaLayoutGuide.rightAnchor, constant: -padding.right) - + topStackViewLayoutSet?.left = topStackView.leftAnchor.constraint(equalTo: safeAreaLayoutGuide.leftAnchor, constant: topStackViewPadding.left) topStackViewLayoutSet?.right = topStackView.rightAnchor.constraint(equalTo: safeAreaLayoutGuide.rightAnchor, constant: -topStackViewPadding.right) } - + // Constraints Within the contentView textViewLayoutSet = NSLayoutConstraintSet( - top: inputTextView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: textViewPadding.top), + top: inputTextView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: textViewPadding.top), bottom: inputTextView.bottomAnchor.constraint(equalTo: bottomStackView.topAnchor, constant: -textViewPadding.bottom), - left: inputTextView.leftAnchor.constraint(equalTo: leftStackView.rightAnchor, constant: textViewPadding.left), - right: inputTextView.rightAnchor.constraint(equalTo: rightStackView.leftAnchor, constant: -textViewPadding.right) + left: inputTextView.leftAnchor.constraint(equalTo: leftStackView.rightAnchor, constant: textViewPadding.left), + right: inputTextView.rightAnchor.constraint(equalTo: rightStackView.leftAnchor, constant: -textViewPadding.right) ) maxTextViewHeight = calculateMaxTextViewHeight() textViewHeightAnchor = inputTextView.heightAnchor.constraint(equalToConstant: maxTextViewHeight) - + leftStackViewLayoutSet = NSLayoutConstraintSet( - top: leftStackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 0), + top: leftStackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 0), bottom: leftStackView.bottomAnchor.constraint(equalTo: inputTextView.bottomAnchor, constant: 0), - left: leftStackView.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 0), - width: leftStackView.widthAnchor.constraint(equalToConstant: leftStackViewWidthConstant) + left: leftStackView.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 0), + width: leftStackView.widthAnchor.constraint(equalToConstant: leftStackViewWidthConstant) ) - + rightStackViewLayoutSet = NSLayoutConstraintSet( - top: rightStackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 0), + top: rightStackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 0), bottom: rightStackView.bottomAnchor.constraint(equalTo: inputTextView.bottomAnchor, constant: 0), - right: rightStackView.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: 0), - width: rightStackView.widthAnchor.constraint(equalToConstant: rightStackViewWidthConstant) + right: rightStackView.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: 0), + width: rightStackView.widthAnchor.constraint(equalToConstant: rightStackViewWidthConstant) ) - + bottomStackViewLayoutSet = NSLayoutConstraintSet( - top: bottomStackView.topAnchor.constraint(equalTo: inputTextView.bottomAnchor, constant: textViewPadding.bottom), + top: bottomStackView.topAnchor.constraint(equalTo: inputTextView.bottomAnchor, constant: textViewPadding.bottom), bottom: bottomStackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: 0), - left: bottomStackView.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 0), - right: bottomStackView.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: 0) + left: bottomStackView.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 0), + right: bottomStackView.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: 0) ) activateConstraints() } - + /// Respect iPhone X safeAreaInsets /// Adds a constraint to anchor the bottomAnchor of the contentView to the window's safeAreaLayoutGuide.bottomAnchor /// @@ -434,9 +434,9 @@ open class MessageInputBar: UIView { } } } - + // MARK: - Constraint Layout Updates - + /// Updates the constraint constants that correspond to the padding UIEdgeInsets private func updatePadding() { topStackViewLayoutSet?.bottom?.constant = -padding.top @@ -446,7 +446,7 @@ open class MessageInputBar: UIView { contentViewLayoutSet?.bottom?.constant = -padding.bottom windowAnchor?.constant = -padding.bottom } - + /// Updates the constraint constants that correspond to the textViewPadding UIEdgeInsets private func updateTextViewPadding() { textViewLayoutSet?.top?.constant = textViewPadding.top @@ -455,14 +455,14 @@ open class MessageInputBar: UIView { textViewLayoutSet?.bottom?.constant = -textViewPadding.bottom bottomStackViewLayoutSet?.top?.constant = textViewPadding.bottom } - + /// Updates the constraint constants that correspond to the topStackViewPadding UIEdgeInsets private func updateTopStackViewPadding() { topStackViewLayoutSet?.top?.constant = topStackViewPadding.top topStackViewLayoutSet?.left?.constant = topStackViewPadding.left topStackViewLayoutSet?.right?.constant = -topStackViewPadding.right } - + /// Invalidates the view’s intrinsic content size open override func invalidateIntrinsicContentSize() { super.invalidateIntrinsicContentSize() @@ -472,12 +472,12 @@ open class MessageInputBar: UIView { previousIntrinsicContentSize = cachedIntrinsicContentSize } } - + /// Calculates the correct intrinsicContentSize of the MessageInputBar /// /// - Returns: The required intrinsicContentSize open func calculateIntrinsicContentSize() -> CGSize { - + var inputTextViewHeight = requiredInputTextViewHeight if inputTextViewHeight >= maxTextViewHeight { if !isOverMaxTextViewHeight { @@ -495,7 +495,7 @@ open class MessageInputBar: UIView { inputTextView.invalidateIntrinsicContentSize() } } - + // Calculate the required height let totalPadding = padding.top + padding.bottom + topStackViewPadding.top + textViewPadding.top + textViewPadding.bottom let topStackViewHeight = topStackView.arrangedSubviews.count > 0 ? topStackView.bounds.height : 0 @@ -504,8 +504,7 @@ open class MessageInputBar: UIView { let requiredHeight = inputTextViewHeight + totalPadding + verticalStackViewHeight return CGSize(width: bounds.width, height: requiredHeight) } - - + /// Returns the max height the InputTextView can grow to based on the UIScreen /// /// - Returns: Max Height @@ -515,14 +514,14 @@ open class MessageInputBar: UIView { } return (UIScreen.main.bounds.height / 5).rounded(.down) } - + // MARK: - Layout Helper Methods - + /// Layout the given InputStackView's /// /// - Parameter positions: The InputStackView's to layout public func layoutStackViews(_ positions: [InputStackView.Position] = [.left, .right, .bottom, .top]) { - + guard superview != nil else { return } for position in positions { switch position { @@ -541,7 +540,7 @@ open class MessageInputBar: UIView { } } } - + /// Performs layout changes over the main thread /// /// - Parameters: @@ -558,7 +557,7 @@ open class MessageInputBar: UIView { } activateConstraints() } - + /// Activates the NSLayoutConstraintSet's private func activateConstraints() { contentViewLayoutSet?.activate() @@ -568,7 +567,7 @@ open class MessageInputBar: UIView { bottomStackViewLayoutSet?.activate() topStackViewLayoutSet?.activate() } - + /// Deactivates the NSLayoutConstraintSet's private func deactivateConstraints() { contentViewLayoutSet?.deactivate() @@ -578,7 +577,7 @@ open class MessageInputBar: UIView { bottomStackViewLayoutSet?.deactivate() topStackViewLayoutSet?.deactivate() } - + /// Removes all of the arranged subviews from the InputStackView and adds the given items. /// Sets the messageInputBar property of the InputBarButtonItem /// @@ -587,7 +586,7 @@ open class MessageInputBar: UIView { /// - position: The targeted InputStackView /// - animated: If the layout should be animated open func setStackViewItems(_ items: [InputItem], forStack position: InputStackView.Position, animated: Bool) { - + func setNewItems() { switch position { case .left: @@ -641,12 +640,12 @@ open class MessageInputBar: UIView { } invalidateIntrinsicContentSize() } - + performLayout(animated) { setNewItems() } } - + /// Sets the leftStackViewWidthConstant /// /// - Parameters: @@ -660,7 +659,7 @@ open class MessageInputBar: UIView { self.superview?.superview?.layoutIfNeeded() } } - + /// Sets the rightStackViewWidthConstant /// /// - Parameters: @@ -674,7 +673,7 @@ open class MessageInputBar: UIView { self.superview?.superview?.layoutIfNeeded() } } - + /// Sets the `shouldForceTextViewMaxHeight` property /// /// - Parameters: @@ -688,9 +687,9 @@ open class MessageInputBar: UIView { self.superview?.superview?.layoutIfNeeded() } } - + // MARK: - Notifications/Hooks - + /// Invalidates the intrinsicContentSize open override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { super.traitCollectionDidChange(previousTraitCollection) @@ -702,7 +701,7 @@ open class MessageInputBar: UIView { } } } - + /// Invalidates the intrinsicContentSize @objc open func orientationDidChange() { @@ -711,16 +710,16 @@ open class MessageInputBar: UIView { } invalidateIntrinsicContentSize() } - + /// Enables/Disables the sendButton based on the InputTextView's text being empty /// Calls each items `textViewDidChangeAction` method /// Calls the delegates `textViewTextDidChangeTo` method /// Invalidates the intrinsicContentSize @objc open func inputTextViewDidChange() { - + let trimmedText = inputTextView.text.trimmingCharacters(in: .whitespacesAndNewlines) - + if shouldManageSendButtonEnabledState { var isEnabled = !trimmedText.isEmpty if !isEnabled { @@ -729,43 +728,43 @@ open class MessageInputBar: UIView { } sendButton.isEnabled = isEnabled } - + // Capture change before iterating over the InputItem's let shouldInvalidateIntrinsicContentSize = requiredInputTextViewHeight != inputTextView.bounds.height - + items.forEach { $0.textViewDidChangeAction(with: self.inputTextView) } delegate?.messageInputBar(self, textViewTextDidChangeTo: trimmedText) - + if shouldInvalidateIntrinsicContentSize { // Prevent un-needed content size invalidation invalidateIntrinsicContentSize() } } - + /// Calls each items `keyboardEditingBeginsAction` method @objc open func inputTextViewDidBeginEditing() { items.forEach { $0.keyboardEditingBeginsAction() } } - + /// Calls each items `keyboardEditingEndsAction` method @objc open func inputTextViewDidEndEditing() { items.forEach { $0.keyboardEditingEndsAction() } } - + // MARK: - Plugins - + /// Reloads each of the plugins open func reloadPlugins() { plugins.forEach { $0.reloadData() } } - + /// Invalidates each of the plugins open func invalidatePlugins() { plugins.forEach { $0.invalidate() } } - + // MARK: - User Actions /// Calls the delegates `didPressSendButtonWith` method diff --git a/Pods/MessageInputBar/Sources/Models/NSConstraintLayoutSet.swift b/Pods/MessageInputBar/Sources/Models/NSConstraintLayoutSet.swift index ba098a3..c114b92 100644 --- a/Pods/MessageInputBar/Sources/Models/NSConstraintLayoutSet.swift +++ b/Pods/MessageInputBar/Sources/Models/NSConstraintLayoutSet.swift @@ -25,7 +25,7 @@ import UIKit internal class NSLayoutConstraintSet { - + internal var top: NSLayoutConstraint? internal var bottom: NSLayoutConstraint? internal var left: NSLayoutConstraint? @@ -34,7 +34,7 @@ internal class NSLayoutConstraintSet { internal var centerY: NSLayoutConstraint? internal var width: NSLayoutConstraint? internal var height: NSLayoutConstraint? - + internal init(top: NSLayoutConstraint? = nil, bottom: NSLayoutConstraint? = nil, left: NSLayoutConstraint? = nil, right: NSLayoutConstraint? = nil, centerX: NSLayoutConstraint? = nil, centerY: NSLayoutConstraint? = nil, @@ -60,7 +60,7 @@ internal class NSLayoutConstraintSet { } return available } - + /// Activates all of the non-nil constraints /// /// - Returns: Self @@ -69,7 +69,7 @@ internal class NSLayoutConstraintSet { NSLayoutConstraint.activate(availableConstraints) return self } - + /// Deactivates all of the non-nil constraints /// /// - Returns: Self diff --git a/Pods/MessageInputBar/Sources/Protocols/InputItem.swift b/Pods/MessageInputBar/Sources/Protocols/InputItem.swift index e5a13b6..b0f25ad 100755 --- a/Pods/MessageInputBar/Sources/Protocols/InputItem.swift +++ b/Pods/MessageInputBar/Sources/Protocols/InputItem.swift @@ -26,19 +26,19 @@ import UIKit /// InputItem is a protocol that links elements to the MessageInputBar to make them reactive public protocol InputItem: AnyObject { - + /// A reference to the MessageInputBar. Set automatically when inserted into an InputStackView var messageInputBar: MessageInputBar? { get set } - + /// A reference to the InputStackView that the InputItem is contained in. Set when inserted into an InputStackView var parentStackViewPosition: InputStackView.Position? { get set } - + /// A hook that is called when the InputTextView's text is changed func textViewDidChangeAction(with textView: InputTextView) - + /// A hook that is called when the InputTextView is resigned as the first responder func keyboardEditingEndsAction() - + /// A hook that is called when the InputTextView is made the first responder func keyboardEditingBeginsAction() } diff --git a/Pods/MessageInputBar/Sources/Protocols/InputPlugin.swift b/Pods/MessageInputBar/Sources/Protocols/InputPlugin.swift index e2b8cf4..43d7f1c 100755 --- a/Pods/MessageInputBar/Sources/Protocols/InputPlugin.swift +++ b/Pods/MessageInputBar/Sources/Protocols/InputPlugin.swift @@ -26,13 +26,13 @@ import UIKit /// `InputPlugin` is a protocol that makes integrating plugins to the `MessageInputBar` easy. public protocol InputPlugin: AnyObject { - + /// Should reload the state if the `InputPlugin` func reloadData() - + /// Should remove any content that the `InputPlugin` is managing func invalidate() - + /// Should handle the input of data types that an `InputPlugin` manages /// /// - Parameter object: The object to input diff --git a/Pods/MessageInputBar/Sources/Protocols/MessageInputBarDelegate.swift b/Pods/MessageInputBar/Sources/Protocols/MessageInputBarDelegate.swift index 39c5b18..116440c 100644 --- a/Pods/MessageInputBar/Sources/Protocols/MessageInputBarDelegate.swift +++ b/Pods/MessageInputBar/Sources/Protocols/MessageInputBarDelegate.swift @@ -26,14 +26,14 @@ import Foundation /// A protocol that can receive different event notifications from the MessageInputBar. public protocol MessageInputBarDelegate: AnyObject { - + /// Called when the default send button has been selected. /// /// - Parameters: /// - inputBar: The `MessageInputBar`. /// - text: The current text in the `InputTextView` of the `MessageInputBar`. func messageInputBar(_ inputBar: MessageInputBar, didPressSendButtonWith text: String) - + /// Called when the instrinsicContentSize of the MessageInputBar has changed. /// Can be used for adjusting content insets on other views to make sure /// the MessageInputBar does not cover up any other view. @@ -42,7 +42,7 @@ public protocol MessageInputBarDelegate: AnyObject { /// - inputBar: The `MessageInputBar`. /// - size: The new instrinsic content size. func messageInputBar(_ inputBar: MessageInputBar, didChangeIntrinsicContentTo size: CGSize) - + /// Called when the `MessageInputBar`'s `InputTextView`'s text has changed. /// Useful for adding your own logic without the need of assigning a delegate or notification. /// @@ -53,10 +53,10 @@ public protocol MessageInputBarDelegate: AnyObject { } public extension MessageInputBarDelegate { - + func messageInputBar(_ inputBar: MessageInputBar, didPressSendButtonWith text: String) {} - + func messageInputBar(_ inputBar: MessageInputBar, didChangeIntrinsicContentTo size: CGSize) {} - + func messageInputBar(_ inputBar: MessageInputBar, textViewTextDidChangeTo text: String) {} } diff --git a/Pods/MessageInputBar/Sources/Views/InputStackView.swift b/Pods/MessageInputBar/Sources/Views/InputStackView.swift index 897f2bf..7b12b0c 100644 --- a/Pods/MessageInputBar/Sources/Views/InputStackView.swift +++ b/Pods/MessageInputBar/Sources/Views/InputStackView.swift @@ -33,7 +33,7 @@ import UIKit 3. The distribution property needs to be based on its arranged subviews intrinsicContentSize so it is not recommended to change it */ open class InputStackView: UIStackView { - + /// The stack view position in the MessageInputBar /// /// - left: Left Stack View @@ -43,26 +43,26 @@ open class InputStackView: UIStackView { public enum Position { case left, right, bottom, top } - + // MARK: Initialization - + public convenience init(axis: NSLayoutConstraint.Axis, spacing: CGFloat) { self.init(frame: .zero) self.axis = axis self.spacing = spacing } - + public override init(frame: CGRect) { super.init(frame: frame) setup() } - + required public init(coder: NSCoder) { super.init(coder: coder) } - + // MARK: - Setup - + /// Sets up the default properties open func setup() { translatesAutoresizingMaskIntoConstraints = false diff --git a/Pods/MessageInputBar/Sources/Views/InputTextView.swift b/Pods/MessageInputBar/Sources/Views/InputTextView.swift index 294f387..fc446a3 100644 --- a/Pods/MessageInputBar/Sources/Views/InputTextView.swift +++ b/Pods/MessageInputBar/Sources/Views/InputTextView.swift @@ -34,32 +34,32 @@ import UIKit 4. Will pass a pasted image it's `MessageInputBar`'s `InputManager`s */ open class InputTextView: UITextView { - + // MARK: - Properties - + open override var text: String! { didSet { postTextViewDidChangeNotification() } } - + open override var attributedText: NSAttributedString! { didSet { postTextViewDidChangeNotification() } } - + /// The images that are currently stored as `NSTextAttachment`'s open var images: [UIImage] { return parseForAttachedImages() } - + open var components: [Any] { return parseForComponents() } - + open var isImagePasteEnabled: Bool = true - + /// A UILabel that holds the `InputTextView`'s placeholder text public let placeholderLabel: UILabel = { let label = UILabel() @@ -70,49 +70,49 @@ open class InputTextView: UITextView { label.translatesAutoresizingMaskIntoConstraints = false return label }() - + /// The placeholder text that appears when there is no text. The default value is "New Message" open var placeholder: String? = "New Message" { didSet { placeholderLabel.text = placeholder } } - + /// The placeholderLabel's textColor open var placeholderTextColor: UIColor? = .lightGray { didSet { placeholderLabel.textColor = placeholderTextColor } } - + /// The `UIEdgeInsets` the placeholderLabel has within the `InputTextView` - open var placeholderLabelInsets: UIEdgeInsets = UIEdgeInsets(top: 8, left: 4, bottom: 8, right: 4) { + open var placeholderLabelInsets: UIEdgeInsets = UIEdgeInsets(top: 8, left: 4, bottom: 8, right: 4) { didSet { updateConstraintsForPlaceholderLabel() } } - + /// The font of the `InputTextView`. When set the placeholderLabel's font is also updated open override var font: UIFont! { didSet { placeholderLabel.font = font } } - + /// The `textAlignment` of the `InputTextView`. When set the placeholderLabel's `textAlignment` is also updated open override var textAlignment: NSTextAlignment { didSet { placeholderLabel.textAlignment = textAlignment } } - + /// The textContainerInset of the `InputTextView`. When set the placeholderLabelInsets is also updated open override var textContainerInset: UIEdgeInsets { didSet { placeholderLabelInsets = textContainerInset } } - + open override var scrollIndicatorInsets: UIEdgeInsets { didSet { // When .zero a rendering issue can occur @@ -124,38 +124,38 @@ open class InputTextView: UITextView { } } } - + /// A weak reference to the `MessageInputBar` that the `InputTextView` is contained within open weak var messageInputBar: MessageInputBar? - + /// The constraints of the placeholderLabel private var placeholderLabelConstraintSet: NSLayoutConstraintSet? - + // MARK: - Initializers - + public convenience init() { self.init(frame: .zero) } - + public override init(frame: CGRect, textContainer: NSTextContainer?) { super.init(frame: frame, textContainer: textContainer) setup() } - + required public init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) setup() } - + deinit { NotificationCenter.default.removeObserver(self) } - + // MARK: - Setup - + /// Sets up the default properties open func setup() { - + backgroundColor = .clear font = UIFont.preferredFont(forTextStyle: .body) isScrollEnabled = false @@ -172,10 +172,10 @@ open class InputTextView: UITextView { addSubview(placeholderLabel) placeholderLabelConstraintSet = NSLayoutConstraintSet( - top: placeholderLabel.topAnchor.constraint(equalTo: topAnchor, constant: placeholderLabelInsets.top), - bottom: placeholderLabel.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -placeholderLabelInsets.bottom), - left: placeholderLabel.leftAnchor.constraint(equalTo: leftAnchor, constant: placeholderLabelInsets.left), - right: placeholderLabel.rightAnchor.constraint(equalTo: rightAnchor, constant: -placeholderLabelInsets.right), + top: placeholderLabel.topAnchor.constraint(equalTo: topAnchor, constant: placeholderLabelInsets.top), + bottom: placeholderLabel.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -placeholderLabelInsets.bottom), + left: placeholderLabel.leftAnchor.constraint(equalTo: leftAnchor, constant: placeholderLabelInsets.left), + right: placeholderLabel.rightAnchor.constraint(equalTo: rightAnchor, constant: -placeholderLabelInsets.right), centerX: placeholderLabel.centerXAnchor.constraint(equalTo: centerXAnchor), centerY: placeholderLabel.centerYAnchor.constraint(equalTo: centerYAnchor) ) @@ -183,10 +183,10 @@ open class InputTextView: UITextView { placeholderLabelConstraintSet?.centerY?.priority = .defaultLow placeholderLabelConstraintSet?.activate() } - + /// Adds the required notification observers private func setupObservers() { - + NotificationCenter.default.addObserver(self, selector: #selector(InputTextView.redrawTextAttachments), name: UIDevice.orientationDidChangeNotification, object: nil) @@ -194,7 +194,7 @@ open class InputTextView: UITextView { selector: #selector(InputTextView.textViewTextDidChange), name: UITextView.textDidChangeNotification, object: nil) } - + /// Updates the placeholderLabels constraint constants to match the placeholderLabelInsets private func updateConstraintsForPlaceholderLabel() { @@ -203,31 +203,30 @@ open class InputTextView: UITextView { placeholderLabelConstraintSet?.left?.constant = placeholderLabelInsets.left placeholderLabelConstraintSet?.right?.constant = -placeholderLabelInsets.right } - - + // MARK: - Notification - + private func postTextViewDidChangeNotification() { NotificationCenter.default.post(name: UITextView.textDidChangeNotification, object: self) } - + @objc private func textViewTextDidChange() { placeholderLabel.isHidden = !text.isEmpty } - + // MARK: - Image Paste Support - + open override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool { - + if action == NSSelectorFromString("paste:") && UIPasteboard.general.image != nil { return isImagePasteEnabled } return super.canPerformAction(action, withSender: sender) } - + open override func paste(_ sender: Any?) { - + guard let image = UIPasteboard.general.image else { return super.paste(sender) } @@ -241,66 +240,66 @@ open class InputTextView: UITextView { } } } - + /// Addes a new UIImage to the NSTextContainer as an NSTextAttachment /// /// - Parameter image: The image to add private func pasteImageInTextContainer(with image: UIImage) { - + // Add the new image as an NSTextAttachment let attributedImageString = NSAttributedString(attachment: textAttachment(using: image)) - + let isEmpty = attributedText.length == 0 - + // Add a new line character before the image, this is what iMessage does let newAttributedStingComponent = isEmpty ? NSMutableAttributedString(string: "") : NSMutableAttributedString(string: "\n") newAttributedStingComponent.append(attributedImageString) - + // Add a new line character after the image, this is what iMessage does newAttributedStingComponent.append(NSAttributedString(string: "\n")) - + // The attributes that should be applied to the new NSAttributedString to match the current attributes let attributes: [NSAttributedString.Key: Any] = [ NSAttributedString.Key.font: font ?? UIFont.preferredFont(forTextStyle: .body), NSAttributedString.Key.foregroundColor: textColor ?? .black ] newAttributedStingComponent.addAttributes(attributes, range: NSRange(location: 0, length: newAttributedStingComponent.length)) - + textStorage.beginEditing() // Paste over selected text textStorage.replaceCharacters(in: selectedRange, with: newAttributedStingComponent) textStorage.endEditing() - + // Advance the range to the selected range plus the number of characters added let location = selectedRange.location + (isEmpty ? 2 : 3) selectedRange = NSRange(location: location, length: 0) - + // Broadcast a notification to recievers such as the MessageInputBar which will handle resizing postTextViewDidChangeNotification() } - + /// Returns an NSTextAttachment the provided image that will fit inside the NSTextContainer /// /// - Parameter image: The image to create an attachment with /// - Returns: The formatted NSTextAttachment private func textAttachment(using image: UIImage) -> NSTextAttachment { - + guard let cgImage = image.cgImage else { return NSTextAttachment() } let scale = image.size.width / (frame.width - 2 * (textContainerInset.left + textContainerInset.right)) let textAttachment = NSTextAttachment() textAttachment.image = UIImage(cgImage: cgImage, scale: scale, orientation: .up) return textAttachment } - + /// Returns all images that exist as NSTextAttachment's /// /// - Returns: An array of type UIImage private func parseForAttachedImages() -> [UIImage] { - + var images = [UIImage]() let range = NSRange(location: 0, length: attributedText.length) attributedText.enumerateAttribute(.attachment, in: range, options: [], using: { value, range, _ -> Void in - + if let attachment = value as? NSTextAttachment { if let image = attachment.image { images.append(image) @@ -313,13 +312,13 @@ open class InputTextView: UITextView { }) return images } - + /// Returns an array of components (either a String or UIImage) that makes up the textContainer in /// the order that they were typed /// /// - Returns: An array of objects guaranteed to be of UIImage or String private func parseForComponents() -> [Any] { - + var components = [Any]() var attachments = [(NSRange, UIImage)]() let length = attributedText.length @@ -331,52 +330,51 @@ open class InputTextView: UITextView { } else if let image = attachment.image(forBounds: attachment.bounds, textContainer: nil, characterIndex: range.location) { - attachments.append((range,image)) + attachments.append((range, image)) } } } - + var curLocation = 0 if attachments.count == 0 { let text = attributedText.string.trimmingCharacters(in: .whitespacesAndNewlines) if !text.isEmpty { components.append(text) } - } - else { + } else { attachments.forEach { (attachment) in let (range, image) = attachment if curLocation < range.location { - let textRange = NSMakeRange(curLocation, range.location) + let textRange = NSRange(location: curLocation, length: range.location) let text = attributedText.attributedSubstring(from: textRange).string.trimmingCharacters(in: .whitespacesAndNewlines) if !text.isEmpty { components.append(text) } } - + curLocation = range.location + range.length components.append(image) } - if curLocation < length - 1 { - let text = attributedText.attributedSubstring(from: NSMakeRange(curLocation, length - curLocation)).string.trimmingCharacters(in: .whitespacesAndNewlines) + if curLocation < length - 1 { + let text = attributedText.attributedSubstring(from: NSRange(location: curLocation, length: length - curLocation)).string.trimmingCharacters(in: .whitespacesAndNewlines) if !text.isEmpty { components.append(text) } } } - + return components } - + /// Redraws the NSTextAttachments in the NSTextContainer to fit the current bounds @objc private func redrawTextAttachments() { - + guard images.count > 0 else { return } let range = NSRange(location: 0, length: attributedText.length) attributedText.enumerateAttribute(.attachment, in: range, options: [], using: { value, _, _ -> Void in if let attachment = value as? NSTextAttachment, let image = attachment.image { - + // Calculates a new width/height ratio to fit the image in the current frame let newWidth = frame.width - 2 * (textContainerInset.left + textContainerInset.right) let ratio = image.size.height / image.size.width @@ -385,5 +383,5 @@ open class InputTextView: UITextView { }) layoutManager.invalidateLayout(forCharacterRange: range, actualCharacterRange: nil) } - + } diff --git a/Pods/MessageInputBar/Sources/Views/SeparatorLine.swift b/Pods/MessageInputBar/Sources/Views/SeparatorLine.swift index 8af3abe..1fb1489 100644 --- a/Pods/MessageInputBar/Sources/Views/SeparatorLine.swift +++ b/Pods/MessageInputBar/Sources/Views/SeparatorLine.swift @@ -33,9 +33,9 @@ import UIKit 3. Intended to be used in an `InputStackView` */ open class SeparatorLine: UIView { - + // MARK: - Properties - + /// The height of the line open var height: CGFloat = 1.0 { didSet { @@ -43,23 +43,23 @@ open class SeparatorLine: UIView { invalidateIntrinsicContentSize() } } - + open override var intrinsicContentSize: CGSize { return CGSize(width: super.intrinsicContentSize.width, height: height) } - + // MARK: - Initialization - + public override init(frame: CGRect) { super.init(frame: frame) setup() } - + required public init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) setup() } - + /// Sets up the default properties open func setup() { backgroundColor = .lightGray diff --git a/Pods/MessageKit/Sources/Controllers/MessagesViewController+Keyboard.swift b/Pods/MessageKit/Sources/Controllers/MessagesViewController+Keyboard.swift index 881b6aa..1222d77 100644 --- a/Pods/MessageKit/Sources/Controllers/MessagesViewController+Keyboard.swift +++ b/Pods/MessageKit/Sources/Controllers/MessagesViewController+Keyboard.swift @@ -62,7 +62,7 @@ extension MessagesViewController { // ignore this notification. return } - + // Note that the check above does not exclude all notifications from an undocked keyboard, only the weird ones. // // We've tried following Apple's recommended approach of tracking UIKeyboardWillShow / UIKeyboardDidHide and ignoring frame @@ -77,18 +77,18 @@ extension MessagesViewController { // We could make it work by adding extra checks for the state of the keyboard and compensating accordingly, but it seems easier // to simply check whether the current keyboard frame, whatever it is (even when undocked), covers the bottom of the collection // view. - + guard let keyboardEndFrameInScreenCoords = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return } let keyboardEndFrame = view.convert(keyboardEndFrameInScreenCoords, from: view.window) - + let newBottomInset = requiredScrollViewBottomInset(forKeyboardFrame: keyboardEndFrame) let differenceOfBottomInset = newBottomInset - messageCollectionViewBottomInset - + if maintainPositionOnKeyboardFrameChanged && differenceOfBottomInset != 0 { let contentOffset = CGPoint(x: messagesCollectionView.contentOffset.x, y: messagesCollectionView.contentOffset.y + differenceOfBottomInset) messagesCollectionView.setContentOffset(contentOffset, animated: false) } - + messageCollectionViewBottomInset = newBottomInset } @@ -111,7 +111,7 @@ extension MessagesViewController { // we only need to adjust for the part of the keyboard that covers (i.e. intersects) our collection view; // see https://developer.apple.com/videos/play/wwdc2017/242/ for more details let intersection = messagesCollectionView.frame.intersection(keyboardFrame) - + if intersection.isNull || intersection.maxY < messagesCollectionView.frame.maxY { // The keyboard is hidden, is a hardware one, or is undocked and does not cover the bottom of the collection view. // Note: intersection.maxY may be less than messagesCollectionView.frame.maxY when dealing with undocked keyboards. diff --git a/Pods/MessageKit/Sources/Controllers/MessagesViewController.swift b/Pods/MessageKit/Sources/Controllers/MessagesViewController.swift index ff43ffe..f707a50 100644 --- a/Pods/MessageKit/Sources/Controllers/MessagesViewController.swift +++ b/Pods/MessageKit/Sources/Controllers/MessagesViewController.swift @@ -41,7 +41,7 @@ UICollectionViewDelegateFlowLayout, UICollectionViewDataSource { /// /// The default value of this property is `false`. open var scrollsToBottomOnKeyboardBeginsEditing: Bool = false - + /// A Boolean value that determines whether the `MessagesCollectionView` /// maintains it's current position when the height of the `MessageInputBar` changes. /// @@ -72,7 +72,7 @@ UICollectionViewDelegateFlowLayout, UICollectionViewDataSource { } private var isFirstLayout: Bool = true - + internal var isMessagesControllerBeingDismissed: Bool = false internal var selectedIndexPathForMenu: IndexPath? @@ -95,22 +95,22 @@ UICollectionViewDelegateFlowLayout, UICollectionViewDataSource { addMenuControllerObservers() addObservers() } - + open override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) isMessagesControllerBeingDismissed = false } - + open override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) isMessagesControllerBeingDismissed = true } - + open override func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(animated) isMessagesControllerBeingDismissed = false } - + open override func viewDidLayoutSubviews() { // Hack to prevent animation of the contentInset after viewDidAppear if isFirstLayout { @@ -151,7 +151,7 @@ UICollectionViewDelegateFlowLayout, UICollectionViewDataSource { private func setupConstraints() { messagesCollectionView.translatesAutoresizingMaskIntoConstraints = false - + let top = messagesCollectionView.topAnchor.constraint(equalTo: view.topAnchor, constant: topLayoutGuide.length) let bottom = messagesCollectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor) if #available(iOS 11.0, *) { @@ -298,16 +298,16 @@ UICollectionViewDelegateFlowLayout, UICollectionViewDataSource { } // MARK: - Helpers - + private func addObservers() { NotificationCenter.default.addObserver( self, selector: #selector(clearMemoryCache), name: UIApplication.didReceiveMemoryWarningNotification, object: nil) } - + private func removeObservers() { NotificationCenter.default.removeObserver(self, name: UIApplication.didReceiveMemoryWarningNotification, object: nil) } - + @objc private func clearMemoryCache() { MessageStyle.bubbleImageCache.removeAllObjects() } diff --git a/Pods/MessageKit/Sources/Extensions/Bundle+Extensions.swift b/Pods/MessageKit/Sources/Extensions/Bundle+Extensions.swift index 0cda64b..9ebb7fc 100644 --- a/Pods/MessageKit/Sources/Extensions/Bundle+Extensions.swift +++ b/Pods/MessageKit/Sources/Extensions/Bundle+Extensions.swift @@ -28,15 +28,15 @@ extension Bundle { internal static func messageKitAssetBundle() -> Bundle { let podBundle = Bundle(for: MessagesViewController.self) - + guard let resourceBundleUrl = podBundle.url(forResource: "MessageKitAssets", withExtension: "bundle") else { fatalError(MessageKitError.couldNotCreateAssetsPath) } - + guard let resourceBundle = Bundle(url: resourceBundleUrl) else { fatalError(MessageKitError.couldNotLoadAssetsBundle) } - + return resourceBundle } diff --git a/Pods/MessageKit/Sources/Extensions/CGRect+Extensions.swift b/Pods/MessageKit/Sources/Extensions/CGRect+Extensions.swift index 1a1177b..dcaf0f1 100644 --- a/Pods/MessageKit/Sources/Extensions/CGRect+Extensions.swift +++ b/Pods/MessageKit/Sources/Extensions/CGRect+Extensions.swift @@ -25,7 +25,7 @@ import Foundation extension CGRect { - + internal init(_ x: CGFloat, _ y: CGFloat, _ w: CGFloat, _ h: CGFloat) { self.init(x: x, y: y, width: w, height: h) } diff --git a/Pods/MessageKit/Sources/Extensions/NSAttributedString+Extensions.swift b/Pods/MessageKit/Sources/Extensions/NSAttributedString+Extensions.swift index a6a8f74..94a89aa 100644 --- a/Pods/MessageKit/Sources/Extensions/NSAttributedString+Extensions.swift +++ b/Pods/MessageKit/Sources/Extensions/NSAttributedString+Extensions.swift @@ -31,6 +31,6 @@ extension NSAttributedString { let constraintBox = CGSize(width: .greatestFiniteMagnitude, height: height) let rect = self.boundingRect(with: constraintBox, options: [.usesLineFragmentOrigin, .usesFontLeading], context: nil) return rect.width - + } } diff --git a/Pods/MessageKit/Sources/Extensions/UIView+Extensions.swift b/Pods/MessageKit/Sources/Extensions/UIView+Extensions.swift index b38d39a..bbb0886 100644 --- a/Pods/MessageKit/Sources/Extensions/UIView+Extensions.swift +++ b/Pods/MessageKit/Sources/Extensions/UIView+Extensions.swift @@ -25,7 +25,7 @@ import UIKit extension UIView { - + internal func fillSuperview() { guard let superview = self.superview else { return @@ -52,7 +52,7 @@ extension UIView { ] NSLayoutConstraint.activate(constraints) } - + internal func constraint(equalTo size: CGSize) { guard superview != nil else { return } translatesAutoresizingMaskIntoConstraints = false @@ -61,55 +61,55 @@ extension UIView { heightAnchor.constraint(equalToConstant: size.height) ] NSLayoutConstraint.activate(constraints) - + } @discardableResult internal func addConstraints(_ top: NSLayoutYAxisAnchor? = nil, left: NSLayoutXAxisAnchor? = nil, bottom: NSLayoutYAxisAnchor? = nil, right: NSLayoutXAxisAnchor? = nil, topConstant: CGFloat = 0, leftConstant: CGFloat = 0, bottomConstant: CGFloat = 0, rightConstant: CGFloat = 0, widthConstant: CGFloat = 0, heightConstant: CGFloat = 0) -> [NSLayoutConstraint] { - + if self.superview == nil { return [] } translatesAutoresizingMaskIntoConstraints = false - + var constraints = [NSLayoutConstraint]() - + if let top = top { let constraint = topAnchor.constraint(equalTo: top, constant: topConstant) constraint.identifier = "top" constraints.append(constraint) } - + if let left = left { let constraint = leftAnchor.constraint(equalTo: left, constant: leftConstant) constraint.identifier = "left" constraints.append(constraint) } - + if let bottom = bottom { let constraint = bottomAnchor.constraint(equalTo: bottom, constant: -bottomConstant) constraint.identifier = "bottom" constraints.append(constraint) } - + if let right = right { let constraint = rightAnchor.constraint(equalTo: right, constant: -rightConstant) constraint.identifier = "right" constraints.append(constraint) } - + if widthConstant > 0 { let constraint = widthAnchor.constraint(equalToConstant: widthConstant) constraint.identifier = "width" constraints.append(constraint) } - + if heightConstant > 0 { let constraint = heightAnchor.constraint(equalToConstant: heightConstant) constraint.identifier = "height" constraints.append(constraint) } - + NSLayoutConstraint.activate(constraints) return constraints } diff --git a/Pods/MessageKit/Sources/Layout/CellSizeCalculator.swift b/Pods/MessageKit/Sources/Layout/CellSizeCalculator.swift index 7037b57..58cae13 100644 --- a/Pods/MessageKit/Sources/Layout/CellSizeCalculator.swift +++ b/Pods/MessageKit/Sources/Layout/CellSizeCalculator.swift @@ -44,7 +44,7 @@ open class CellSizeCalculator { /// - indexPath: The `IndexPath` of the item to be displayed. /// The default return .zero open func sizeForItem(at indexPath: IndexPath) -> CGSize { return .zero } - + public init() {} } diff --git a/Pods/MessageKit/Sources/Layout/MessageSizeCalculator.swift b/Pods/MessageKit/Sources/Layout/MessageSizeCalculator.swift index f83f826..9c79c55 100644 --- a/Pods/MessageKit/Sources/Layout/MessageSizeCalculator.swift +++ b/Pods/MessageKit/Sources/Layout/MessageSizeCalculator.swift @@ -28,7 +28,7 @@ open class MessageSizeCalculator: CellSizeCalculator { public init(layout: MessagesCollectionViewFlowLayout? = nil) { super.init() - + self.layout = layout } @@ -166,16 +166,16 @@ open class MessageSizeCalculator: CellSizeCalculator { let isFromCurrentSender = dataSource.isFromCurrentSender(message: message) return isFromCurrentSender ? outgoingCellTopLabelAlignment : incomingCellTopLabelAlignment } - + // MARK: - Top message Label - + open func messageTopLabelSize(for message: MessageType, at indexPath: IndexPath) -> CGSize { let layoutDelegate = messagesLayout.messagesLayoutDelegate let collectionView = messagesLayout.messagesCollectionView let height = layoutDelegate.messageTopLabelHeight(for: message, at: indexPath, in: collectionView) return CGSize(width: messagesLayout.itemWidth, height: height) } - + open func messageTopLabelAlignment(for message: MessageType) -> LabelAlignment { let dataSource = messagesLayout.messagesDataSource let isFromCurrentSender = dataSource.isFromCurrentSender(message: message) diff --git a/Pods/MessageKit/Sources/Layout/MessagesCollectionViewFlowLayout.swift b/Pods/MessageKit/Sources/Layout/MessagesCollectionViewFlowLayout.swift index cd5fe5a..edff623 100644 --- a/Pods/MessageKit/Sources/Layout/MessagesCollectionViewFlowLayout.swift +++ b/Pods/MessageKit/Sources/Layout/MessagesCollectionViewFlowLayout.swift @@ -32,7 +32,7 @@ open class MessagesCollectionViewFlowLayout: UICollectionViewFlowLayout { open override class var layoutAttributesClass: AnyClass { return MessagesCollectionViewLayoutAttributes.self } - + /// The `MessagesCollectionView` that owns this layout object. public var messagesCollectionView: MessagesCollectionView { guard let messagesCollectionView = collectionView as? MessagesCollectionView else { @@ -40,7 +40,7 @@ open class MessagesCollectionViewFlowLayout: UICollectionViewFlowLayout { } return messagesCollectionView } - + /// The `MessagesDataSource` for the layout's collection view. public var messagesDataSource: MessagesDataSource { guard let messagesDataSource = messagesCollectionView.messagesDataSource else { @@ -48,7 +48,7 @@ open class MessagesCollectionViewFlowLayout: UICollectionViewFlowLayout { } return messagesDataSource } - + /// The `MessagesLayoutDelegate` for the layout's collection view. public var messagesLayoutDelegate: MessagesLayoutDelegate { guard let messagesLayoutDelegate = messagesCollectionView.messagesLayoutDelegate else { @@ -66,14 +66,14 @@ open class MessagesCollectionViewFlowLayout: UICollectionViewFlowLayout { public override init() { super.init() - + setupView() setupObserver() } required public init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) - + setupView() setupObserver() } @@ -81,13 +81,13 @@ open class MessagesCollectionViewFlowLayout: UICollectionViewFlowLayout { deinit { NotificationCenter.default.removeObserver(self) } - + // MARK: - Methods - + private func setupView() { sectionInset = UIEdgeInsets(top: 4, left: 8, bottom: 4, right: 8) } - + private func setupObserver() { NotificationCenter.default.addObserver(self, selector: #selector(MessagesCollectionViewFlowLayout.handleOrientationChange(_:)), name: UIDevice.orientationDidChangeNotification, object: nil) } @@ -173,62 +173,62 @@ open class MessagesCollectionViewFlowLayout: UICollectionViewFlowLayout { let calculator = cellSizeCalculatorForItem(at: indexPath) return calculator.sizeForItem(at: indexPath) } - + /// Set `incomingAvatarSize` of all `MessageSizeCalculator`s public func setMessageIncomingAvatarSize(_ newSize: CGSize) { messageSizeCalculators().forEach { $0.incomingAvatarSize = newSize } } - + /// Set `outgoingAvatarSize` of all `MessageSizeCalculator`s public func setMessageOutgoingAvatarSize(_ newSize: CGSize) { messageSizeCalculators().forEach { $0.outgoingAvatarSize = newSize } } - + /// Set `incomingAvatarPosition` of all `MessageSizeCalculator`s public func setMessageIncomingAvatarPosition(_ newPosition: AvatarPosition) { messageSizeCalculators().forEach { $0.incomingAvatarPosition = newPosition } } - + /// Set `outgoingAvatarPosition` of all `MessageSizeCalculator`s public func setMessageOutgoingAvatarPosition(_ newPosition: AvatarPosition) { messageSizeCalculators().forEach { $0.outgoingAvatarPosition = newPosition } } - + /// Set `incomingMessagePadding` of all `MessageSizeCalculator`s public func setMessageIncomingMessagePadding(_ newPadding: UIEdgeInsets) { messageSizeCalculators().forEach { $0.incomingMessagePadding = newPadding } } - + /// Set `outgoingMessagePadding` of all `MessageSizeCalculator`s public func setMessageOutgoingMessagePadding(_ newPadding: UIEdgeInsets) { messageSizeCalculators().forEach { $0.outgoingMessagePadding = newPadding } } - + /// Set `incomingCellTopLabelAlignment` of all `MessageSizeCalculator`s public func setMessageIncomingCellTopLabelAlignment(_ newAlignment: LabelAlignment) { messageSizeCalculators().forEach { $0.incomingCellTopLabelAlignment = newAlignment } } - + /// Set `outgoingCellTopLabelAlignment` of all `MessageSizeCalculator`s public func setMessageOutgoingCellTopLabelAlignment(_ newAlignment: LabelAlignment) { messageSizeCalculators().forEach { $0.outgoingCellTopLabelAlignment = newAlignment } } - + /// Set `incomingMessageTopLabelAlignment` of all `MessageSizeCalculator`s public func setMessageIncomingMessageTopLabelAlignment(_ newAlignment: LabelAlignment) { messageSizeCalculators().forEach { $0.incomingMessageTopLabelAlignment = newAlignment } } - + /// Set `outgoingMessageTopLabelAlignment` of all `MessageSizeCalculator`s public func setMessageOutgoingMessageTopLabelAlignment(_ newAlignment: LabelAlignment) { messageSizeCalculators().forEach { $0.outgoingMessageTopLabelAlignment = newAlignment } } - + /// Set `incomingMessageBottomLabelAlignment` of all `MessageSizeCalculator`s public func setMessageIncomingMessageBottomLabelAlignment(_ newAlignment: LabelAlignment) { messageSizeCalculators().forEach { $0.incomingMessageBottomLabelAlignment = newAlignment } } - + /// Set `outgoingMessageBottomLabelAlignment` of all `MessageSizeCalculator`s public func setMessageOutgoingMessageBottomLabelAlignment(_ newAlignment: LabelAlignment) { messageSizeCalculators().forEach { $0.outgoingMessageBottomLabelAlignment = newAlignment } @@ -258,5 +258,5 @@ open class MessagesCollectionViewFlowLayout: UICollectionViewFlowLayout { open func messageSizeCalculators() -> [MessageSizeCalculator] { return [textMessageSizeCalculator, attributedTextMessageSizeCalculator, emojiMessageSizeCalculator, photoMessageSizeCalculator, videoMessageSizeCalculator, locationMessageSizeCalculator] } - + } diff --git a/Pods/MessageKit/Sources/Layout/MessagesCollectionViewLayoutAttributes.swift b/Pods/MessageKit/Sources/Layout/MessagesCollectionViewLayoutAttributes.swift index e055ac5..6ea1117 100644 --- a/Pods/MessageKit/Sources/Layout/MessagesCollectionViewLayoutAttributes.swift +++ b/Pods/MessageKit/Sources/Layout/MessagesCollectionViewLayoutAttributes.swift @@ -39,7 +39,7 @@ open class MessagesCollectionViewLayoutAttributes: UICollectionViewLayoutAttribu public var cellTopLabelAlignment = LabelAlignment(textAlignment: .center, textInsets: .zero) public var cellTopLabelSize: CGSize = .zero - + public var messageTopLabelAlignment = LabelAlignment(textAlignment: .center, textInsets: .zero) public var messageTopLabelSize: CGSize = .zero diff --git a/Pods/MessageKit/Sources/Models/Avatar.swift b/Pods/MessageKit/Sources/Models/Avatar.swift index 29fa169..f82cd57 100644 --- a/Pods/MessageKit/Sources/Models/Avatar.swift +++ b/Pods/MessageKit/Sources/Models/Avatar.swift @@ -26,22 +26,22 @@ import Foundation /// An object used to group the information to be used by an `AvatarView`. public struct Avatar { - + // MARK: - Properties - + /// The image to be used for an `AvatarView`. public let image: UIImage? - + /// The placeholder initials to be used in the case where no image is provided. /// /// The default value of this property is "?". public var initials: String = "?" - + // MARK: - Initializer - + public init(image: UIImage? = nil, initials: String = "?") { self.image = image self.initials = initials } - + } diff --git a/Pods/MessageKit/Sources/Models/AvatarPosition.swift b/Pods/MessageKit/Sources/Models/AvatarPosition.swift index e887e78..a20ae14 100644 --- a/Pods/MessageKit/Sources/Models/AvatarPosition.swift +++ b/Pods/MessageKit/Sources/Models/AvatarPosition.swift @@ -27,55 +27,55 @@ import Foundation /// Used to determine the `Horizontal` and `Vertical` position of // an `AvatarView` in a `MessageCollectionViewCell`. public struct AvatarPosition { - + /// An enum representing the horizontal alignment of an `AvatarView`. public enum Horizontal { - + /// Positions the `AvatarView` on the side closest to the cell's leading edge. case cellLeading - + /// Positions the `AvatarView` on the side closest to the cell's trailing edge. case cellTrailing - + /// Positions the `AvatarView` based on whether the message is from the current Sender. /// The cell is positioned `.cellTrailling` if `isFromCurrentSender` is true /// and `.cellLeading` if false. case natural } - + /// An enum representing the verical alignment for an `AvatarView`. public enum Vertical { - + /// Aligns the `AvatarView`'s top edge to the cell's top edge. case cellTop - + /// Aligns the `AvatarView`'s top edge to the `messageTopLabel`'s top edge. case messageLabelTop - + /// Aligns the `AvatarView`'s top edge to the `MessageContainerView`'s top edge. case messageTop - + /// Aligns the `AvatarView` center to the `MessageContainerView` center. case messageCenter - + /// Aligns the `AvatarView`'s bottom edge to the `MessageContainerView`s bottom edge. case messageBottom - + /// Aligns the `AvatarView`'s bottom edge to the cell's bottom edge. case cellBottom - + } - + // MARK: - Properties - + // The vertical position public var vertical: Vertical - + // The horizontal position public var horizontal: Horizontal - + // MARK: - Initializers - + public init(horizontal: Horizontal, vertical: Vertical) { self.horizontal = horizontal self.vertical = vertical @@ -84,7 +84,7 @@ public struct AvatarPosition { public init(vertical: Vertical) { self.init(horizontal: .natural, vertical: vertical) } - + } // MARK: - Equatable Conformance diff --git a/Pods/MessageKit/Sources/Models/LabelAlignment.swift b/Pods/MessageKit/Sources/Models/LabelAlignment.swift index 320971f..92b8e35 100644 --- a/Pods/MessageKit/Sources/Models/LabelAlignment.swift +++ b/Pods/MessageKit/Sources/Models/LabelAlignment.swift @@ -28,7 +28,7 @@ public struct LabelAlignment { public var textAlignment: NSTextAlignment public var textInsets: UIEdgeInsets - + public init(textAlignment: NSTextAlignment, textInsets: UIEdgeInsets) { self.textAlignment = textAlignment self.textInsets = textInsets diff --git a/Pods/MessageKit/Sources/Models/LocationMessageSnapshotOptions.swift b/Pods/MessageKit/Sources/Models/LocationMessageSnapshotOptions.swift index 21628fc..59df612 100644 --- a/Pods/MessageKit/Sources/Models/LocationMessageSnapshotOptions.swift +++ b/Pods/MessageKit/Sources/Models/LocationMessageSnapshotOptions.swift @@ -40,25 +40,25 @@ public struct LocationMessageSnapshotOptions { self.span = span self.scale = scale } - + /// A Boolean value indicating whether the snapshot image should display buildings. /// /// The default value of this property is `false`. public var showsBuildings: Bool - + /// A Boolean value indicating whether the snapshot image should display points of interest. /// /// The default value of this property is `false`. public var showsPointsOfInterest: Bool - + /// The span of the snapshot. /// /// The default value of this property uses a width of `0` and height of `0`. public var span: MKCoordinateSpan - + /// The scale of the snapshot. /// /// The default value of this property uses the `UIScreen.main.scale`. public var scale: CGFloat - + } diff --git a/Pods/MessageKit/Sources/Models/MessageKind.swift b/Pods/MessageKit/Sources/Models/MessageKind.swift index a29d76d..9769dde 100644 --- a/Pods/MessageKit/Sources/Models/MessageKind.swift +++ b/Pods/MessageKit/Sources/Models/MessageKind.swift @@ -35,7 +35,7 @@ public enum MessageKind { /// Using `MessageKind.attributedText(NSAttributedString)` doesn't require you /// to set this property and results in higher performance. case text(String) - + /// A message with attributed text. case attributedText(NSAttributedString) diff --git a/Pods/MessageKit/Sources/Models/MessageKitDateFormatter.swift b/Pods/MessageKit/Sources/Models/MessageKitDateFormatter.swift index c0d02bc..f924073 100644 --- a/Pods/MessageKit/Sources/Models/MessageKitDateFormatter.swift +++ b/Pods/MessageKit/Sources/Models/MessageKitDateFormatter.swift @@ -62,5 +62,5 @@ open class MessageKitDateFormatter { formatter.dateFormat = "MMM d, yyyy, h:mm a" } } - + } diff --git a/Pods/MessageKit/Sources/Models/MessageStyle.swift b/Pods/MessageKit/Sources/Models/MessageStyle.swift index f8abd50..bd8bd1c 100644 --- a/Pods/MessageKit/Sources/Models/MessageStyle.swift +++ b/Pods/MessageKit/Sources/Models/MessageStyle.swift @@ -74,7 +74,7 @@ public enum MessageStyle { // MARK: - Public public var image: UIImage? { - + guard let imageCacheKey = imageCacheKey, let path = imagePath else { return nil } let cache = MessageStyle.bubbleImageCache @@ -83,7 +83,7 @@ public enum MessageStyle { return cachedImage } guard var image = UIImage(contentsOfFile: path) else { return nil } - + switch self { case .none, .custom: return nil @@ -93,25 +93,25 @@ public enum MessageStyle { guard let cgImage = image.cgImage else { return nil } image = UIImage(cgImage: cgImage, scale: image.scale, orientation: corner.imageOrientation) } - + let stretchedImage = stretch(image) cache.setObject(stretchedImage, forKey: imageCacheKey as NSString) return stretchedImage } // MARK: - Internal - + internal static let bubbleImageCache: NSCache = { let cache = NSCache() cache.name = "com.messagekit.MessageKit.bubbleImageCache" return cache }() - + // MARK: - Private - + private var imageCacheKey: String? { guard let imageName = imageName else { return nil } - + switch self { case .bubble, .bubbleOutline: return imageName diff --git a/Pods/MessageKit/Sources/Models/NSConstraintLayoutSet.swift b/Pods/MessageKit/Sources/Models/NSConstraintLayoutSet.swift index cd063df..0bc4cf8 100644 --- a/Pods/MessageKit/Sources/Models/NSConstraintLayoutSet.swift +++ b/Pods/MessageKit/Sources/Models/NSConstraintLayoutSet.swift @@ -25,7 +25,7 @@ import UIKit internal class NSLayoutConstraintSet { - + internal var top: NSLayoutConstraint? internal var bottom: NSLayoutConstraint? internal var left: NSLayoutConstraint? @@ -34,7 +34,7 @@ internal class NSLayoutConstraintSet { internal var centerY: NSLayoutConstraint? internal var width: NSLayoutConstraint? internal var height: NSLayoutConstraint? - + internal init(top: NSLayoutConstraint? = nil, bottom: NSLayoutConstraint? = nil, left: NSLayoutConstraint? = nil, right: NSLayoutConstraint? = nil, centerX: NSLayoutConstraint? = nil, centerY: NSLayoutConstraint? = nil, @@ -60,7 +60,7 @@ internal class NSLayoutConstraintSet { } return available } - + /// Activates all of the non-nil constraints /// /// - Returns: Self @@ -69,7 +69,7 @@ internal class NSLayoutConstraintSet { NSLayoutConstraint.activate(availableConstraints) return self } - + /// Deactivates all of the non-nil constraints /// /// - Returns: Self diff --git a/Pods/MessageKit/Sources/Protocols/MessageCellDelegate.swift b/Pods/MessageKit/Sources/Protocols/MessageCellDelegate.swift index 4fbe9da..7122937 100644 --- a/Pods/MessageKit/Sources/Protocols/MessageCellDelegate.swift +++ b/Pods/MessageKit/Sources/Protocols/MessageCellDelegate.swift @@ -57,7 +57,7 @@ public protocol MessageCellDelegate: MessageLabelDelegate { /// `indexPath(for: cell)` method. Then using the returned `IndexPath` with the `MessagesDataSource` /// method `messageForItem(at:indexPath:messagesCollectionView)`. func didTapCellTopLabel(in cell: MessageCollectionViewCell) - + /// Triggered when a tap occurs in the messageTopLabel. /// /// - Parameters: @@ -77,7 +77,7 @@ public protocol MessageCellDelegate: MessageLabelDelegate { /// `indexPath(for: cell)` method. Then using the returned `IndexPath` with the `MessagesDataSource` /// method `messageForItem(at:indexPath:messagesCollectionView)`. func didTapMessageBottomLabel(in cell: MessageCollectionViewCell) - + /// Triggered when a tap occurs in the accessoryView. /// /// - Parameters: @@ -101,6 +101,6 @@ public extension MessageCellDelegate { func didTapMessageTopLabel(in cell: MessageCollectionViewCell) {} func didTapMessageBottomLabel(in cell: MessageCollectionViewCell) {} - + func didTapAccessoryView(in cell: MessageCollectionViewCell) {} } diff --git a/Pods/MessageKit/Sources/Protocols/MessageLabelDelegate.swift b/Pods/MessageKit/Sources/Protocols/MessageLabelDelegate.swift index e84ea62..ecfa6fe 100644 --- a/Pods/MessageKit/Sources/Protocols/MessageLabelDelegate.swift +++ b/Pods/MessageKit/Sources/Protocols/MessageLabelDelegate.swift @@ -68,7 +68,7 @@ public extension MessageLabelDelegate { func didSelectPhoneNumber(_ phoneNumber: String) {} func didSelectURL(_ url: URL) {} - + func didSelectTransitInformation(_ transitInformation: [String: String]) {} } diff --git a/Pods/MessageKit/Sources/Protocols/MessagesDataSource.swift b/Pods/MessageKit/Sources/Protocols/MessagesDataSource.swift index 3caba08..d805996 100644 --- a/Pods/MessageKit/Sources/Protocols/MessagesDataSource.swift +++ b/Pods/MessageKit/Sources/Protocols/MessagesDataSource.swift @@ -72,7 +72,7 @@ public protocol MessagesDataSource: AnyObject { /// /// The default value returned by this method is `nil`. func cellTopLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString? - + /// The attributed text to be used for message bubble's top label. /// /// - Parameters: @@ -92,7 +92,7 @@ public protocol MessagesDataSource: AnyObject { /// /// The default value returned by this method is `nil`. func messageBottomLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString? - + /// Custom collectionView cell for message with `custom` message type. /// /// - Parameters: @@ -118,7 +118,7 @@ public extension MessagesDataSource { func cellTopLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString? { return nil } - + func messageTopLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString? { return nil } @@ -126,7 +126,7 @@ public extension MessagesDataSource { func messageBottomLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString? { return nil } - + func customCell(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> UICollectionViewCell { fatalError(MessageKitError.customDataUnresolvedCell) } diff --git a/Pods/MessageKit/Sources/Protocols/MessagesDisplayDelegate.swift b/Pods/MessageKit/Sources/Protocols/MessagesDisplayDelegate.swift index 2af2eac..1cdaafe 100644 --- a/Pods/MessageKit/Sources/Protocols/MessagesDisplayDelegate.swift +++ b/Pods/MessageKit/Sources/Protocols/MessagesDisplayDelegate.swift @@ -71,7 +71,7 @@ public protocol MessagesDisplayDelegate: AnyObject { /// - indexPath: The `IndexPath` of the footer. /// - messagesCollectionView: The `MessagesCollectionView` in which this footer will be displayed. func messageFooterView(for indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> MessageReusableView - + /// Used to configure the `AvatarView`‘s image in a `MessageContentCell` class. /// /// - Parameters: @@ -193,7 +193,7 @@ public extension MessagesDisplayDelegate { return dataSource.isFromCurrentSender(message: message) ? .outgoingGreen : .incomingGray } } - + func messageHeaderView(for indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> MessageReusableView { return messagesCollectionView.dequeueReusableHeaderView(MessageReusableView.self, for: indexPath) } @@ -201,7 +201,7 @@ public extension MessagesDisplayDelegate { func messageFooterView(for indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> MessageReusableView { return messagesCollectionView.dequeueReusableFooterView(MessageReusableView.self, for: indexPath) } - + func configureAvatarView(_ avatarView: AvatarView, for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) { avatarView.initials = "?" } diff --git a/Pods/MessageKit/Sources/Protocols/MessagesLayoutDelegate.swift b/Pods/MessageKit/Sources/Protocols/MessagesLayoutDelegate.swift index 4dd7574..0e96253 100644 --- a/Pods/MessageKit/Sources/Protocols/MessagesLayoutDelegate.swift +++ b/Pods/MessageKit/Sources/Protocols/MessagesLayoutDelegate.swift @@ -58,7 +58,7 @@ public protocol MessagesLayoutDelegate: AnyObject { /// - Note: /// The default value returned by this method is zero. func cellTopLabelHeight(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> CGFloat - + /// Specifies the height for the message bubble's top label. /// /// - Parameters: @@ -80,7 +80,7 @@ public protocol MessagesLayoutDelegate: AnyObject { /// - Note: /// The default value returned by this method is zero. func messageBottomLabelHeight(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> CGFloat - + /// Custom cell size calculator for messages with MessageType.custom. /// /// - Parameters: @@ -106,7 +106,7 @@ public extension MessagesLayoutDelegate { func cellTopLabelHeight(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> CGFloat { return 0 } - + func messageTopLabelHeight(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> CGFloat { return 0 } @@ -114,7 +114,7 @@ public extension MessagesLayoutDelegate { func messageBottomLabelHeight(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> CGFloat { return 0 } - + func customCellSizeCalculator(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> CellSizeCalculator { fatalError("Must return a CellSizeCalculator for MessageKind.custom(Any?)") } diff --git a/Pods/MessageKit/Sources/Views/AvatarView.swift b/Pods/MessageKit/Sources/Views/AvatarView.swift index cf3c145..267aec7 100644 --- a/Pods/MessageKit/Sources/Views/AvatarView.swift +++ b/Pods/MessageKit/Sources/Views/AvatarView.swift @@ -27,7 +27,7 @@ import Foundation open class AvatarView: UIImageView { // MARK: - Properties - + open var initials: String? { didSet { setImageFrom(initials: initials) @@ -74,7 +74,7 @@ open class AvatarView: UIImageView { super.init(frame: frame) prepareView() } - + required public init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) prepareView() @@ -84,7 +84,7 @@ open class AvatarView: UIImageView { self.init(frame: .zero) prepareView() } - + private func setImageFrom(initials: String?) { guard let initials = initials else { return } image = getImageFrom(initials: initials) @@ -169,7 +169,7 @@ open class AvatarView: UIImageView { } // MARK: - Open setters - + open func set(avatar: Avatar) { if let image = avatar.image { self.image = image diff --git a/Pods/MessageKit/Sources/Views/Cells/LocationMessageCell.swift b/Pods/MessageKit/Sources/Views/Cells/LocationMessageCell.swift index ed84ed7..cd99e70 100644 --- a/Pods/MessageKit/Sources/Views/Cells/LocationMessageCell.swift +++ b/Pods/MessageKit/Sources/Views/Cells/LocationMessageCell.swift @@ -33,7 +33,7 @@ open class LocationMessageCell: MessageContentCell { /// The image view holding the map image. open var imageView = UIImageView() - + private weak var snapShotter: MKMapSnapshotter? open override func setupSubviews() { @@ -49,7 +49,7 @@ open class LocationMessageCell: MessageContentCell { imageView.fillSuperview() activityIndicator.centerInSuperview() } - + open override func prepareForReuse() { super.prepareForReuse() snapShotter?.cancel() diff --git a/Pods/MessageKit/Sources/Views/Cells/MessageContentCell.swift b/Pods/MessageKit/Sources/Views/Cells/MessageContentCell.swift index 3a194a6..a3c21a5 100644 --- a/Pods/MessageKit/Sources/Views/Cells/MessageContentCell.swift +++ b/Pods/MessageKit/Sources/Views/Cells/MessageContentCell.swift @@ -45,7 +45,7 @@ open class MessageContentCell: MessageCollectionViewCell { label.textAlignment = .center return label }() - + /// The top label of the messageBubble. open var messageTopLabel: InsetLabel = { let label = InsetLabel() @@ -252,7 +252,7 @@ open class MessageContentCell: MessageCollectionViewCell { open func layoutCellTopLabel(with attributes: MessagesCollectionViewLayoutAttributes) { cellTopLabel.frame = CGRect(origin: .zero, size: attributes.cellTopLabelSize) } - + /// Positions the message bubble's top label. /// - attributes: The `MessagesCollectionViewLayoutAttributes` for the cell. open func layoutMessageTopLabel(with attributes: MessagesCollectionViewLayoutAttributes) { @@ -261,7 +261,7 @@ open class MessageContentCell: MessageCollectionViewCell { let y = messageContainerView.frame.minY - attributes.messageContainerPadding.top - attributes.messageTopLabelSize.height let origin = CGPoint(x: 0, y: y) - + messageTopLabel.frame = CGRect(origin: origin, size: attributes.messageTopLabelSize) } @@ -280,7 +280,7 @@ open class MessageContentCell: MessageCollectionViewCell { /// Positions the cell's accessory view. /// - attributes: The `MessagesCollectionViewLayoutAttributes` for the cell. open func layoutAccessoryView(with attributes: MessagesCollectionViewLayoutAttributes) { - + // Accessory view aligned to the middle of the messageContainerView let y = messageContainerView.frame.midY - (attributes.accessoryViewSize.height / 2) diff --git a/Pods/MessageKit/Sources/Views/Cells/TextMessageCell.swift b/Pods/MessageKit/Sources/Views/Cells/TextMessageCell.swift index 481411b..1586202 100644 --- a/Pods/MessageKit/Sources/Views/Cells/TextMessageCell.swift +++ b/Pods/MessageKit/Sources/Views/Cells/TextMessageCell.swift @@ -91,7 +91,7 @@ open class TextMessageCell: MessageContentCell { } } } - + /// Used to handle the cell's contentView's tap gesture. /// Return false when the contentView does not need to handle the gesture. open override func cellContentView(canHandle touchPoint: CGPoint) -> Bool { diff --git a/Pods/MessageKit/Sources/Views/MessageLabel.swift b/Pods/MessageKit/Sources/Views/MessageLabel.swift index d451d48..7c9cfcb 100644 --- a/Pods/MessageKit/Sources/Views/MessageLabel.swift +++ b/Pods/MessageKit/Sources/Views/MessageLabel.swift @@ -50,7 +50,7 @@ open class MessageLabel: UILabel { }() private lazy var rangesForDetectors: [DetectorType: [(NSRange, MessageTextCheckingType)]] = [:] - + private var isConfiguring: Bool = false // MARK: - Public Properties @@ -119,7 +119,7 @@ open class MessageLabel: UILabel { size.height += textInsets.vertical return size } - + internal var messageLabelFont: UIFont? private var attributesNeedUpdate = false @@ -139,7 +139,7 @@ open class MessageLabel: UILabel { open internal(set) var phoneNumberAttributes: [NSAttributedString.Key: Any] = defaultAttributes open internal(set) var urlAttributes: [NSAttributedString.Key: Any] = defaultAttributes - + open internal(set) var transitInformationAttributes: [NSAttributedString.Key: Any] = defaultAttributes public func setAttributes(_ attributes: [NSAttributedString.Key: Any], detector: DetectorType) { @@ -189,7 +189,7 @@ open class MessageLabel: UILabel { } // MARK: - Public Methods - + public func configure(block: () -> Void) { isConfiguring = true block() @@ -210,19 +210,19 @@ open class MessageLabel: UILabel { setNeedsDisplay() return } - + let style = paragraphStyle(for: newText) let range = NSRange(location: 0, length: newText.length) - + let mutableText = NSMutableAttributedString(attributedString: newText) mutableText.addAttribute(.paragraphStyle, value: style, range: range) - + if shouldParse { rangesForDetectors.removeAll() let results = parse(text: mutableText) setRangesForDetectors(in: results) } - + for (detector, rangeTuples) in rangesForDetectors { if enabledDetectors.contains(detector) { let attributes = detectorAttributes(for: detector) @@ -238,17 +238,17 @@ open class MessageLabel: UILabel { if !isConfiguring { setNeedsDisplay() } } - + private func paragraphStyle(for text: NSAttributedString) -> NSParagraphStyle { guard text.length > 0 else { return NSParagraphStyle() } - + var range = NSRange(location: 0, length: text.length) let existingStyle = text.attribute(.paragraphStyle, at: 0, effectiveRange: &range) as? NSMutableParagraphStyle let style = existingStyle ?? NSMutableParagraphStyle() - + style.lineBreakMode = lineBreakMode style.alignment = textAlignment - + return style } @@ -303,7 +303,7 @@ open class MessageLabel: UILabel { fatalError(MessageKitError.unrecognizedCheckingResult) } } - + private func setupView() { numberOfLines = 0 lineBreakMode = .byWordWrapping @@ -337,7 +337,7 @@ open class MessageLabel: UILabel { private func setRangesForDetectors(in checkingResults: [NSTextCheckingResult]) { guard checkingResults.isEmpty == false else { return } - + for result in checkingResults { switch result.resultType { @@ -388,13 +388,13 @@ open class MessageLabel: UILabel { let index = layoutManager.glyphIndex(for: location, in: textContainer) let lineRect = layoutManager.lineFragmentUsedRect(forGlyphAt: index, effectiveRange: nil) - + var characterIndex: Int? - + if lineRect.contains(location) { characterIndex = layoutManager.characterIndexForGlyph(at: index) } - + return characterIndex } @@ -415,7 +415,7 @@ open class MessageLabel: UILabel { } private func handleGesture(for detectorType: DetectorType, value: MessageTextCheckingType) { - + switch value { case let .addressComponents(addressComponents): var transformedAddressComponents = [String: String]() @@ -442,27 +442,27 @@ open class MessageLabel: UILabel { handleTransitInformation(transformedTransitInformation) } } - + private func handleAddress(_ addressComponents: [String: String]) { delegate?.didSelectAddress(addressComponents) } - + private func handleDate(_ date: Date) { delegate?.didSelectDate(date) } - + private func handleURL(_ url: URL) { delegate?.didSelectURL(url) } - + private func handlePhoneNumber(_ phoneNumber: String) { delegate?.didSelectPhoneNumber(phoneNumber) } - + private func handleTransitInformation(_ components: [String: String]) { delegate?.didSelectTransitInformation(components) } - + } private enum MessageTextCheckingType { diff --git a/Pods/MessageKit/Sources/Views/MessagesCollectionView.swift b/Pods/MessageKit/Sources/Views/MessagesCollectionView.swift index ee1e4cd..d0a8940 100644 --- a/Pods/MessageKit/Sources/Views/MessagesCollectionView.swift +++ b/Pods/MessageKit/Sources/Views/MessagesCollectionView.swift @@ -50,7 +50,7 @@ open class MessagesCollectionView: UICollectionView { registerReusableViews() setupGestureRecognizers() } - + required public init?(coder aDecoder: NSCoder) { super.init(frame: .zero, collectionViewLayout: MessagesCollectionViewFlowLayout()) } @@ -60,7 +60,7 @@ open class MessagesCollectionView: UICollectionView { } // MARK: - Methods - + private func registerReusableViews() { register(TextMessageCell.self) register(MediaMessageCell.self) @@ -68,20 +68,20 @@ open class MessagesCollectionView: UICollectionView { register(MessageReusableView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader) register(MessageReusableView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionFooter) } - + private func setupGestureRecognizers() { let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTapGesture(_:))) tapGesture.delaysTouchesBegan = true addGestureRecognizer(tapGesture) } - + @objc open func handleTapGesture(_ gesture: UIGestureRecognizer) { guard gesture.state == .ended else { return } - + let touchLocation = gesture.location(in: self) guard let indexPath = indexPathForItem(at: touchLocation) else { return } - + let cell = cellForItem(at: indexPath) as? MessageContentCell cell?.handleTapGesture(gesture) } @@ -93,17 +93,17 @@ open class MessagesCollectionView: UICollectionView { self.scrollRectToVisible(CGRect(0.0, collectionViewContentHeight - 1.0, 1.0, 1.0), animated: animated) } } - + public func reloadDataAndKeepOffset() { // stop scrolling setContentOffset(contentOffset, animated: false) - + // calculate the offset and reloadData let beforeContentSize = contentSize reloadData() layoutIfNeeded() let afterContentSize = contentSize - + // reset the contentOffset after data is updated let newOffset = CGPoint( x: contentOffset.x + (afterContentSize.width - beforeContentSize.width), @@ -122,12 +122,12 @@ open class MessagesCollectionView: UICollectionView { forSupplementaryViewOfKind: kind, withReuseIdentifier: String(describing: T.self)) } - + /// Registers a nib with reusable view for a specific SectionKind public func register(_ nib: UINib? = UINib(nibName: String(describing: T.self), bundle: nil), headerFooterClassOfNib headerFooterClass: T.Type, forSupplementaryViewOfKind kind: String) { register(nib, forSupplementaryViewOfKind: kind, - withReuseIdentifier: String(describing: T.self)) + withReuseIdentifier: String(describing: T.self)) } /// Generically dequeues a cell of the correct type allowing you to avoid scattering your code with guard-let-else-fatal diff --git a/Pods/MessageKit/Sources/Views/PlayButtonView.swift b/Pods/MessageKit/Sources/Views/PlayButtonView.swift index b446ccf..4517089 100644 --- a/Pods/MessageKit/Sources/Views/PlayButtonView.swift +++ b/Pods/MessageKit/Sources/Views/PlayButtonView.swift @@ -45,20 +45,20 @@ open class PlayButtonView: UIView { required public init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) - + setupSubviews() setupConstraints() setupView() } // MARK: - Methods - + open override func layoutSubviews() { super.layoutSubviews() - + guard !cacheFrame.equalTo(frame) else { return } cacheFrame = frame - + updateTriangleConstraints() applyCornerRadius() applyTriangleMask() @@ -67,11 +67,11 @@ open class PlayButtonView: UIView { private func setupSubviews() { addSubview(triangleView) } - + private func setupView() { triangleView.clipsToBounds = true triangleView.backgroundColor = .black - + backgroundColor = .playButtonLightGray } @@ -118,5 +118,5 @@ open class PlayButtonView: UIView { private func applyCornerRadius() { layer.cornerRadius = frame.width / 2 } - + }