{"id":668,"date":"2024-01-31T17:41:29","date_gmt":"2024-01-31T16:41:29","guid":{"rendered":"https:\/\/sii.ua\/blog\/?p=668"},"modified":"2024-02-16T09:34:18","modified_gmt":"2024-02-16T08:34:18","slug":"widgets-in-ios-16","status":"publish","type":"post","link":"https:\/\/sii.ua\/blog\/en\/widgets-in-ios-16\/","title":{"rendered":"Widgets in iOS 16"},"content":{"rendered":"\n<p>Apple introduced widgets for the first time in iOS 14, and with the release of iOS 16.0, widgets have been added to the Lock Screen to improve UX and usability. Widgets show the main information of an application without opening the application itself.<\/p>\n\n\n\n<p>This article will cover the main aspects of using widgets (in particular on the Lock Screen), as well as a tutorial with a simple demo application for iOS 16 using a new type of widget.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Widget families<\/strong><\/h2>\n\n\n\n<p>There are four widget families that can be displayed on unlocked device\u2019s screen (together with apps):<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>systemSmall<\/li>\n\n\n\n<li>systemMedium<\/li>\n\n\n\n<li>systemLarge<\/li>\n\n\n\n<li>SystemExtraLarge<\/li>\n<\/ul>\n\n\n\n<p>And four accessory families which can be displayed Apple Watch or iOS device\u2019s Lock Screen:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>accessoryCircle<\/li>\n\n\n\n<li>accessoryRectangular<\/li>\n\n\n\n<li>accessoryInline (contains a single text line and optional image)<\/li>\n\n\n\n<li>accessoryCorner (WatchOS only)<br><\/li>\n<\/ul>\n\n\n\n<p>Screenshots below presents a different accessories appearance on iOS and WatchOS:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-1-1.png\"><img decoding=\"async\" width=\"1000\" height=\"562\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-1-1.png\" alt=\"a different accessories appearance on iOS and WatchOS\" class=\"wp-image-669\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-1-1.png 1000w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-1-1-300x169.png 300w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-1-1-768x432.png 768w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-1-1-555x312.png 555w\" sizes=\"(max-width: 1000px) 100vw, 1000px\" \/><\/a><\/figure>\n\n\n\n<p>Lock screen widgets are supporting those rendering modes:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>vibrant,<\/li>\n\n\n\n<li>full-colour,<\/li>\n\n\n\n<li>accented.<\/li>\n<\/ul>\n\n\n\n<p>For iOS, there is available only vibrant mode which provides desaturated text, images and gauges in monochrome view for widgets. Check out the <a href=\"https:\/\/developer.apple.com\/documentation\/widgetkit\/creating-lock-screen-widgets-and-watch-complications\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" >official documentation<\/a> to learn more.<\/p>\n\n\n\n<p>The image below shows how the widget appearance changes when the rendering mode is changed (from full-colour to accented blue colour):<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-2.png\"><img decoding=\"async\" width=\"642\" height=\"355\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-2.png\" alt=\"how the widget appearance changes \" class=\"wp-image-673\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-2.png 642w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-2-300x166.png 300w\" sizes=\"(max-width: 642px) 100vw, 642px\" \/><\/a><\/figure>\n\n\n\n<p>The widget family should be specific to the application and content size. An accent colour can be used to highlight the title and provide an aesthetically pleasing widget UI.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Lock Screen widgets customization and limitations<\/strong><\/h2>\n\n\n\n<p>Widgets have many limitations. In Apple\u2019s documentation, we can find that we shouldn&#8217;t consider widgets as separate apps. It\u2019s just an extension to an existing app, and we can\u2019t implement functions like scrolling, buttons or other interactive mechanics. It should be a simple view with text and optional images.<\/p>\n\n\n\n<p>Building our little project and adding widgets to it, <strong>we encountered some limitations that we would like to share with you.<\/strong><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Constraints encountered in the project<\/strong><\/h3>\n\n\n\n<p>The first of them is the size of the entries array given in <a href=\"https:\/\/developer.apple.com\/documentation\/widgetkit\/intenttimelineprovider\/gettimeline(for:in:completion:)-9oqa4\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" >getTimeline<\/a> method. For example, updates will not work if the size of the array of objects of the type <a href=\"https:\/\/developer.apple.com\/documentation\/widgetkit\/timelineentry\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" >TimelineEntry<\/a> is too large (more than about 1000), but if there are about 100 of them, then everything works as expected).<\/p>\n\n\n\n<p>The next limitation is the frequency of updating the widget. There is a limit to updating the actual information about the widget, the update depends on the logic provided in the <a href=\"https:\/\/developer.apple.com\/documentation\/widgetkit\/intenttimelineprovider\/gettimeline(for:in:completion:)-9oqa4\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" >getTimeline<\/a> method and on the <a href=\"https:\/\/developer.apple.com\/documentation\/widgetkit\/keeping-a-widget-up-to-date#:~:text=Reloads%20Within%20a-,Budget,-Reloading%20widgets%20consumes\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" >budget<\/a> of the widget calculated by WidgetKit. The budget is unique for each widget and the system takes into account many factors to calculate it. See the <a href=\"https:\/\/developer.apple.com\/documentation\/widgetkit\/keeping-a-widget-up-to-date\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" >link<\/a> for detailed information about the budget.<\/p>\n\n\n\n<p>The third type of limitation is related to the UI representation of the widget. The developer must take care that the content fits correctly in the widget\u2019s frame and all-important information is visible to the user. When adding an image to a widget, the developer must pay attention that it will take up additional space, while the size of the widget will remain the same. There is also a limit on the size of the images. Empirically, it was found out that the widget will not work with a 1200x1200px image, while it works with its small version 120x120px.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Lock Screen widget demo tutorial<\/strong><\/h2>\n\n\n\n<p>For the purpose of this article, we\u2019ve prepared a small demo app to show how widgets work and how easy is to implement one. We will focus on <strong>iOS <\/strong>only leaving <strong>WatchOS <\/strong>for another occasion.<\/p>\n\n\n\n<p>For the beginning, please download a starter app from GitHub or <a href=\"https:\/\/github.com\/SiiIOSAcademy\/QuotesDemoApp\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" >clone it from provided link<\/a> using Xcode 14 beta 1 or newer.<\/p>\n\n\n\n<p><strong>* A disclaimer here<\/strong> \u2013 we used Xcode 14 beta 1 to build this project and there is a small chance that something will be not working or Apple will make some changes in code for the released version of Xcode or future betas.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-3.png\"><img decoding=\"async\" width=\"374\" height=\"696\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-3.png\" alt=\"screenshot of quote\" class=\"wp-image-675\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-3.png 374w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-3-161x300.png 161w\" sizes=\"(max-width: 374px) 100vw, 374px\" \/><\/a><\/figure>\n\n\n\n<p>After you clone and run the project it should download quotas from the Internet and show it on devices or simulator\u2019s screen. <strong>This app was built to show you a quotation from a simple API<\/strong>. You can move between quotes by scrolling down or up on the screen. If you\u2019d like you can also share a quote using share button.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Initial preparation<\/strong><\/h3>\n\n\n\n<p>After you play with the app, we can go to Xcode project and start building a simple widget that will get random quotes from API and show them on a widget outside the app. After chosen time period quotation will change for another. Let\u2019s start.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Zrzut-ekranu-2022-06-24-o-18.49.52-1024x668-1.png\"><img decoding=\"async\" width=\"1024\" height=\"668\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Zrzut-ekranu-2022-06-24-o-18.49.52-1024x668-1.png\" alt=\"QuotesDemoApp\" class=\"wp-image-677\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Zrzut-ekranu-2022-06-24-o-18.49.52-1024x668-1.png 1024w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Zrzut-ekranu-2022-06-24-o-18.49.52-1024x668-1-300x196.png 300w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Zrzut-ekranu-2022-06-24-o-18.49.52-1024x668-1-768x501.png 768w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Go to project navigator and select your project name on the top. Next in general settings on the right press \u201c+\u201d to add a new target with widget.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Zrzut-ekranu-2022-06-24-o-18.50.11-1024x668-1.png\"><img decoding=\"async\" width=\"1024\" height=\"668\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Zrzut-ekranu-2022-06-24-o-18.50.11-1024x668-1.png\" alt=\"Choose a template for your new target\" class=\"wp-image-679\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Zrzut-ekranu-2022-06-24-o-18.50.11-1024x668-1.png 1024w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Zrzut-ekranu-2022-06-24-o-18.50.11-1024x668-1-300x196.png 300w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Zrzut-ekranu-2022-06-24-o-18.50.11-1024x668-1-768x501.png 768w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Enter Product Name and do not check <strong>Include Configuration Intent<\/strong>, because we will not use it in this simple demo. We will use static configuration here.<\/p>\n\n\n\n<p>Intent configuration can be used for user-configurable properties that will for example change what data will be displayed by a widget or to allow automate your app using Siri and Shortcuts. Press Next.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-7.png\"><img decoding=\"async\" width=\"372\" height=\"550\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-7.png\" alt=\"Activate \" class=\"wp-image-681\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-7.png 372w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-7-203x300.png 203w\" sizes=\"(max-width: 372px) 100vw, 372px\" \/><\/a><\/figure>\n\n\n\n<p>Xcode will probably ask you if you want to activate the scheme for our newly created widget for building and debugging. It is recommended to do so if we want to be able to test the code.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"1024\" height=\"660\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Zrzut-ekranu-2022-06-24-o-19.09.00-1024x660-1.png\" alt=\"code\" class=\"wp-image-683\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Zrzut-ekranu-2022-06-24-o-19.09.00-1024x660-1.png 1024w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Zrzut-ekranu-2022-06-24-o-19.09.00-1024x660-1-300x193.png 300w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Zrzut-ekranu-2022-06-24-o-19.09.00-1024x660-1-768x495.png 768w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Now, we have our widget target added to the project. You can see new files on the left. I marked them with blue frame. We will get to the <strong>QuotesWidget.swift<\/strong> file in the moment. First select three files as shown on the screenshot above, and in File inspector on the right choose Target <strong>Membership <\/strong>for <strong>QuotesWidgetExtension<\/strong> also with <strong>QuotesDemoApp<\/strong>. This will allow using services, model and view model on both targets instead of creating the same files for all targets separately.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-9.png\"><img decoding=\"async\" width=\"390\" height=\"262\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-9.png\" alt=\"code\" class=\"wp-image-685\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-9.png 390w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-9-300x202.png 300w\" sizes=\"(max-width: 390px) 100vw, 390px\" \/><\/a><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Building the widget<\/strong><\/h3>\n\n\n\n<p>We can now focus on building our widget. Go to<strong> QuotesWidget.swift<\/strong> and start with changing <strong>SimpleEntry <\/strong>struct to <strong>QuoteEntry <\/strong>for better readability. We will add a \u201c<strong>let quote: Quote<\/strong>\u201d to allow widget to get our quote data for displaying it on user\u2019s device.<\/p>\n\n\n\n<p>Let\u2019s look closer on <strong>QuoteEntry <\/strong>struct. It has to conform to <a href=\"https:\/\/developer.apple.com\/documentation\/widgetkit\/timelineentry\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" ><strong>TimelineEntry<\/strong><\/a> protocol. Widgets on iOS can be changed during time events or user action. Those structs are created to provide data for a timeline of views to be displayed at the appropriate time.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-10-1.png\"><img decoding=\"async\" width=\"921\" height=\"381\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-10-1.png\" alt=\"code\" class=\"wp-image-687\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-10-1.png 921w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-10-1-300x124.png 300w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-10-1-768x318.png 768w\" sizes=\"(max-width: 921px) 100vw, 921px\" \/><\/a><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>The Provider Struct<\/strong><\/h3>\n\n\n\n<p>The Provider struct that conforms to <a href=\"https:\/\/developer.apple.com\/documentation\/widgetkit\/timelineprovider\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" ><strong>TimeLineProvider<\/strong><\/a> protocol has three required methods that we will be using to tell widget when to send our data to the view and how to update it.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/developer.apple.com\/documentation\/widgetkit\/timelineprovider\/placeholder(in:)\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" ><strong>placeholder(in: )<\/strong><\/a>method is providing data for widget\u2019s placeholder UI which is the temporary content of your widget. This method is usually called when for example device\u2019s environment changes occur like change of dynamic type setting. System may reload your widget and use placeholder data. In this case we are using example quote written in code to quickly acquire necessary data.<\/li>\n\n\n\n<li><a href=\"https:\/\/developer.apple.com\/documentation\/widgetkit\/timelineprovider\/getsnapshot(in:completion:)\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" ><strong>getSnapshot(for: )<\/strong><\/a> is used to create a single data snapshot for your widget. Snapshot is where the system needs to quickly display a single entry. Data from this method is used for example on widget gallery, when user can choose a widget to be displayed on the home screen. We\u2019re also using an example quote here were needed fast access to data to quickly return a view.<\/li>\n\n\n\n<li><a href=\"https:\/\/developer.apple.com\/documentation\/widgetkit\/timelineprovider\/gettimeline(in:completion:)\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" ><strong>getTimeline(in: )<\/strong><\/a> method contains an array of entries and rules when they should be displayed on widget. Timelines are a combination of views and dates that are returned, which allow you to decide at what time a particular view should be shown.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-11-1.png\"><img decoding=\"async\" width=\"921\" height=\"615\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-11-1.png\" alt=\"code\" class=\"wp-image-689\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-11-1.png 921w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-11-1-300x200.png 300w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-11-1-768x513.png 768w\" sizes=\"(max-width: 921px) 100vw, 921px\" \/><\/a><\/figure>\n\n\n\n<p>In our example we used asynchronous function running on main thread to get quotes, put them in array of <strong>QuoteEntry <\/strong>objects and manipulate date objects to allow widget to show a new quote every 10 seconds. Feel free to use different time interval or change the method to display quotes in a different way.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Timeline<\/strong><\/h3>\n\n\n\n<p><a href=\"https:\/\/developer.apple.com\/documentation\/widgetkit\/timeline\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" ><strong>Timeline<\/strong><\/a> object from method <a href=\"https:\/\/developer.apple.com\/documentation\/widgetkit\/timelineprovider\/gettimeline(in:completion:)\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" ><strong>getTimeline<\/strong><\/a> creates a timeline with quote entries and a policy how to create a new timeline when actual one used the last object in the array. We can choose how new timeline gets created: after selected date, after using last entry from the array (used in this case) and after user interaction within the app.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Widget options and the view<\/strong><\/h3>\n\n\n\n<p>When we created our placeholder, snapshot and timeline, we can configure widget options and the view.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-12.png\"><img decoding=\"async\" width=\"710\" height=\"363\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-12.png\" alt=\"code\" class=\"wp-image-691\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-12.png 710w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-12-300x153.png 300w\" sizes=\"(max-width: 710px) 100vw, 710px\" \/><\/a><\/figure>\n\n\n\n<p>In main widget struct we can set widget\u2019s configuration and settings. It uses configuration and provider to populate the view with data we provided earlier.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The <a href=\"https:\/\/developer.apple.com\/documentation\/widgetkit\/staticconfiguration\/init(kind:provider:content:)\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" ><strong>kind: String<\/strong><\/a> variable is an exclusive name for this widget which should be different from our other widgets names.<\/li>\n\n\n\n<li>A <a href=\"https:\/\/developer.apple.com\/documentation\/widgetkit\/staticconfiguration\/configurationdisplayname(_:)-8puo4\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" ><strong>.configurationDisplayName<\/strong><\/a>shows a name of our widget on device screen.<\/li>\n\n\n\n<li>A <a href=\"https:\/\/developer.apple.com\/documentation\/widgetkit\/staticconfiguration\/description(_:)-20uc6\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" ><strong>.description<\/strong><\/a> as name suggest should be a short description what our widget is about.<\/li>\n\n\n\n<li><a href=\"https:\/\/developer.apple.com\/documentation\/widgetkit\/staticconfiguration\/supportedfamilies(_:)\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" ><strong>.supportedFamilies<\/strong><\/a> method tells the widget what sizes it should be using on main screen. We are using <a href=\"https:\/\/developer.apple.com\/documentation\/widgetkit\/widgetfamily\/systemsmall\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" ><strong>.systemSmall<\/strong><\/a> and <a href=\"https:\/\/developer.apple.com\/documentation\/widgetkit\/widgetfamily\/systemmedium\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" ><strong>.systemMedium<\/strong><\/a> to present small square widget to the user and rectangular medium size widget.<\/li>\n<\/ul>\n\n\n\n<p>We can also use some new types for supported families that ware announced with iOS 16. We will get back to it later.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-13.png\"><img decoding=\"async\" width=\"643\" height=\"687\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-13.png\" alt=\"code\" class=\"wp-image-693\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-13.png 643w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-13-281x300.png 281w\" sizes=\"(max-width: 643px) 100vw, 643px\" \/><\/a><\/figure>\n\n\n\n<p>As for a view, we are using standard <strong>SwiftUI <\/strong>components, separate for each system family we\u2019re using to allow rendering different components for each view. This is quite normal procedure, because different family can contain different amount of text and images.<\/p>\n\n\n\n<p>Please, feel free to build a view for <a href=\"https:\/\/developer.apple.com\/documentation\/widgetkit\/widgetfamily\/systemlarge\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" ><strong>.systemLarge<\/strong><\/a> type of family and see how it is different from medium and small.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-14.png\"><img decoding=\"async\" width=\"938\" height=\"237\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-14.png\" alt=\"code\" class=\"wp-image-695\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-14.png 938w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-14-300x76.png 300w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-14-768x194.png 768w\" sizes=\"(max-width: 938px) 100vw, 938px\" \/><\/a><\/figure>\n\n\n\n<p>If you have problems with setting up the preview for a view in canvas, you can use this code above.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-15.png\"><img decoding=\"async\" width=\"518\" height=\"480\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-15.png\" alt=\"Screens of the iPhones\" class=\"wp-image-697\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-15.png 518w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-15-300x278.png 300w\" sizes=\"(max-width: 518px) 100vw, 518px\" \/><\/a><\/figure>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Adding new widget to the home screen<\/strong><\/h3>\n\n\n\n<p>Now you can add your new widget to the home screen. If it\u2019s not appearing in widget gallery, just put its name in a search field.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-16.png\"><img decoding=\"async\" width=\"777\" height=\"363\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-16.png\" alt=\"code\" class=\"wp-image-699\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-16.png 777w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-16-300x140.png 300w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-16-768x359.png 768w\" sizes=\"(max-width: 777px) 100vw, 777px\" \/><\/a><\/figure>\n\n\n\n<p>If we want to use a new API for iOS 16 that shows widgets on the lock screen, we just need to add a new family type to supported families and update the view.<\/p>\n\n\n\n<p>A rectangular widget can display text and a small image.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-17.png\"><img decoding=\"async\" width=\"423\" height=\"201\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-17.png\" alt=\"code\" class=\"wp-image-701\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-17.png 423w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-17-300x143.png 300w\" sizes=\"(max-width: 423px) 100vw, 423px\" \/><\/a><\/figure>\n\n\n\n<p>We can add a <strong>new case<\/strong> to our view that will be displayed on a lock screen widget.<\/p>\n\n\n\n<p><a href=\"https:\/\/developer.apple.com\/documentation\/swiftui\/viewthatfits\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" ><strong>ViewThatFits<\/strong><\/a> adapts to available space and use it all for children views. This way text will fill all available widget\u2019s space.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-18.png\"><img decoding=\"async\" width=\"506\" height=\"484\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-18.png\" alt=\"Screens of the iPhones\" class=\"wp-image-703\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-18.png 506w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-18-300x287.png 300w\" sizes=\"(max-width: 506px) 100vw, 506px\" \/><\/a><\/figure>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Adding widget to the lock screen<\/strong><\/h2>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-19.png\"><img decoding=\"async\" width=\"862\" height=\"147\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-19.png\" alt=\"code\" class=\"wp-image-705\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-19.png 862w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-19-300x51.png 300w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-19-768x131.png 768w\" sizes=\"(max-width: 862px) 100vw, 862px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-20.png\"><img decoding=\"async\" width=\"390\" height=\"165\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-20.png\" alt=\"code\" class=\"wp-image-707\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-20.png 390w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-20-300x127.png 300w\" sizes=\"(max-width: 390px) 100vw, 390px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-21.png\"><img decoding=\"async\" width=\"374\" height=\"696\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-21.png\" alt=\"Screen of the iPhone\" class=\"wp-image-709\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-21.png 374w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-21-161x300.png 161w\" sizes=\"(max-width: 374px) 100vw, 374px\" \/><\/a><\/figure>\n\n\n\n<p>By adding <a href=\"https:\/\/developer.apple.com\/documentation\/widgetkit\/widgetfamily\/accessoryinline\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" ><strong>.accessoryInline<\/strong><\/a>we can now add an inline widget on lock screen. This widget just shows a single line of text and an optional image at the top of the screen.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-22.png\"><img decoding=\"async\" width=\"704\" height=\"165\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-22.png\" alt=\"code\" class=\"wp-image-711\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-22.png 704w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-22-300x70.png 300w\" sizes=\"(max-width: 704px) 100vw, 704px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-23.png\"><img decoding=\"async\" width=\"533\" height=\"219\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-23.png\" alt=\"code\" class=\"wp-image-713\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-23.png 533w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-23-300x123.png 300w\" sizes=\"(max-width: 533px) 100vw, 533px\" \/><\/a><\/figure>\n\n\n\n<p>Adding <a href=\"https:\/\/developer.apple.com\/documentation\/widgetkit\/widgetfamily\/accessorycircular\" target=\"_blank\" rel=\"noopener\" title=\"\" rel=\"nofollow\" ><strong>.accessoryCircular<\/strong><\/a> allows us to use circular widgets with text, image or a new <a href=\"https:\/\/developer.apple.com\/documentation\/swiftui\/gauge\" rel=\"nofollow\" >Gauge<\/a> view, which we are using here.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-24.png\"><img decoding=\"async\" width=\"414\" height=\"770\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-24.png\" alt=\"Screen of the iPhone\" class=\"wp-image-715\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-24.png 414w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Ryc.-24-161x300.png 161w\" sizes=\"(max-width: 414px) 100vw, 414px\" \/><\/a><\/figure>\n\n\n\n<p>Using a circular widget and gauge you can show a value represented in some sort of value in a declared range in a circular way or linear if we use another accessory family.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Conclusion<\/strong><\/h2>\n\n\n\n<p>Apple has done a great job with widgets on the Lock Screen for iOS devices, adding improvements, personalization, and live activities. With the right approach to creation, the Lock Screen widgets can significantly improve the user experience and provide greater ease of use. As we just build a widget ourselves, we can now write that the API is very friendly to developers and easy to implement.<\/p>\n\n\n\n<p><em>Many thanks to Damian Drohobycki and Marta Mazurek for an inspiration to write this article, technical review and support.<\/em><\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;668&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;0&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;0&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;2&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;0\\\/5&quot;,&quot;size&quot;:&quot;30&quot;,&quot;title&quot;:&quot;Widgets in iOS 16&quot;,&quot;width&quot;:&quot;0&quot;,&quot;_legend&quot;:&quot;{score}\\\/5&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 2px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 2px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 2px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 2px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 2px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 0px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 2px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 2px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 2px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 2px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 2px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 24px;\">\n            <span class=\"kksr-muted\"><\/span>\n    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>Apple introduced widgets for the first time in iOS 14, and with the release of iOS 16.0, widgets have been &hellip; <a class=\"continued-btn\" href=\"https:\/\/sii.ua\/blog\/en\/widgets-in-ios-16\/\">Continued<\/a><\/p>\n","protected":false},"author":43,"featured_media":671,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","inline_featured_image":false,"footnotes":""},"categories":[1],"tags":[106,107,108],"class_list":["post-668","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-hard-development","tag-digital-competency-center","tag-ios","tag-widget"],"acf":[],"aioseo_notices":[],"featured_media_url":"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Widzety-w-systemie-iOS-16-1.jpg","category_names":["Hard development"],"_links":{"self":[{"href":"https:\/\/sii.ua\/blog\/en\/wp-json\/wp\/v2\/posts\/668"}],"collection":[{"href":"https:\/\/sii.ua\/blog\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sii.ua\/blog\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sii.ua\/blog\/en\/wp-json\/wp\/v2\/users\/43"}],"replies":[{"embeddable":true,"href":"https:\/\/sii.ua\/blog\/en\/wp-json\/wp\/v2\/comments?post=668"}],"version-history":[{"count":4,"href":"https:\/\/sii.ua\/blog\/en\/wp-json\/wp\/v2\/posts\/668\/revisions"}],"predecessor-version":[{"id":899,"href":"https:\/\/sii.ua\/blog\/en\/wp-json\/wp\/v2\/posts\/668\/revisions\/899"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.ua\/blog\/en\/wp-json\/wp\/v2\/media\/671"}],"wp:attachment":[{"href":"https:\/\/sii.ua\/blog\/en\/wp-json\/wp\/v2\/media?parent=668"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.ua\/blog\/en\/wp-json\/wp\/v2\/categories?post=668"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.ua\/blog\/en\/wp-json\/wp\/v2\/tags?post=668"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}