This is a more advanced iOS17+ widget project to learn how to create a medium and large widget which relies on network calls to update its content.
- Functionality
- Tech Stack
- Frameworks
- Device Compatibility
- Screenshots
- Learnings
- GitHub API Call
- Testing
- Code Comments
- Pull Requests
- Credits
A medium and large sized Widget that gets a GitHub repository and displays the following infos:
- Owner avatar image
- Repository name
- Days since last pushes
- Number of watchers
- Number of forks
- Number of open issues
A large sized Widget that gets the (top 4) contributors of a GitHub repository and displays the following infos:
- Login name
- Avatar
- Number of contributions made
An App Group is setup among the GitHubRepoWatcher and the RepoWatcherIntents target to share the same UserDefaults database.
- Xcode 15.1
- Swift 5.9
- SwiftUI
- WidgetKit
- App Intents
- iPhone >= iOS17.0+
- iPad >= iOS17.0+
Medium/Large Widget | Large Widget |
---|---|
Edit Widget | Widget Intent Configurations |
---|---|
Lock Screen Widgets | Lock Screen Conf |
---|---|
Lock Screen Conf | App Main View |
---|---|
- AsyncImage is not working for widgets.
- To chose good useful information to show to a user of a widget is fundamental. A good widget has to show to a user:
- Glanceable UI Elements
- Graphical attractive data
- Quick information
Point of contention:
- Apple recommends giving a Widget some placeholder (mock data) to show it in the Widget Gallery instead of doing any network calls. (Note: Twitch does network calls in getSnapshot, but probably because of some business reasons)
- But we want to show our users the best representation of our widgets, so how do we do that? Better mock-data?
- Normally there are no error alerts shown to a user in a widget.
- But there are cases where it makes sense to tell the user an issue (eg. 'Sign in with Google').
- How you handle errors in Widgets is a unique product decision.
- To make our lives as developer easier, add log/print statements for debugging errors.
- A successive network call is a network call that relies on a parent network call
- Async/await: 'try await' is like a guard statement, if it fails nothing is being executed below it (because it falls into the catch block)
- If we have an App with different widget types, we can put them into a WidgetBundle
- Configurations introduces (SiriKit) Intents Definitions File
-
- Setup an intents definition file
- 1.1 Info: The intent definition file creates lots of code for you (e.g protocols, classes)
-
- Setup an IntentHandler which is handled in an intents extension target
-
- Add the App Group as capability to the intents extension target
- Is just another small view
- Lock screen widget families are: .accessoryInline, .accessoryRectangular, .accessoryCircular
- On the lock screen: each widget of the same widget type (here GitHubRepo Watcher), can have its own configuration
I use the Arrange, Act and Assert Pattern for Unit Testing.
I love putting in the effort of adding comments to my code, here is why.
When I create PRs I stick to this guideline.
ππ½ Sean Allen
Made with a π Simon Berner