Skip to content

Instantly share code, notes, and snippets.

@drochetti
Last active November 23, 2020 23:44
Show Gist options
  • Save drochetti/23b18e5df0f9a1d2d7448a96f306bbcc to your computer and use it in GitHub Desktop.
Save drochetti/23b18e5df0f9a1d2d7448a96f306bbcc to your computer and use it in GitHub Desktop.
Amplify+Kingfisher
import Amplify
//import AmplifyExtensions
import struct Kingfisher.KFImage
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Button(action: onFileUpload) {
Text("Upload file")
}
Spacer()
KFImage(source: .amplify(key: "megadeth.jpeg"))
}.padding()
}
func onFileUpload() {
let filePath = Bundle.main.path(forResource: "megadeth", ofType: "jpeg")
let file = URL(fileURLWithPath: filePath!)
let start = DispatchTime.now()
_ = Amplify.Storage.uploadFile(key: "megadeth.jpeg", local: file) {
switch $0 {
case .success:
let elapsed = DispatchTime.now().uptimeNanoseconds - start.uptimeNanoseconds
print("-------------------")
print("Upload done. It took \(elapsed / 1_000_000) ms")
case .failure(let error):
print("-------------------")
print("Upload failed!")
print(error)
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
#if canImport(Amplify) && canImport(Kingfisher)
import Amplify
import Kingfisher
/// `ImageDataProvider` implementation that loads images using `Amplify.Storage`.
public struct AmplifyImageProvider: ImageDataProvider {
public let key: String
public let accessLevel: StorageAccessLevel
public var cacheKey: String {
"\(accessLevel.rawValue)/\(key)"
}
public func data(handler: @escaping (Result<Data, Error>) -> Void) {
Amplify.Logging.verbose("""
Kingfisher will load an image using Amplify.Storage with key \(cacheKey) and access level \(accessLevel)
""")
let options = StorageDownloadDataRequest.Options(accessLevel: accessLevel)
_ = Amplify.Storage.downloadData(key: key, options: options) { result in
switch result {
case .success(let data):
Amplify.Logging.verbose("Success loading image data for Kingfisher using Amplify.Storage")
handler(.success(data))
case .failure(let error):
Amplify.Logging.error(error: error)
handler(.failure(error))
}
}
}
}
extension Source {
/// Returns a `.provider(ImageDataProvider)` setup with the Amplify integration.
///
/// UIKit example:
///
/// ```swift
/// let imageView = ImageView()
/// imageView.kf.setImage(with: .amplify(key: "myimage", accessLevel: .guest))
/// ```
///
/// SwiftUI example:
///
/// ```swift
/// VStack {
/// KFImage(source: .amplify(key: "myimage", accessLevel: .guest))
/// }
/// ```
///
/// - Parameters
/// - key: the stored image identifier.
/// - accessLevel: the access level (defaults to `.guest`)
/// - Returns: `.provider(ImageDataProvider)` using `AmplifyImageProvider`
public static func amplify(key: String, accessLevel: StorageAccessLevel = .guest) -> Source {
return .provider(AmplifyImageProvider(key: key, accessLevel: accessLevel))
}
}
#endif
@drochetti
Copy link
Author

This is till not 100% accurate, since on private and protected access the user id needs to be part of the path:

// TODO: needs to wire up the user id when access if not `.guest`
public var cacheKey: String {
    "\(accessLevel.rawValue)/\(key)"
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment