-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add AvatarService and refactor accordingly (#122)
* Add AvatarService and refactor * Revert * Rename method signature * Update docs * Add @discardableResult to image upload method * Update Sources/Gravatar/Network/Services/AvatarService.swift Co-authored-by: etoledom <[email protected]> * Update Sources/Gravatar/Network/Services/AvatarService.swift Co-authored-by: etoledom <[email protected]> * Update Sources/Gravatar/Network/Services/AvatarService.swift Co-authored-by: etoledom <[email protected]> * Fix documentation warning --------- Co-authored-by: etoledom <[email protected]>
- Loading branch information
Showing
22 changed files
with
493 additions
and
630 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -69,7 +69,7 @@ avatarImageView.gravatar.setImage(email: "[email protected]") { result in | |
} | ||
``` | ||
|
||
You can also download the Gravatar image using the `ImageService` to download an image: | ||
You can also download the Gravatar image using the `AvatarService` to download an image: | ||
|
||
```swift | ||
import Gravatar | ||
|
@@ -81,7 +81,7 @@ Task { | |
} | ||
|
||
func fetchAvatar(with email: String) async { | ||
let service = ImageService() | ||
let service = AvatarService() | ||
|
||
do { | ||
let result = try await service.fetchImage(with: email) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,7 +27,7 @@ gravatarImageView.gravatar.setImage(email: "[email protected]") | |
``` | ||
|
||
For more info check: | ||
- ``GravatarWrapper/setImage(email:placeholder:rating:preferredSize:defaultImage:options:completionHandler:)`` | ||
- ``GravatarWrapper/setImage(email:placeholder:rating:preferredSize:defaultImageOption:options:completionHandler:)`` | ||
|
||
## Featured | ||
|
||
|
@@ -39,7 +39,8 @@ For more info check: | |
|
||
### Downloading images | ||
|
||
- ``ImageService`` | ||
- ``ImageDownloadService`` | ||
- ``AvatarService`` | ||
|
||
|
||
### Get user Profile | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import Foundation | ||
import UIKit | ||
|
||
/// A service to perform uploading and downloading of avatars. | ||
/// | ||
/// An avatar is a profile image of a Gravatar user. See [the avatar docs](https://support.gravatar.com/profiles/avatars/) for more info. | ||
public struct AvatarService { | ||
private let imageDownloader: ImageDownloader | ||
private let imageUploader: ImageUploader | ||
|
||
/// Creates a new `AvatarService` | ||
/// | ||
/// Optionally, you can pass a custom type conforming to ``HTTPClient`` to gain control over networking tasks. | ||
/// Similarly, you can pass a custom type conforming to ``ImageCaching`` to use your custom caching system. | ||
/// - Parameters: | ||
/// - client: A type which will perform basic networking operations. | ||
/// - cache: A type which will perform image caching operations. | ||
public init(client: HTTPClient? = nil, cache: ImageCaching? = nil) { | ||
self.imageDownloader = ImageDownloadService(client: client, cache: cache) | ||
self.imageUploader = ImageUploadService(client: client) | ||
} | ||
|
||
/// Fetches a Gravatar user profile image using the user account's email, and delivers the image asynchronously. See also: ``ImageDownloadService`` to | ||
/// download the avatar via URL. | ||
/// - Parameters: | ||
/// - email: The user account email | ||
/// - options: The options needed to perform the download. | ||
/// - Returns: An asynchronously-delivered Result type containing the image and its URL. | ||
public func fetch( | ||
with email: String, | ||
options: ImageDownloadOptions = ImageDownloadOptions() | ||
) async throws -> ImageDownloadResult { | ||
guard let gravatarURL = GravatarURL.gravatarUrl(with: email, options: options.imageQueryOptions) else { | ||
throw ImageFetchingError.requestError(reason: .urlInitializationFailed) | ||
} | ||
|
||
return try await imageDownloader.fetchImage(with: gravatarURL, forceRefresh: options.forceRefresh, processingMethod: options.processingMethod) | ||
} | ||
|
||
/// Uploads an image to be used as the user's Gravatar profile image, and returns the `URLResponse` of the network tasks asynchronously. Throws | ||
/// ``ImageUploadError``. | ||
/// - Parameters: | ||
/// - image: The image to be uploaded. | ||
/// - email: The user email account. | ||
/// - accessToken: The authentication token for the user. This is a WordPress.com OAuth2 access token. | ||
/// - Returns: An asynchronously-delivered `URLResponse` instance, containing the response of the upload network task. | ||
@discardableResult | ||
public func upload(_ image: UIImage, email: String, accessToken: String) async throws -> URLResponse { | ||
try await imageUploader.uploadImage(image, email: email, accessToken: accessToken) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
65 changes: 65 additions & 0 deletions
65
Sources/Gravatar/Network/Services/ImageDownloadService.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import UIKit | ||
|
||
/// A service to perform image downloading. | ||
/// | ||
/// This is the default type which implements ``ImageDownloader``.. | ||
/// Unless specified otherwise, `ImageDownloadService` will use a `URLSession` based `HTTPClient`, and a in-memory image cache. | ||
public struct ImageDownloadService: ImageDownloader { | ||
private let client: HTTPClient | ||
let imageCache: ImageCaching | ||
|
||
/// Creates a new `ImageDownloadService` | ||
/// | ||
/// Optionally, you can pass a custom type conforming to ``HTTPClient`` to gain control over networking tasks. | ||
/// Similarly, you can pass a custom type conforming to ``ImageCaching`` to use your custom caching system. | ||
/// - Parameters: | ||
/// - client: A type which will perform basic networking operations. | ||
/// - cache: A type which will perform image caching operations. | ||
public init(client: HTTPClient? = nil, cache: ImageCaching? = nil) { | ||
self.client = client ?? URLSessionHTTPClient() | ||
self.imageCache = cache ?? ImageCache() | ||
} | ||
|
||
private func fetchImage(from url: URL, forceRefresh: Bool, processor: ImageProcessor) async throws -> ImageDownloadResult { | ||
let request = URLRequest.imageRequest(url: url, forceRefresh: forceRefresh) | ||
do { | ||
let (data, _) = try await client.fetchData(with: request) | ||
guard let image = processor.process(data) else { | ||
throw ImageFetchingError.imageProcessorFailed | ||
} | ||
imageCache.setImage(image, forKey: url.absoluteString) | ||
return ImageDownloadResult(image: image, sourceURL: url) | ||
} catch let error as HTTPClientError { | ||
throw ImageFetchingError.responseError(reason: error.map()) | ||
} catch { | ||
throw ImageFetchingError.responseError(reason: .unexpected(error)) | ||
} | ||
} | ||
|
||
public func fetchImage( | ||
with url: URL, | ||
forceRefresh: Bool = false, | ||
processingMethod: ImageProcessingMethod = .common | ||
) async throws -> ImageDownloadResult { | ||
if !forceRefresh, let result = cachedImageResult(for: url) { | ||
return result | ||
} | ||
return try await fetchImage(from: url, forceRefresh: forceRefresh, processor: processingMethod.processor) | ||
} | ||
|
||
func cachedImageResult(for url: URL) -> ImageDownloadResult? { | ||
guard let cachedImage = imageCache.getImage(forKey: url.absoluteString) else { | ||
return nil | ||
} | ||
return ImageDownloadResult(image: cachedImage, sourceURL: url) | ||
} | ||
} | ||
|
||
extension URLRequest { | ||
fileprivate static func imageRequest(url: URL, forceRefresh: Bool) -> URLRequest { | ||
var request = forceRefresh ? URLRequest(url: url, cachePolicy: .reloadIgnoringLocalCacheData) : URLRequest(url: url) | ||
request.httpShouldHandleCookies = false | ||
request.addValue("image/*", forHTTPHeaderField: "Accept") | ||
return request | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.