You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

127 lines
6.0 KiB

  1. //
  2. // ImageDownloaderDelegate.swift
  3. // Kingfisher
  4. //
  5. // Created by Wei Wang on 2018/10/11.
  6. //
  7. // Copyright (c) 2019 Wei Wang <onevcat@gmail.com>
  8. //
  9. // Permission is hereby granted, free of charge, to any person obtaining a copy
  10. // of this software and associated documentation files (the "Software"), to deal
  11. // in the Software without restriction, including without limitation the rights
  12. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. // copies of the Software, and to permit persons to whom the Software is
  14. // furnished to do so, subject to the following conditions:
  15. //
  16. // The above copyright notice and this permission notice shall be included in
  17. // all copies or substantial portions of the Software.
  18. //
  19. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25. // THE SOFTWARE.
  26. import Foundation
  27. /// Protocol of `ImageDownloader`. This protocol provides a set of methods which are related to image downloader
  28. /// working stages and rules.
  29. public protocol ImageDownloaderDelegate: AnyObject {
  30. /// Called when the `ImageDownloader` object will start downloading an image from a specified URL.
  31. ///
  32. /// - Parameters:
  33. /// - downloader: The `ImageDownloader` object which is used for the downloading operation.
  34. /// - url: URL of the starting request.
  35. /// - request: The request object for the download process.
  36. ///
  37. func imageDownloader(_ downloader: ImageDownloader, willDownloadImageForURL url: URL, with request: URLRequest?)
  38. /// Called when the `ImageDownloader` completes a downloading request with success or failure.
  39. ///
  40. /// - Parameters:
  41. /// - downloader: The `ImageDownloader` object which is used for the downloading operation.
  42. /// - url: URL of the original request URL.
  43. /// - response: The response object of the downloading process.
  44. /// - error: The error in case of failure.
  45. ///
  46. func imageDownloader(
  47. _ downloader: ImageDownloader,
  48. didFinishDownloadingImageForURL url: URL,
  49. with response: URLResponse?,
  50. error: Error?)
  51. /// Called when the `ImageDownloader` object successfully downloaded image data from specified URL. This is
  52. /// your last chance to verify or modify the downloaded data before Kingfisher tries to perform addition
  53. /// processing on the image data.
  54. ///
  55. /// - Parameters:
  56. /// - downloader: The `ImageDownloader` object which is used for the downloading operation.
  57. /// - data: The original downloaded data.
  58. /// - url: The URL of the original request URL.
  59. /// - Returns: The data from which Kingfisher should use to create an image. You need to provide valid data
  60. /// which content is one of the supported image file format. Kingfisher will perform process on this
  61. /// data and try to convert it to an image object.
  62. /// - Note:
  63. /// This can be used to pre-process raw image data before creation of `Image` instance (i.e.
  64. /// decrypting or verification). If `nil` returned, the processing is interrupted and a `KingfisherError` with
  65. /// `ResponseErrorReason.dataModifyingFailed` will be raised. You could use this fact to stop the image
  66. /// processing flow if you find the data is corrupted or malformed.
  67. func imageDownloader(_ downloader: ImageDownloader, didDownload data: Data, for url: URL) -> Data?
  68. /// Called when the `ImageDownloader` object successfully downloads and processes an image from specified URL.
  69. ///
  70. /// - Parameters:
  71. /// - downloader: The `ImageDownloader` object which is used for the downloading operation.
  72. /// - image: The downloaded and processed image.
  73. /// - url: URL of the original request URL.
  74. /// - response: The original response object of the downloading process.
  75. ///
  76. func imageDownloader(
  77. _ downloader: ImageDownloader,
  78. didDownload image: KFCrossPlatformImage,
  79. for url: URL,
  80. with response: URLResponse?)
  81. /// Checks if a received HTTP status code is valid or not.
  82. /// By default, a status code in range 200..<400 is considered as valid.
  83. /// If an invalid code is received, the downloader will raise an `KingfisherError` with
  84. /// `ResponseErrorReason.invalidHTTPStatusCode` as its reason.
  85. ///
  86. /// - Parameters:
  87. /// - code: The received HTTP status code.
  88. /// - downloader: The `ImageDownloader` object asks for validate status code.
  89. /// - Returns: Returns a value to indicate whether this HTTP status code is valid or not.
  90. /// - Note: If the default 200 to 400 valid code does not suit your need,
  91. /// you can implement this method to change that behavior.
  92. func isValidStatusCode(_ code: Int, for downloader: ImageDownloader) -> Bool
  93. }
  94. // Default implementation for `ImageDownloaderDelegate`.
  95. extension ImageDownloaderDelegate {
  96. public func imageDownloader(
  97. _ downloader: ImageDownloader,
  98. willDownloadImageForURL url: URL,
  99. with request: URLRequest?) {}
  100. public func imageDownloader(
  101. _ downloader: ImageDownloader,
  102. didFinishDownloadingImageForURL url: URL,
  103. with response: URLResponse?,
  104. error: Error?) {}
  105. public func imageDownloader(
  106. _ downloader: ImageDownloader,
  107. didDownload image: KFCrossPlatformImage,
  108. for url: URL,
  109. with response: URLResponse?) {}
  110. public func isValidStatusCode(_ code: Int, for downloader: ImageDownloader) -> Bool {
  111. return (200..<400).contains(code)
  112. }
  113. public func imageDownloader(_ downloader: ImageDownloader, didDownload data: Data, for url: URL) -> Data? {
  114. return data
  115. }
  116. }