diff --git a/README.md b/README.md index 69ecc7e5..267cb8e9 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,13 @@ Follow the steps in the [REST API documentation](https://docs.gravatar.com/api/p For installation instructions and examples, see out [getting started](Sources/Gravatar/Gravatar.docc/GettingStarted.md) guide. +## Documentation + +You can find some detailed articles, tutorials and API docs via these links: + +- [Gravatar docs](https://automattic.github.io/Gravatar-SDK-iOS/gravatar/documentation/gravatar/) +- [GravatarUI docs](https://automattic.github.io/Gravatar-SDK-iOS/gravatarui/documentation/gravatarui/) + ## Author Gravatar diff --git a/Sources/Gravatar/Gravatar.docc/1. GettingStarted.md b/Sources/Gravatar/Gravatar.docc/1. GettingStarted.md new file mode 100644 index 00000000..3727af8f --- /dev/null +++ b/Sources/Gravatar/Gravatar.docc/1. GettingStarted.md @@ -0,0 +1,57 @@ +# Getting started +Install and start using Gravatar for iOS + +## Installation + +### Swift Package Manager + +##### Adding Gravatar SDK to an iOS project in Xcode: +- File > Add Package Dependency +- Search by https://github.com/Automattic/Gravatar-SDK-iOS.git +- Click on **Add Package** + +For more info, check the [Apple Docs](https://developer.apple.com/documentation/xcode/adding-package-dependencies-to-your-app). + +##### Adding Gravatar to a SPM project: + +1. Add the `Gravatar-SDK-iOS` as a dependency of your project. Recommended to use the [latest tagged version](https://github.com/Automattic/Gravatar-SDK-iOS/tags). +2. Add the `Gravatar` product as a dependency of your target. + +```swift +let package = Package( + name: "Package Name", + dependencies: [ + // 1. + .package(url: "https://github.com/Automattic/Gravatar-SDK-iOS.git", from: "x.y.z") + ], + targets: [ + .executableTarget( + name: "Target Name", + dependencies: [ + // 2. + .product(name: "Gravatar", package: "Gravatar") + ] + ) + ] +) +``` +### CocoaPods + +Add `pod 'Gravatar'` to your target in your `PODFILE`. + +```ruby +source 'https://github.com/CocoaPods/Specs.git' +use_frameworks! + +target 'MyApp' do + pod 'Gravatar' +end +``` + +## Articles + +@Links(visualStyle: list) { + - + - + - +} diff --git a/Sources/Gravatar/Gravatar.docc/2. DownloadingAvatar.md b/Sources/Gravatar/Gravatar.docc/2. DownloadingAvatar.md new file mode 100644 index 00000000..2378ec50 --- /dev/null +++ b/Sources/Gravatar/Gravatar.docc/2. DownloadingAvatar.md @@ -0,0 +1,101 @@ +# Downloading an Avatar + +Download an avatar provided by Gravatar. + +## Download Avatar via email + +Use the ``AvatarService`` to download an avatar image: + +```swift +import Gravatar + +// [...] + +Task { + await fetchAvatar(with: "some@email.com") +} + +func fetchAvatar(with email: String) async { + let service = AvatarService() + + do { + let result = try await service.fetchImage(with: .email(email)) + updateAvatar(with: result.image) + } catch { + print(error) + } +} + +@MainActor +func updateAvatar(with image: UIImage) { + avatarImageView.image = image +} +``` + +### Download Options + +Check out ``ImageDownloadOptions`` and [the backend documentation](https://docs.gravatar.com/api/avatars/images/). Pass your preferences about the avatar size, rating etc. Even though each option has a default value we highly encourage you to investigate the provided documentation and set your own values because they can have big impact on the result. + +```swift +import Gravatar + +let service = AvatarService() +let options = ImageDownloadOptions(preferredSize: .points(50), + rating: .general, + forceRefresh: false, + defaultAvatarOption: .mysteryPerson) +let result = try await service.fetch(with: .email("email@domain.com"), options: options) + +``` + +#### Providing a custom ImageProcessor + +If you want to control the way the downloaded `Data` is converted into a `UIImage` you can implement your own ``ImageProcessor``. + + +```swift +import Gravatar + +struct CustomImageProcessor: ImageProcessor { + func process(_ data: Data) -> UIImage? { + let result: UIImage? + // work on the data + // result = ... + return result + } +} + +let service = AvatarService() +let options = ImageDownloadOptions(processingMethod: .custom(processor: CustomImageProcessor())) +let result = try await service.fetch(with: .email("email@domain.com"), options: options) + +``` + +## Download Avatar via URL + +Sometimes you may need to download the Avatar based on a URL. You may also need to apply different options on the URL. + +Use ``AvatarURL`` and ``ImageDownloadService`` to achieve this. + + +```swift +import Gravatar + +// [...] + +let options = AvatarQueryOptions(preferredPixelSize: 120, + rating: .restricted, + defaultAvatarOption: .mysteryPerson) + +// `AvatarURL` takes care of removing the query parameters in the initial URL and reconstructing the URL based on the given options. + +guard let url = URL(string: "https://gravatar.com/avatar/b815b4f3f5e4be2256bce9e25eac7714?r=pg&s=150"), + let avatarURL = AvatarURL(url: url, options: options)?.url else { + // handle the unexpected state +} + +let service = ImageDownloadService() +let result = try await service.fetchImage(with: avatarURL) + +``` + diff --git a/Sources/Gravatar/Gravatar.docc/3. UploadingAvatar.md b/Sources/Gravatar/Gravatar.docc/3. UploadingAvatar.md new file mode 100644 index 00000000..87cf599a --- /dev/null +++ b/Sources/Gravatar/Gravatar.docc/3. UploadingAvatar.md @@ -0,0 +1,25 @@ +# Uploading an Avatar + +Let a user to update their avatar. + +You can provide a way to upload a new avatar for your users who have a Gravatar account. + +At the moment, Gravatar uses WordPress.com OAuth2 access token. Thus, you need a WordPress.com access token to update a user's avatar. Check out [the documentation](https://developer.wordpress.com/docs/oauth2/) to find more about how to get consent from the user and how to retrieve an access token. + +Use ``AvatarService`` to upload an avatar. + +```swift +import Gravatar + +// [...] + +let service = AvatarService() +let image: UIImage = // image of choice from the user +let accessToken = // WordPress.com OAuth2 access token +do { + try await service.upload(image, email: Email("email@domain.com"), accessToken: accessToken) +} catch { + // handle error +} + +`` diff --git a/Sources/Gravatar/Gravatar.docc/4. FetchingProfile.md b/Sources/Gravatar/Gravatar.docc/4. FetchingProfile.md new file mode 100644 index 00000000..d8d7d7f9 --- /dev/null +++ b/Sources/Gravatar/Gravatar.docc/4. FetchingProfile.md @@ -0,0 +1,43 @@ +# Fetching Profile Information + +Fetch a public Gravatar profile. + +Use ``ProfileService`` to fetch profile information. + +```swift +import Gravatar + +// [...] + +Task { + await fetchProfile(with: "some@email.com") +} + +func fetchProfile(with email: String) async { + let service = ProfileService() + + do { + let profile = try await service.fetch(with: .email(email)) + updateUI(with: profile) + } catch { + print(error) + } +} + +@MainActor +func updateUI(with profile: Profile) { + /// Update UI elements... +} +``` + +#### Getting full Profile information and better rate limits + +Follow the steps in the [REST API documentation](https://docs.gravatar.com/api/profiles/rest-api/) to create a Gravatar API key. You can use some features without an API Key, but you’ll receive limited information, and stricter rate limits may apply. So we highly encourage you to create one in the [developer portal](https://gravatar.com/developers/). + +Use the ``Configuration`` class to set an api key, which will be used to authorise the request. + +```swift +await Configuration.shared.configure(with: apiKey) +``` + +See ``Profile`` to know which fields are public, and which ones need `apiKey` authorization. diff --git a/Sources/Gravatar/Gravatar.docc/GettingStarted.md b/Sources/Gravatar/Gravatar.docc/GettingStarted.md deleted file mode 100644 index e889b0af..00000000 --- a/Sources/Gravatar/Gravatar.docc/GettingStarted.md +++ /dev/null @@ -1,121 +0,0 @@ -# Getting started -Install and start using Gravatar for iOS - -## Installation - -### Swift Package Manager - -##### Adding Gravatar SDK to an iOS project in Xcode: -- File > Add Package Dependency -- Search by https://github.com/Automattic/Gravatar-SDK-iOS.git -- Click on `Add Package` - -For more info, check the [Apple Docs](https://developer.apple.com/documentation/xcode/adding-package-dependencies-to-your-app). - -##### Adding Gravatar to a SPM project: - -1. Add the `Gravatar-SDK-iOS` as a dependency of your project. Recommended to use the [latest tagged version](https://github.com/Automattic/Gravatar-SDK-iOS/tags). -2. Add the `Gravatar` product as a dependency of your target. - -```swift -let package = Package( - name: "Package Name", - dependencies: [ - // 1. - .package(url: "https://github.com/Automattic/Gravatar-SDK-iOS.git", from: "x.y.z") - ], - targets: [ - .executableTarget( - name: "Target Name", - dependencies: [ - // 2. - .product(name: "Gravatar", package: "Gravatar") - ] - ) - ] -) -``` -### CocoaPods - -Add `pod 'Gravatar'` to your target in your `PODFILE`. - -```ruby -source 'https://github.com/CocoaPods/Specs.git' -use_frameworks! - -target 'MyApp' do - pod 'Gravatar' -end -``` - -## Getting Started - -### Downloading a user Gravatar image - -Use the ``AvatarService`` to download an image: - -```swift -import Gravatar - -// [...] - -Task { - await fetchAvatar(with: "some@email.com") -} - -func fetchAvatar(with email: String) async { - let service = AvatarService() - - do { - let result = try await service.fetchImage(with: .email(email)) - updateAvatar(with: result.image) - } catch { - print(error) - } -} - -@MainActor -func updateAvatar(with image: UIImage) { - avatarImageView.image = image -} -``` - -### Download Profile information - -You can get the public information of a Gravatar using an instance of ``ProfileService``. - -```swift -import Gravatar - -// [...] - -Task { - await fetchProfile(with: "some@email.com") -} - -func fetchProfile(with email: String) async { - let service = ProfileService() - - do { - let profile = try await service.fetch(with: .email(email)) - updateUI(with: profile) - } catch { - print(error) - } -} - -@MainActor -func updateUI(with profile: Profile) { - /// Update UI elements... -} -``` - -#### Getting full Profile information - -Use the ``Configuration`` class to set an api key, which will be used to authorise the request of a full Gravatar profile. - -```swift -await Configuration.shared.configure(with: apiKey) -``` - -See ``Profile`` to know which fields are public, and whichones need authorization. diff --git a/Sources/Gravatar/Gravatar.docc/Gravatar.md b/Sources/Gravatar/Gravatar.docc/Gravatar.md index c0718a28..f1d4bfc7 100644 --- a/Sources/Gravatar/Gravatar.docc/Gravatar.md +++ b/Sources/Gravatar/Gravatar.docc/Gravatar.md @@ -9,7 +9,6 @@ Gravatar iOS SDK ) } - ## Overview An “avatar” is an image that represents you online—a little picture that appears next to your name when you interact with websites. @@ -17,40 +16,3 @@ An “avatar” is an image that represents you online—a little picture that a A Gravatar is a Globally Recognized Avatar. You upload an image and create your public profile just once, and then when you participate in any Gravatar-enabled site, your Gravatar image and public profile will automatically follow you there. This SDK will allow you to easily implement the Gravatar services in your project. - -### Obtaining a Gravatar Image - -Using the **AvatarService**: - -```swift -let service = AvatarService() -let result = try await imageRetriever.fetch(with: .email("some@email.com")) -let avatar = result.image -``` - -For more information, check ``AvatarService``. - -## Featured - -@Links(visualStyle: list) { - - -} - -## Topics - -### Downloading images - -- ``ImageDownloadService`` -- ``AvatarService`` - - -### Get user Profile - -- ``ProfileService`` - -### Identifiers - -- ``AvatarIdentifier`` -- ``ProfileIdentifier`` -- ``Email`` -- ``HashID`` diff --git a/Sources/GravatarUI/GravatarUI.docc/GettingStarted.md b/Sources/GravatarUI/GravatarUI.docc/GettingStarted.md new file mode 100644 index 00000000..090069a5 --- /dev/null +++ b/Sources/GravatarUI/GravatarUI.docc/GettingStarted.md @@ -0,0 +1,48 @@ +# Getting started +Install and start using GravatarUI for iOS + +## Installation + +### Swift Package Manager + +##### Adding Gravatar SDK to an iOS project in Xcode: +- File > Add Package Dependency +- Search by https://github.com/Automattic/Gravatar-SDK-iOS.git +- Click on **Add Package** + +For more info, check the [Apple Docs](https://developer.apple.com/documentation/xcode/adding-package-dependencies-to-your-app). + +##### Adding GravatarUI to a SPM project: + +Select a package version. Recommended to use the [latest tagged version](https://github.com/Automattic/Gravatar-SDK-iOS/tags). + +```swift +.package(url: "https://github.com/Automattic/Gravatar-SDK-iOS.git", from: "x.y.z") + +``` + +Add the `GravatarUI` product as a dependency for your target: + +```swift +.product(name: "GravatarUI", package: "gravatar-sdk-ios") +``` + +### CocoaPods + +Add `pod 'GravatarUI'` to your target in your `PODFILE`. + +```ruby +source 'https://github.com/CocoaPods/Specs.git' +use_frameworks! + +target 'MyApp' do + pod 'GravatarUI' +end +``` + +## Articles + +@Links(visualStyle: list) { + - + - +} diff --git a/Sources/GravatarUI/GravatarUI.docc/GravatarUI.md b/Sources/GravatarUI/GravatarUI.docc/GravatarUI.md index f27f4178..498f4022 100644 --- a/Sources/GravatarUI/GravatarUI.docc/GravatarUI.md +++ b/Sources/GravatarUI/GravatarUI.docc/GravatarUI.md @@ -15,42 +15,15 @@ An “avatar” is an image that represents you online—a little picture that a A Gravatar is a Globally Recognized Avatar. You upload an image and create your public profile just once, and then when you participate in any Gravatar-enabled site, your Gravatar image and public profile will automatically follow you there. -This SDK offers an easy way to present Gravatar user's visually in your app. - -### How to: - -We offer a variety of profile view layouts for different usecases. As an example, you can use a ```ProfileView``` to be added to your UI in this way: - -```swift -// 1. Get an instance of a ProfileService -let service = ProfileService() -// 2. Get the user's profile: -let profile = try await service.fetch(with: .email("user@email.com")) -// 3. Get the instance of a ProfileView: -let profileView = ProfileView() -// 4. Set the profile to the view: -profileView.update(with: profile) -``` -`ProfileView` will look like this: -![Profile view example](profileView.view) - -### Gravatar profile image - -To set a gravatar image on your own `UIImageView` instance directly (or a `UIImageView subclass`), the easiest way is to use the `.gravatar` extension: - -```swift -import GravatarUI - -// [...] -do { - try await avatarImageView.gravatar.setImage( - avatarID: .email("some@email.com") - ) - print("The image view is already displaying the avatar! 🎉") -} catch { - print(error) +This SDK offers ways to adapt Gravatar profiles to your application with stylish visuals. + +## Articles + +@Links(visualStyle: list) { + - + - + - } -``` ## Tutorials @@ -58,7 +31,7 @@ do { - } -## Topics +## Important Types ### Profile views @@ -74,3 +47,7 @@ do { ### UI Content Configuration - ``ProfileViewConfiguration`` + +### Color Palette + +- ``PaletteType`` diff --git a/Sources/GravatarUI/GravatarUI.docc/ProfileViews.md b/Sources/GravatarUI/GravatarUI.docc/ProfileViews.md new file mode 100644 index 00000000..5e0e0ccf --- /dev/null +++ b/Sources/GravatarUI/GravatarUI.docc/ProfileViews.md @@ -0,0 +1,100 @@ +# Profile view designs + +We offer a variety of profile view layouts for different usecases. + +As an example, you can use a ```ProfileView``` to be added to your UI in this way: + +```swift +// 1. Get an instance of a ProfileService +let service = ProfileService() +// 2. Get the user's profile: +let profile = try await service.fetch(with: .email("user@email.com")) +// 3. Get the instance of a ProfileView: +let profileView = ProfileView() +// 4. Set the profile to the view: +profileView.update(with: profile) +``` + +#### Currently we offer 4 styles: + +``ProfileViewConfiguration/Style/standard`` (underlying type: ``ProfileView``) + +![](profileView.view) + +``ProfileViewConfiguration/Style/summary`` (underlying type: ``ProfileSummaryView``) + +![](profileSummaryView.view) + +``ProfileViewConfiguration/Style/large`` (underlying type: ``LargeProfileView``) + +![](largeProfileView.view) + +``ProfileViewConfiguration/Style/largeSummary`` (underlying type: ``LargeProfileSummaryView``) + +![](largeProfileSummaryView.view) + +### How to use a `ProfileViewConfiguration` to manage the view + +``ProfileViewConfiguration`` is a `UIContentConfiguration` and it allows you to create or update the content view. + +```swift +import GravatarUI + +let profile = try await service.fetch(with: .email("user@email.com")) +var config = ProfileViewConfiguration.standard() + +// customize it for your neeeds: +config.palette = .system // or .custom(paletteProvider) to pass your own `Palette`. +config.padding = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8) +config.profileButtonStyle = .view +config.delegate = // delegate to handle events +config.model = profile + +let view = config.makeContentView() + +// Update the config as needed. +// Let's fetch a different profile for example. + +// Clear the model and start loading indicators: +config.model = nil +config.isLoading = true +view.configuration = config + +// Fetch the profile: +let profile = try await service.fetch(with: .email("other_user@email.com")) + +// Set the model and stop loading indicators: +config.model = profile +config.isLoading = true +view.configuration = config + +``` +#### How to apply a custom color palette + +See ``PaletteType`` for available color palettes. You can also pass your own ``Palette`` if you need different colors. + +```swift +import GravatarUI + +let myPalette1 = Palette(...) +let myPalette2 = Palette(...) +let myPalette3 = Palette(...) + +let paletteProvider = { + switch currentTheme { + case .theme1: + return myPalette1 + case .theme2: + return myPalette2 + case .theme2: + return myPalette3 + } +} + +var config = ProfileViewConfiguration.standard() +config.paletteType = .custom(paletteProvider) + +let view = config.makeContentView() + +``` + diff --git a/Sources/GravatarUI/GravatarUI.docc/UIImageViewExtension.md b/Sources/GravatarUI/GravatarUI.docc/UIImageViewExtension.md new file mode 100644 index 00000000..837d3719 --- /dev/null +++ b/Sources/GravatarUI/GravatarUI.docc/UIImageViewExtension.md @@ -0,0 +1,104 @@ +# UIImageView extension + +Use UIImageView extension to easily set an avatar. + +### Set an avatar via email + +To set an avatar on your own `UIImageView` directly (or a `UIImageView subclass`), the easiest way is to use the `.gravatar` extension: + +```swift +import GravatarUI + +// [...] + +let avatarImageView = UIImageView() + +do { + try await avatarImageView.gravatar.setImage(avatarID: .email("some@email.com")) + print("The image view is already displaying the avatar! 🎉") +} catch { + print(error) +} +``` + +#### Extra options + +You can pass an `option` parameter of type [``ImageSettingOption``] to customize the operaton. + +```swift +import GravatarUI + +// [...] + +let placeholder = UIImage(named: "...") +let avatarImageView = UIImageView() + +do { + try await avatarImageView.gravatar.setImage( + avatarID: .email(""), + placeholder: placeholder, + options: [.forceRefresh, + .transition(.fade(0.3)), + .imageCache(MyCache.shared)] // MyCache should conform to ``ImageCaching``. + ) + print("The image view is already displaying the avatar! 🎉") +} catch { + print(error) +} +``` + +### Show an activity indicator + +You can show an activity indicator on the UIImageView during the download. + +```swift +import GravatarUI + +// [...] + +let avatarImageView = UIImageView() + +do { + // You can use the system activity indicator by: + avatarImageView.gravatar.activityIndicatorType = .activity + + // and then access it by: + avatarImageView.gravatar.activityIndicator?.view.tintColor = .blue + + // Or, you can use a fully custom activity indicator: + avatarImageView.gravatar.activityIndicatorType = .custom(MyActivityIndicator()) // `MyActivityIndicator` conforms to ``ActivityIndicatorProvider`` + + try await avatarImageView.gravatar.setImage(avatarID: .email("some@email.com")) + print("The image view is already displaying the avatar! 🎉") +} catch { + print(error) +} +``` + +### Set an avatar via URL + +```swift +import GravatarUI + +// [...] + +let avatarImageView = UIImageView() +let options = AvatarQueryOptions(preferredPixelSize: 120, + rating: .restricted, + defaultAvatarOption: .mysteryPerson) + +// `AvatarURL` takes care of removing the query parameters in the initial URL and reconstructing the URL based on the given options. + +guard let url = URL(string: "https://gravatar.com/avatar/b815b4f3f5e4be2256bce9e25eac7714?r=pg&s=150"), + let avatarURL = AvatarURL(url: url, options: options)?.url else { + // handle the unexpected state +} +let placeholder = UIImage(named: "...") + +do { + try await avatarImageView.gravatar.setImage(with: avatarURL, placeholder: placeholder) + print("The image view is already displaying the avatar! 🎉") +} catch { + print(error) +} +```