{"id":2638,"date":"2022-06-09T17:43:13","date_gmt":"2022-06-09T21:43:13","guid":{"rendered":"https:\/\/michaelrowe01.com\/?p=2638"},"modified":"2022-12-15T06:45:54","modified_gmt":"2022-12-15T11:45:54","slug":"wwdc-2022-day-four-the-nitty-gritty","status":"publish","type":"post","link":"https:\/\/michaelrowe01.com\/index.php\/blog\/wwdc-2022-day-four-the-nitty-gritty\/","title":{"rendered":"<strong>WWDC 2022 &#8211; Day Four &#8211; The nitty gritty<\/strong>"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Yesterday was a really productive day. As always, there was too much content to get to it all, but I learned a ton of new things that I want to go back and learn more about over the summer.&nbsp; There were multiple sessions that have led me to rethink some of my existing code in both Wasted Time and my Card Tracker app.&nbsp; Today\u2019s set of items is a bit deeper on specific that I believe will have a direct impact on my Card Tracker app, starting with how I manage Photos.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>What\u2019s new in Photos Picker<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The systems photo picker has been updated to not require special permissions.&nbsp; There were sessions over the last two years that I should review including <a href=\"https:\/\/developer.apple.com\/videos\/play\/wwdc2021\/10046\">Improve access to Photos in your app<\/a> (WWDC21) and <a href=\"https:\/\/developer.apple.com\/videos\/play\/wwdc2020\/10652\">Meet the new Photos picker<\/a> (WWDC20).&nbsp; Check out the links to those sessions. Documentation &#8211;&nbsp; <a href=\"https:\/\/developer.apple.com\/documentation\/photokit\">PhotoKit<\/a><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>New Features<ul><li>Added new types of images for filters, like .sceenshots, .screenRecordings, .slomoVideos, etc.&nbsp; These have been back ported too.<\/li><li>You can also use .any, .not, and .or &#8211; examples include (I will certainly want to include these new filters in my app, which should only include .images and .screenshots<ul><li>.filter = .any(of: [.videos, .livePhotos])<\/li><li>.filter = .screenShots<\/li><li>.filter = ..all(of: [.images, .not(.screenshots])<\/li><\/ul><\/li><li>Sheet presentation improvements &#8211; you can now create half-height mode.<\/li><li>You can also use .deselectAssets(withIdentifiers: [identifier])<\/li><li>You can also reorder via the moveAsset<\/li><\/ul><\/li><li>Platform Support<ul><li>It is now available also on macOS and watchOS, so no supported on iOS, iPadOS and the prior two.<\/li><li>On the iPad you have the sidebar available:<\/li><\/ul><\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/michaelrowe01.com\/wp-content\/uploads\/2022\/06\/Screen-Shot-2022-06-09-at-13.01.40-2.png?w=660&#038;ssl=1\" alt=\"\"\/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>On macOS<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/michaelrowe01.com\/wp-content\/uploads\/2022\/06\/Screen-Shot-2022-06-09-at-13.01.17-2.png?w=660&#038;ssl=1\" alt=\"\"\/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>Both pickers will also show assets in iCloudPhotos<\/li><li>On MacOS For simple picks of images or videos &#8211; the NSOpenPanel API may be enough for more apps.<\/li><li>Media Centric apps should use PHPicker<\/li><li>WatchOS Looks like this<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/michaelrowe01.com\/wp-content\/uploads\/2022\/06\/Screen-Shot-2022-06-09-at-13.29.09-2.png?w=660&#038;ssl=1\" alt=\"\"\/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>However only images will show<\/li><li>Frameworks<ul><li>Available in AppKit and SwiftUI, since I am focused on SwiftUI for my apps, I will focus on that side only<\/li><li>SwiftUI API<\/li><li>You can present via a @Binding selection: [PhotosPickerItem]<\/li><li>And using the PhotosPicker(selection: matching:) {} Item<\/li><li>Will pick best layout based on platform, configuration, and screen space<\/li><li>Loading selective photos and videos, note some will be delayed (ie iCloud Photos), show a per Item in loading UI<\/li><li>It uses Transferable and can load directly in your objects via this method.&nbsp; Check out yesterdays \u201cMeet Transferable\u201d session.<\/li><li>Use FileTransferRepresentation to reduce memory footprint<\/li><li>Sample code&nbsp;<\/li><\/ul><\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/michaelrowe01.com\/wp-content\/uploads\/2022\/06\/Screen-Shot-2022-06-09-at-13.35.21-2.png?w=660&#038;ssl=1\" alt=\"\"\/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>You will need to update the image and add a didSet in the model as you see here:<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/michaelrowe01.com\/wp-content\/uploads\/2022\/06\/Screen-Shot-2022-06-09-at-13.36.18-2.png?w=660&#038;ssl=1\" alt=\"\"\/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>Note on watchOS you should consider small short interactions<\/li><li>Family Setup<ul><li>You can also use Images stored in iCloud Photos<\/li><li>This will show a loading UI before closing<\/li><\/ul><\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Discover PhotoKit change history<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Accessing photo change history, allows you to get to information about editing, etc.&nbsp; PhotoKit allows for deep understanding of images in your library. It will also allow you to be notified of updates and deletion of images.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/michaelrowe01.com\/wp-content\/uploads\/2022\/06\/Screen-Shot-2022-06-09-at-13.44.00-2.png?w=660&#038;ssl=1\" alt=\"\"\/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>New Change History API<ul><li>This uses a persistent change token that can be persisted across app launches.&nbsp; It represented library state.<\/li><li>It is local to the device and matched the selected library.<\/li><li>Supported on all platforms that support PhotoKit<\/li><li>For each change you can get details on three types of objects, Asset, Asset Collection, and Collection List<\/li><\/ul><\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/michaelrowe01.com\/wp-content\/uploads\/2022\/06\/Screen-Shot-2022-06-09-at-13.46.34-2.png?w=660&#038;ssl=1\" alt=\"\"\/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>At the end you have a new token.<\/li><li>To look at the persistent change API you will get back a an identifier for each change.&nbsp; You would use that identifier in your app, to store access to specific images,&nbsp; without having to store the image in your app.<\/li><li>If an asset returns .hasAdjustments &#8211; you can update the image view in your app to address if they\u2019ve been edited.<\/li><li>Considerations<ul><li>Determine what is important to your app and only address them.<\/li><li>Make sure your changes run in a background thread since there may be many changes&nbsp;<\/li><\/ul><\/li><li>Handling Errors<ul><li>Expired change token &#8211; older than histories<\/li><li>Change details unavailable.<\/li><li>In both cases refetch data in API<\/li><\/ul><\/li><li>Cinematic Video Access<\/li><li>New Error Codes<ul><li>File provider sync root&nbsp;<\/li><li>Network error<\/li><\/ul><\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>What\u2019s New in App Store Connect<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">App Store Connect is used to manage the apps I have on the App Store.&nbsp; It allows me to setup TestFlights and check the status of new users and updates.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Key Links: <a href=\"https:\/\/developer.apple.com\/app-store-connect\/\">App Store Connect<\/a> and <a href=\"https:\/\/developer.apple.com\/documentation\/appstoreconnectapi\">App Store Connect API<\/a><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Last year we got in app Events, TestFlight for Mac and more.<\/li><li>Enchanted Submission experience<ul><li>Can group multiple items into a single submission<ul><li>Add multiple Review Items to a submission (typically in 24 hours)<\/li><li>Items can be resolved independently &#8211; but all items in a submission must be approved (or removed) before the submission can go forward.<\/li><li>Review items can be App Versions, in-App events, Custom Product Pages, or Product Page Optimization Tests<\/li><\/ul><\/li><li>You can submit without needing a new app version<ul><li>Each submission has an associate platform with it\u2019s now review items. For example:<\/li><li><\/li><\/ul><\/li><\/ul><\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/michaelrowe01.com\/wp-content\/uploads\/2022\/06\/Screen-Shot-2022-06-09-at-13.58.20-2.png?w=660&#038;ssl=1\" alt=\"\"\/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>You can have on \u201cin progress\u201d submission per platform&nbsp;<\/li><li>If you don\u2019t have a version in the submission the other items will be reviewed against a previously submitted version of your app.<\/li><li>There is a decided app review page&nbsp;<ul><li>This is now available as part of the iOS and iPadOS app (previously only on the web portal)<\/li><\/ul><\/li><li>App Store Connect API<ul><li>Last year Xcode cloud, app clips and many other features were added<\/li><li>With 2.0 there is<ul><li>In app purchases and subscriptions<ul><li>Can create , edit and delete them<\/li><li>Manage pricing<\/li><li>Submit for review<\/li><li>Create special offers and promo codes<\/li><\/ul><\/li><li>Customer reviews and developer responses<ul><li>Build your own workflows to manage feedback and review<\/li><\/ul><\/li><li>App Hang diagnostics<ul><li>Used to only show # of changes<\/li><li>Now will include stack traces, logs, and more<\/li><\/ul><\/li><\/ul><\/li><li>Starting to decommission the XML feed and supporting RestAPIs for access<\/li><\/ul><\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Go further with Complications in WidgetKit<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A few years back I added complications to my Watch App and Widgets to my iOS and macOS version of Wasted Time.&nbsp; Apple has now merged this by making complications part of WidgetKit.&nbsp; This gives me an opportunity to update my Complications and also make them available as widgets on the new iOS Lock Screen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Links &#8211;<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li><a href=\"https:\/\/developer.apple.com\/documentation\/widgetkit\/adding_widgets_to_the_lock_screen_and_watch_faces\">Adding widgets to the Lock Screen and watch faces<\/a><\/li><li><a href=\"https:\/\/developer.apple.com\/documentation\/WidgetKit\/Creating-lock-screen-widgets-and-watch-complications\">Creating Lock Screen Widgets and Watch Complications<\/a><\/li><li><a href=\"https:\/\/developer.apple.com\/documentation\/WidgetKit\">WidgetKit<\/a><\/li><\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Check out the Reloaded talk from earlier this week If you have not seen it already.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Unique to WatchOS<ul><li>Watch Specific Family<ul><li>.accessoryCorner<\/li><li>Add the larger circular content style, it will be&nbsp;<\/li><li>.widgetLabel modifier will draw controls for the text, gauge or progress review in the corner.<\/li><\/ul><\/li><li>This are across all<ul><li>.accessoryRectangular (not widget label)<\/li><li>.accessoryInline (already has it\u2019s own label)<\/li><li>.accessoryCircle<ul><li>.widgetLabel can also be used here to provide text (or other information)&nbsp; you may need to look at the environment to decide what you show based on the label.&nbsp; See below:<\/li><\/ul><\/li><\/ul><\/li><\/ul><\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/michaelrowe01.com\/wp-content\/uploads\/2022\/06\/Screen-Shot-2022-06-09-at-14.13.32-2.png?w=660&#038;ssl=1\" alt=\"\"\/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>The larger text watch face will auto scale up one complication to fit.<\/li><li>Auxiliary content<\/li><li>Multiple representation<\/li><li>Migration of existing code<ul><li>Adopt WidgetKit<ul><li>All faces now use rich complications from 12 to 4&nbsp;<\/li><\/ul><\/li><\/ul><\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/michaelrowe01.com\/wp-content\/uploads\/2022\/06\/Screen-Shot-2022-06-09-at-14.15.44-2.png?w=660&#038;ssl=1\" alt=\"\"\/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>Views are used instead of templates<\/li><li>Timelines are also sued.<\/li><li>Upgrade existing installed complications<ul><li>To do this, the app will run automatically on the an existing watch.<\/li><li>This is a new API called CLKComplicationsDataSource with a CLKComplicationWidgetMigrator that you should implement to handle this in your app.&nbsp; See more in the above WidgeKit API documentation listed above.<\/li><li>My approach will be to completely re-write my code to use the four above classes and remove support for watches not running WatchOS 9<\/li><\/ul><\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Discover ARKit 6<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I was really hoping for new hardware this WWDC, but not a new laptop\u2026 I wanted the dev kit for AR\/VR from Apple.&nbsp; Well it didn\u2019t happen.&nbsp; However the new ARKit 6 API may hold hints to what may come in the future.&nbsp; My guess is the new Ear Joint information would definitely need to be available if you had a headset!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Linke:&nbsp;<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li><a href=\"https:\/\/developer.apple.com\/documentation\/arkit\/content_anchors\/tracking_geographic_locations_in_ar\">Tracking Geographic Locations in AR<\/a><\/li><li><a href=\"https:\/\/developer.apple.com\/documentation\/arkit\">ARKit<\/a><\/li><li><a href=\"https:\/\/developer.apple.com\/design\/human-interface-guidelines\/ios\/system-capabilities\/augmented-reality\">Human Interface Guidelines: Augmented Reality<\/a><\/li><li><a href=\"https:\/\/developer.apple.com\/videos\/play\/wwdc2022\/10131\">Qualities of great AR experiences<\/a><\/li><li><a href=\"https:\/\/developer.apple.com\/videos\/play\/wwdc2022\/10128\">Bring your world into augmented reality<\/a><\/li><\/ol>\n\n\n\n<ul class=\"wp-block-list\"><li>4K Video<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/michaelrowe01.com\/wp-content\/uploads\/2022\/06\/Screen-Shot-2022-06-09-at-14.34.31-2.png?w=660&#038;ssl=1\" alt=\"\"\/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>Note that the wide camera has special value for AR work<\/li><li>3840&#215;2840 is the pixel resolution on the 13 Pro for capture.&nbsp; And then simplifies the frame by binning &#8211; to 1920 x 1440, and is used also in low light environments.&nbsp; Roughly every 17ms you get a new image.<\/li><li>With new hardware you can not get access to the full 4k by skipping the binning step above.&nbsp; It will be aver 33ms, or 30 frames per second.&nbsp; Reality Kit will scale, crop and rending for you.<\/li><li>This is available on iPhone 11 and up and any M1 iPad Pro or higher<\/li><li>Camera Enhancements<ul><li>High Resolution Background Photos<ul><li>In an AR session, you can also capture a single photo in the background while continuing to stream&nbsp;<\/li><li>Created a sample app that allows you to see where a picture was actually taken.<\/li><li>Creating of 3D models using option capture will benefit from this feature as you can overlay a 3D UI to provide capture guidance and take pictures at the higher resolution.&nbsp; There is a convenience function to allow your session to capture this via CaptureHighResolutionFrame<\/li><\/ul><\/li><li>HDR mode<ul><li>Another convenience feature .isVideoHDRSupported allows you to turn on .videoHDRAllowed == true on your session\u2019s config<\/li><\/ul><\/li><li>AVCaptureDevice access for more fined control&nbsp;<ul><li>You can do this dynamically as you need it<\/li><\/ul><\/li><li>Exif Tags<ul><li>This are now available for every AR frame.<\/li><\/ul><\/li><\/ul><\/li><li>Plane Anchors<ul><li>Fully decoupled plane anchor and geometry anchor<\/li><li>Information is contained in ARPlaneExtent, and hold .rotationOnYAxis defined by width, height and center&nbsp;<\/li><\/ul><\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/michaelrowe01.com\/wp-content\/uploads\/2022\/06\/Screen-Shot-2022-06-09-at-14.50.58-2.png?w=660&#038;ssl=1\" alt=\"\"\/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>Motion Capture<ul><li>Both skeleton and Joints are detected<\/li><li>Added Ear Joint Tracking (2D)<\/li><li>And better occlusion handling (3)<\/li><\/ul><\/li><li>Location Anchors<ul><li>New cities and countries are supported for Location Anchors<\/li><li>London and many US states<\/li><li>Added 3 in Canada , Singapore, 7 in Japan, and 2 in Australia&nbsp;<\/li><li>More coming later this year&nbsp;<\/li><\/ul><\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Evolve your Core Data schema<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">On thing that my card tracking app doesn\u2019t do is allow you to pick an event and show all the cards based on that event.&nbsp; I have the data, but need to think thru how I would enable this feature.&nbsp; This session may help me out\u2026 Let\u2019s go!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Link &#8211; <a href=\"https:\/\/developer.apple.com\/documentation\/coredata\/using_lightweight_migration\">Using Lightweight Migration<\/a><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>What is schema migration<ul><li>Chaining your data model means you need to materialize it in the data store.<\/li><li>If you don\u2019t change the model you wont\u2019t able to open your datastore&nbsp;<\/li><\/ul><\/li><li>Strategies for migration<ul><li>There are built in tools to migrate your data model.&nbsp; They are referred to as Lightweight migration.<\/li><li>It automatically analyzes and infers the necessary migration changes<\/li><li>This happens at runtime and maps old data to new data<ul><li>Support, adding, removing, making non-optional optional, renaming, and making an optional non-optional and providing a default value.<\/li><li>This also addresses adding and removing relationships, change cardinality, and renaming relationships<\/li><li>Entities are also available for light weight, add, remove, rename, create new parent or child, move an entity up or down in the hierarchy, you CANNOT merge hierarchies&nbsp;<\/li><\/ul><\/li><li>Migration is controlled by two keys<ul><li>NSMigratePersistentStoresAutomaticallyOption<\/li><li>NSInferMappingModelAutomaticallyOption<\/li><li>If you use NSPersistentContainer or NSPersistentStore it happens for you automatically<\/li><\/ul><\/li><li>Let\u2019s see it in code:<\/li><\/ul><\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/michaelrowe01.com\/wp-content\/uploads\/2022\/06\/Screen-Shot-2022-06-09-at-15.03.41-2.png?w=660&#038;ssl=1\" alt=\"\"\/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>You don\u2019t need to make a new model to make changes. &nbsp;<\/li><li>A discussion on how to address non-lightweight is covered in this session.&nbsp; Basically you decompose the migration steps into steps that are available for lightweight &#8211; this way you can step thru multiple migrations to get to your desired end state.<\/li><li>CloudKit schema Migration<ul><li>If you use Core Data and CloudKit keep in mind you need to have a shared understanding<\/li><li>Cloudkit doesn\u2019t support all the features of core data model<\/li><li>Unique constraints are not supported<\/li><li>Undefined and ObjectID are unavailable<\/li><li>All relationships are optional and must have an inverse<\/li><li>You can not modify or delete exiting record types or fields<\/li><li>You can add new fields or record types<\/li><li>It is essentially additive, so consider effects on older versions of the app<\/li><li>Approaches to address<ul><li>Incrementally add new files to existing record types<\/li><li>Version your entities<\/li><li>Create a new container to associate new store with new container, may take an extended period of time for users to upload their data to this new store.<\/li><\/ul><\/li><\/ul><\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Writing for interfaces<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Sometimes a session title looks interesting but I don\u2019t spend a lot of time on the description.&nbsp; This is one of those titles.&nbsp; My guess was API interfaces, but it is really about how to build out clear and concise information in your app; (something I know I need to work on), so this is a pleasant surprise of a session.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Links:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li><a href=\"https:\/\/developer.apple.com\/design\/resources\/\">Apple Design Resources<\/a><\/li><li><a href=\"https:\/\/developer.apple.com\/design\/human-interface-guidelines\/\">Human Interface Guidelines<\/a><\/li><\/ol>\n\n\n\n<ul class=\"wp-block-list\"><li>Early days focus on easy and clear. Conversational with interfaces:&nbsp;<\/li><\/ul>\n\n\n\n<ul class=\"wp-block-list\"><li>Purpose<ul><li>Think about what is the most important thing to know at the moment of the screen<\/li><li>Consider how you order things on the screen.<\/li><li>Headers and Buttons should be clear as people may skip other information<\/li><li>Know what to leave out.&nbsp; Don\u2019t overload the screen with data that could be placed elsewhere or not at all<\/li><li>When introducing a new feature, tell people why it\u2019s there and why it\u2019s important.<\/li><li>Every screen should have a purpose, and for the entire flow.<\/li><\/ul><\/li><li>Anticipation<ul><li>Think of your app as a conversation with the user.<\/li><li>Develop a voice for your app, and vary tone based on the interaction<\/li><li>Think about what comes next in the app flow.&nbsp; This will help you in the interaction&nbsp;<\/li><\/ul><\/li><li>Context<ul><li>Think outside the app, when will people use your app.&nbsp; Will they be distracted<\/li><li>Write helpful alerts &#8211; these are interruptions so make sure they are helpful and clear.&nbsp; Give context, make sure the choices are clear.<\/li><li>Create useful empty states, i.e. show what the user can do.&nbsp; Try not to use idioms.<\/li><\/ul><\/li><li>Empathy<ul><li>Write for everyone, regardless of who your audience is, so you don\u2019t leave people out who may be causally interested in your app<\/li><li>Deal with Localization &#8211; when doing translation be aware of the impact to your UI.<\/li><li>Design for accessibility &#8211; consider size and voice over. &nbsp; Your language should be well designed to make your app welcoming.<\/li><\/ul><\/li><li>Check out the above Human Interface Guidelines to make your app accessible by as many people as possible<\/li><li>Read your writing out loud &#8211; it really helps<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>SwiftUI on iPad: Organize your interface<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The next few sessions are all about SwiftUI and the iPad. My own apps run on multiple platforms and I am really looking forward to making them even better on the iPad. &nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is part 1 of 2 sessions.&nbsp; Links:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li><a href=\"https:\/\/developer.apple.com\/documentation\/SwiftUI\/View\/contextMenu(menuItems:preview:)\">contextMenu(menuItems:preview:)<\/a><\/li><li><a href=\"https:\/\/developer.apple.com\/documentation\/SwiftUI\/EditMode\">EditMode<\/a><\/li><li><a href=\"https:\/\/developer.apple.com\/documentation\/SwiftUI\/List\">List<\/a><\/li><li><a href=\"https:\/\/developer.apple.com\/documentation\/SwiftUI\/NavigationSplitView\">NavigationSplitView<\/a><\/li><li><a href=\"https:\/\/developer.apple.com\/documentation\/SwiftUI\/NavigationSplitViewStyle\">NavigationSplitViewStyle<\/a><\/li><li><a href=\"https:\/\/developer.apple.com\/documentation\/SwiftUI\/Tables\">Tables<\/a><\/li><\/ol>\n\n\n\n<ul class=\"wp-block-list\"><li>Lists and Tables<ul><li>Many of the APIs show also work on Mac.<\/li><li>Multi-column tables should be used for dense lists<ul><li>You now get sections on both Mac and iPadOS &#8211; check out the session SwiftUI on the Mac: Build the fundamentals (WWDC22)<\/li><li>You use a Column Builder instead of a ViewBuilder.<\/li><li>In compact view you only get the first column<\/li><li>There\u2019s a convenience modifier to allow just a string without a viewBuilder<\/li><li>If you have a comparable field then the column becomes sortable (but you have to handle the sorting yourself<\/li><li>On iPad they don\u2019t scroll horizontally so limit your columns.&nbsp; On Mac you can scroll horizontally<\/li><\/ul><\/li><\/ul><\/li><li>Selection and menus<ul><li>Each row has a tag, and some state to hold the tag selection&nbsp;<ul><li>The list will coordinate via a selection binding<\/li><li>Tags are a value for a view in a selectable container. In many cases it can be auto synthesize for you<\/li><li>To manually tag a view use View.tag(_:) &#8211; but be careful tag type is important.<\/li><\/ul><\/li><li>Selection State<\/li><\/ul><\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/michaelrowe01.com\/wp-content\/uploads\/2022\/06\/Screen-Shot-2022-06-09-at-16.42.28-2.png?w=660&#038;ssl=1\" alt=\"\"\/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>Could be a single selection Required selection and multiple selection, along with lightweight multiple selection&nbsp;<\/li><li>List selection no longer requires edit mode&nbsp;<\/li><li>The next session will talk about toolbar buttons<\/li><li>You can also add a multiple select Context Menu.&nbsp; This will work on multiple items, single item or empty area<ul><li>If you use forSelectionType it should match the selection Type<\/li><\/ul><\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/michaelrowe01.com\/wp-content\/uploads\/2022\/06\/Screen-Shot-2022-06-09-at-16.45.37-2.png?w=660&#038;ssl=1\" alt=\"\"\/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>Split Views<ul><li>NavigationSplitView allows for two or three column views &#8211; for details go to the CookBook session from a few days ago<\/li><li>Standard Split View has a Sidebar and a Detailed view &#8211; in landscape they both show by default. In portrait the Sidebar is hidden.<\/li><li>In three column mode you get a Content View between the sidebar and the detail view. Recommended to use automatic style in three column view.<\/li><\/ul><\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>SwiftUI on IPad: add Toolbars, titles and more<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is the second part of SwiftUI on iPad.&nbsp; If you skipped the prior session &#8211; go back and watch it.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/michaelrowe01.com\/wp-content\/uploads\/2022\/06\/Screen-Shot-2022-06-09-at-16.52.26-2.png?w=660&#038;ssl=1\" alt=\"\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Links:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li><a href=\"https:\/\/developer.apple.com\/documentation\/SwiftUI\/Configure-Your-Apps-Navigation-Titles\">Configure Your Apps Navigation Titles<\/a><\/li><li><a href=\"https:\/\/developer.apple.com\/documentation\/SwiftUI\/ControlGroup\">ControlGroup<\/a><\/li><li><a href=\"https:\/\/developer.apple.com\/documentation\/SwiftUI\/ShareLink\">ShareLink<\/a><\/li><li><a href=\"https:\/\/developer.apple.com\/documentation\/SwiftUI\/ToolbarItem\">ToolbarItem<\/a><\/li><li><a href=\"https:\/\/developer.apple.com\/documentation\/SwiftUI\/ToolbarRole\">ToolbarRole<\/a><\/li><\/ol>\n\n\n\n<ul class=\"wp-block-list\"><li>Toolbars &#8211; provide quick action to common features<ul><li>You can customize tool bars, and provide many features that used to be only available on the Mac.<\/li><li>Overflow menus can be handled for you.&nbsp; Change them to a ToolbarItemGroup which will insert individual items into the menu and auto place in the overflow indicator if needed.<\/li><li>There are three areas, leading, trailing and center.&nbsp; Primary actions end up in the Trailing area. Secondary actions are in the overflow menu by default.&nbsp; But if you use ToolBarRole modifier, you can override that behavior<\/li><li>The editor role will move title to the leading location, and will move secondary items in the center area.<\/li><li>User customization (from API on macOS) to adopt this feature.&nbsp; Only toolbar items are customizable.&nbsp; It must have a unique identifier.<\/li><li>Customizations will automatically be persisted across launches.<\/li><li>You can model control groups so that items that are logically together can be added together as one unit.<\/li><li>You also make a toolbarItem as placement: .primaryAction &#8211; to make sure that it is always presented. It will be in the trailing area and is not customizable<\/li><\/ul><\/li><li>Titles and documents<ul><li>You can now define your own Document Types with properties, etc.&nbsp; you can then share those Documents with others via Transferable<\/li><li>You a create a Menu attached to them .navigationTitle, which then can do thing across the document.&nbsp; Like Rename, Print, etc. If you provide a document, you will get a special preview view and a Share icon for Drag and Drop.<\/li><\/ul><\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>The craft of SwiftUI API Design: progressive disclosure<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">My final planned session for the day is about the API design for SwiftUI.&nbsp; During my day job I focus on API discovery and usability.&nbsp; The application I work on has a long history and tons of APIs, but it assumes a lot of preexisting knowledge by potential users.&nbsp; Getting a better view of how to understand Swift\u2019s API design will hopefully help me in my day job too.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Progressive Disclosure is a base design principle. &nbsp;<ul><li>This is not unique to the design of APIs<\/li><li>The Save dialog is a great example of this principle.&nbsp; It shows defaults and common values, but you can always expand the dialog to add complexity.<\/li><\/ul><\/li><li>Making code feel great to use means, the complexity at the call site progressively exposes functionality as it is needed.<\/li><li>Benefit<ul><li>Lowers learning curve<\/li><li>Minimizes time to first build<\/li><li>Creates Tight feedback loop<\/li><\/ul><\/li><\/ul>\n\n\n\n<ul class=\"wp-block-list\"><li>Consider common use cases<ul><li>Label is a great example of this.&nbsp; Simple is just text.<\/li><li>You can drive an overland to create a View for the Label<\/li><li>This same pattern is used across the framework<\/li><\/ul><\/li><li>Provide intelligent defaults<ul><li>To streamline common use cases, all the things that are not specified&nbsp;<\/li><li>A great example is Text(\u201chello world\u201d) with this code it will localize the string, adopt to dark mode, and scale based on accessibility&nbsp; but you don\u2019t need to provide any values.<\/li><li>Line spacing is automatically too.&nbsp; But it can also be manually set of your use case.<\/li><\/ul><\/li><li>Optimize the call site<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/michaelrowe01.com\/wp-content\/uploads\/2022\/06\/Screen-Shot-2022-06-09-at-17.16.14-2.png?w=660&#038;ssl=1\" alt=\"\"\/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>Looking at Table:<\/li><li>The above image is fairly complex example. That shows how to create a simple table but also has the added complexity for sorting and group of data. And it supports sorting.<\/li><li>For a simple example with just the list&nbsp;<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/michaelrowe01.com\/wp-content\/uploads\/2022\/06\/Screen-Shot-2022-06-09-at-17.20.39-2.png?w=660&#038;ssl=1\" alt=\"\"\/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>We can optimize the call site to make it easier. Take a look at this code, note how simple it is.<\/li><li>Compose, don\u2019t enumerate<ul><li>HStack as an example: it only needs two things, the content and how to arrange it.<\/li><li>So most common use cases are simple items next to each other.&nbsp; Alignment may be needed to address all three cases (leading, trailing, center).<\/li><li>What if you want to do spacing, now you an go crazy with enums for every behavior.&nbsp; IF you start enumerating&nbsp; common cases. Try breaking them apart.<\/li><li>An example you can now use Spacer() in a Stack<\/li><\/ul><\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/michaelrowe01.com\/wp-content\/uploads\/2022\/06\/Screen-Shot-2022-06-09-at-17.24.26-2.png?w=660&#038;ssl=1\" alt=\"\"\/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>D20 for the win!<\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Yesterday was a really productive day. As always, there was too much content to get to it all, but I learned a ton of new things that I want to go back and learn more about over the summer.&nbsp; There were multiple sessions that have led me to rethink some of my existing code in [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_wp_convertkit_post_meta":{"form":"-1","landing_page":"0","tag":"0","restrict_content":"0"},"hide_page_title":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[2,3],"tags":[578,657,470,568,97,601,223,566,656,527,655,654,549,636],"class_list":["post-2638","post","type-post","status-publish","format-standard","hentry","category-blog","category-personal-softwareandit","tag-apis","tag-app-store-connect","tag-arkit","tag-complications","tag-core-data","tag-documentation","tag-ipad","tag-menus","tag-photopicker","tag-swiftui","tag-titles","tag-toolbars","tag-widgetkit","tag-wwdc22"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.8 - aioseo.com -->\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Michael Rowe\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/michaelrowe01.com\/index.php\/blog\/wwdc-2022-day-four-the-nitty-gritty\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.8\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Random Thoughts | A blog about things that interest me.\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"WWDC 2022 \u2013 Day Four \u2013 The nitty gritty | Random Thoughts\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/michaelrowe01.com\/index.php\/blog\/wwdc-2022-day-four-the-nitty-gritty\/\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/michaelrowe01.com\/wp-content\/uploads\/2019\/04\/img_0391.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/michaelrowe01.com\/wp-content\/uploads\/2019\/04\/img_0391.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"3088\" \/>\n\t\t<meta property=\"og:image:height\" content=\"2316\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2022-06-09T21:43:13+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2022-12-15T11:45:54+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"WWDC 2022 \u2013 Day Four \u2013 The nitty gritty | Random Thoughts\" \/>\n\t\t<meta name=\"twitter:image\" content=\"https:\/\/michaelrowe01.com\/wp-content\/uploads\/2019\/04\/img_0391.jpg\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/michaelrowe01.com\\\/index.php\\\/blog\\\/wwdc-2022-day-four-the-nitty-gritty\\\/#article\",\"name\":\"WWDC 2022 \\u2013 Day Four \\u2013 The nitty gritty | Random Thoughts\",\"headline\":\"WWDC 2022 &#8211; Day Four &#8211; The nitty gritty\",\"author\":{\"@id\":\"https:\\\/\\\/michaelrowe01.com\\\/index.php\\\/author\\\/michaelrowe\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/michaelrowe01.com\\\/#organization\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/michaelrowe01.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/Screen-Shot-2022-06-09-at-13.01.40-2.png?fit=3840%2C2160&ssl=1\",\"@id\":\"https:\\\/\\\/michaelrowe01.com\\\/index.php\\\/blog\\\/wwdc-2022-day-four-the-nitty-gritty\\\/#articleImage\",\"width\":3840,\"height\":2160},\"datePublished\":\"2022-06-09T17:43:13-04:00\",\"dateModified\":\"2022-12-15T06:45:54-05:00\",\"inLanguage\":\"en-US\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/michaelrowe01.com\\\/index.php\\\/blog\\\/wwdc-2022-day-four-the-nitty-gritty\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/michaelrowe01.com\\\/index.php\\\/blog\\\/wwdc-2022-day-four-the-nitty-gritty\\\/#webpage\"},\"articleSection\":\"blog, Personal - Software and IT, APIs, App Store Connect, ARKit, complications, core data, Documentation, ipad, menus, PhotoPicker, SwiftUI, Titles, Toolbars, widgetkit, wwdc22\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/michaelrowe01.com\\\/index.php\\\/blog\\\/wwdc-2022-day-four-the-nitty-gritty\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/michaelrowe01.com#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/michaelrowe01.com\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/michaelrowe01.com\\\/index.php\\\/category\\\/blog\\\/#listItem\",\"name\":\"blog\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/michaelrowe01.com\\\/index.php\\\/category\\\/blog\\\/#listItem\",\"position\":2,\"name\":\"blog\",\"item\":\"https:\\\/\\\/michaelrowe01.com\\\/index.php\\\/category\\\/blog\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/michaelrowe01.com\\\/index.php\\\/blog\\\/wwdc-2022-day-four-the-nitty-gritty\\\/#listItem\",\"name\":\"WWDC 2022 &#8211; Day Four &#8211; The nitty gritty\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/michaelrowe01.com#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/michaelrowe01.com\\\/index.php\\\/blog\\\/wwdc-2022-day-four-the-nitty-gritty\\\/#listItem\",\"position\":3,\"name\":\"WWDC 2022 &#8211; Day Four &#8211; The nitty gritty\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/michaelrowe01.com\\\/index.php\\\/category\\\/blog\\\/#listItem\",\"name\":\"blog\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/michaelrowe01.com\\\/#organization\",\"name\":\"Michael Rowe\",\"description\":\"A blog about things that interest me.\",\"url\":\"https:\\\/\\\/michaelrowe01.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/michaelrowe01.com\\\/wp-content\\\/uploads\\\/2024\\\/11\\\/IMG_0120.jpeg?fit=1024%2C1024&ssl=1\",\"@id\":\"https:\\\/\\\/michaelrowe01.com\\\/index.php\\\/blog\\\/wwdc-2022-day-four-the-nitty-gritty\\\/#organizationLogo\",\"width\":1024,\"height\":1024},\"image\":{\"@id\":\"https:\\\/\\\/michaelrowe01.com\\\/index.php\\\/blog\\\/wwdc-2022-day-four-the-nitty-gritty\\\/#organizationLogo\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/michaelrowe01.com\\\/index.php\\\/author\\\/michaelrowe\\\/#author\",\"url\":\"https:\\\/\\\/michaelrowe01.com\\\/index.php\\\/author\\\/michaelrowe\\\/\",\"name\":\"Michael Rowe\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/michaelrowe01.com\\\/index.php\\\/blog\\\/wwdc-2022-day-four-the-nitty-gritty\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/23f6c08c7576fa07e47f582da2eb7619aeb556ceddf53a274fdb9069926e5bc1?s=96&r=g\",\"width\":96,\"height\":96,\"caption\":\"Michael Rowe\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/michaelrowe01.com\\\/index.php\\\/blog\\\/wwdc-2022-day-four-the-nitty-gritty\\\/#webpage\",\"url\":\"https:\\\/\\\/michaelrowe01.com\\\/index.php\\\/blog\\\/wwdc-2022-day-four-the-nitty-gritty\\\/\",\"name\":\"WWDC 2022 \\u2013 Day Four \\u2013 The nitty gritty | Random Thoughts\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/michaelrowe01.com\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/michaelrowe01.com\\\/index.php\\\/blog\\\/wwdc-2022-day-four-the-nitty-gritty\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/michaelrowe01.com\\\/index.php\\\/author\\\/michaelrowe\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/michaelrowe01.com\\\/index.php\\\/author\\\/michaelrowe\\\/#author\"},\"datePublished\":\"2022-06-09T17:43:13-04:00\",\"dateModified\":\"2022-12-15T06:45:54-05:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/michaelrowe01.com\\\/#website\",\"url\":\"https:\\\/\\\/michaelrowe01.com\\\/\",\"name\":\"Random Thoughts\",\"description\":\"A blog about things that interest me.\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/michaelrowe01.com\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"WWDC 2022 \u2013 Day Four \u2013 The nitty gritty | Random Thoughts","description":"","canonical_url":"https:\/\/michaelrowe01.com\/index.php\/blog\/wwdc-2022-day-four-the-nitty-gritty\/","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/michaelrowe01.com\/index.php\/blog\/wwdc-2022-day-four-the-nitty-gritty\/#article","name":"WWDC 2022 \u2013 Day Four \u2013 The nitty gritty | Random Thoughts","headline":"WWDC 2022 &#8211; Day Four &#8211; The nitty gritty","author":{"@id":"https:\/\/michaelrowe01.com\/index.php\/author\/michaelrowe\/#author"},"publisher":{"@id":"https:\/\/michaelrowe01.com\/#organization"},"image":{"@type":"ImageObject","url":"https:\/\/i0.wp.com\/michaelrowe01.com\/wp-content\/uploads\/2022\/06\/Screen-Shot-2022-06-09-at-13.01.40-2.png?fit=3840%2C2160&ssl=1","@id":"https:\/\/michaelrowe01.com\/index.php\/blog\/wwdc-2022-day-four-the-nitty-gritty\/#articleImage","width":3840,"height":2160},"datePublished":"2022-06-09T17:43:13-04:00","dateModified":"2022-12-15T06:45:54-05:00","inLanguage":"en-US","mainEntityOfPage":{"@id":"https:\/\/michaelrowe01.com\/index.php\/blog\/wwdc-2022-day-four-the-nitty-gritty\/#webpage"},"isPartOf":{"@id":"https:\/\/michaelrowe01.com\/index.php\/blog\/wwdc-2022-day-four-the-nitty-gritty\/#webpage"},"articleSection":"blog, Personal - Software and IT, APIs, App Store Connect, ARKit, complications, core data, Documentation, ipad, menus, PhotoPicker, SwiftUI, Titles, Toolbars, widgetkit, wwdc22"},{"@type":"BreadcrumbList","@id":"https:\/\/michaelrowe01.com\/index.php\/blog\/wwdc-2022-day-four-the-nitty-gritty\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/michaelrowe01.com#listItem","position":1,"name":"Home","item":"https:\/\/michaelrowe01.com","nextItem":{"@type":"ListItem","@id":"https:\/\/michaelrowe01.com\/index.php\/category\/blog\/#listItem","name":"blog"}},{"@type":"ListItem","@id":"https:\/\/michaelrowe01.com\/index.php\/category\/blog\/#listItem","position":2,"name":"blog","item":"https:\/\/michaelrowe01.com\/index.php\/category\/blog\/","nextItem":{"@type":"ListItem","@id":"https:\/\/michaelrowe01.com\/index.php\/blog\/wwdc-2022-day-four-the-nitty-gritty\/#listItem","name":"WWDC 2022 &#8211; Day Four &#8211; The nitty gritty"},"previousItem":{"@type":"ListItem","@id":"https:\/\/michaelrowe01.com#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/michaelrowe01.com\/index.php\/blog\/wwdc-2022-day-four-the-nitty-gritty\/#listItem","position":3,"name":"WWDC 2022 &#8211; Day Four &#8211; The nitty gritty","previousItem":{"@type":"ListItem","@id":"https:\/\/michaelrowe01.com\/index.php\/category\/blog\/#listItem","name":"blog"}}]},{"@type":"Organization","@id":"https:\/\/michaelrowe01.com\/#organization","name":"Michael Rowe","description":"A blog about things that interest me.","url":"https:\/\/michaelrowe01.com\/","logo":{"@type":"ImageObject","url":"https:\/\/i0.wp.com\/michaelrowe01.com\/wp-content\/uploads\/2024\/11\/IMG_0120.jpeg?fit=1024%2C1024&ssl=1","@id":"https:\/\/michaelrowe01.com\/index.php\/blog\/wwdc-2022-day-four-the-nitty-gritty\/#organizationLogo","width":1024,"height":1024},"image":{"@id":"https:\/\/michaelrowe01.com\/index.php\/blog\/wwdc-2022-day-four-the-nitty-gritty\/#organizationLogo"}},{"@type":"Person","@id":"https:\/\/michaelrowe01.com\/index.php\/author\/michaelrowe\/#author","url":"https:\/\/michaelrowe01.com\/index.php\/author\/michaelrowe\/","name":"Michael Rowe","image":{"@type":"ImageObject","@id":"https:\/\/michaelrowe01.com\/index.php\/blog\/wwdc-2022-day-four-the-nitty-gritty\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/23f6c08c7576fa07e47f582da2eb7619aeb556ceddf53a274fdb9069926e5bc1?s=96&r=g","width":96,"height":96,"caption":"Michael Rowe"}},{"@type":"WebPage","@id":"https:\/\/michaelrowe01.com\/index.php\/blog\/wwdc-2022-day-four-the-nitty-gritty\/#webpage","url":"https:\/\/michaelrowe01.com\/index.php\/blog\/wwdc-2022-day-four-the-nitty-gritty\/","name":"WWDC 2022 \u2013 Day Four \u2013 The nitty gritty | Random Thoughts","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/michaelrowe01.com\/#website"},"breadcrumb":{"@id":"https:\/\/michaelrowe01.com\/index.php\/blog\/wwdc-2022-day-four-the-nitty-gritty\/#breadcrumblist"},"author":{"@id":"https:\/\/michaelrowe01.com\/index.php\/author\/michaelrowe\/#author"},"creator":{"@id":"https:\/\/michaelrowe01.com\/index.php\/author\/michaelrowe\/#author"},"datePublished":"2022-06-09T17:43:13-04:00","dateModified":"2022-12-15T06:45:54-05:00"},{"@type":"WebSite","@id":"https:\/\/michaelrowe01.com\/#website","url":"https:\/\/michaelrowe01.com\/","name":"Random Thoughts","description":"A blog about things that interest me.","inLanguage":"en-US","publisher":{"@id":"https:\/\/michaelrowe01.com\/#organization"}}]},"og:locale":"en_US","og:site_name":"Random Thoughts | A blog about things that interest me.","og:type":"article","og:title":"WWDC 2022 \u2013 Day Four \u2013 The nitty gritty | Random Thoughts","og:url":"https:\/\/michaelrowe01.com\/index.php\/blog\/wwdc-2022-day-four-the-nitty-gritty\/","og:image":"https:\/\/michaelrowe01.com\/wp-content\/uploads\/2019\/04\/img_0391.jpg","og:image:secure_url":"https:\/\/michaelrowe01.com\/wp-content\/uploads\/2019\/04\/img_0391.jpg","og:image:width":3088,"og:image:height":2316,"article:published_time":"2022-06-09T21:43:13+00:00","article:modified_time":"2022-12-15T11:45:54+00:00","twitter:card":"summary","twitter:title":"WWDC 2022 \u2013 Day Four \u2013 The nitty gritty | Random Thoughts","twitter:image":"https:\/\/michaelrowe01.com\/wp-content\/uploads\/2019\/04\/img_0391.jpg"},"aioseo_meta_data":{"post_id":"2638","title":null,"description":null,"keywords":[],"keyphrases":{"focus":{"keyphrase":"","score":0,"analysis":{"keyphraseInTitle":{"score":0,"maxScore":9,"error":1}}},"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":[],"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":"{\"article\":{\"articleType\":\"BlogPosting\"},\"course\":{\"name\":\"\",\"description\":\"\",\"provider\":\"\"},\"faq\":{\"pages\":[]},\"product\":{\"reviews\":[]},\"recipe\":{\"ingredients\":[],\"instructions\":[],\"keywords\":[]},\"software\":{\"reviews\":[],\"operatingSystems\":[]},\"webPage\":{\"webPageType\":\"WebPage\"}}","pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"ai":null,"created":"2022-06-09 21:29:41","updated":"2025-06-04 00:24:20","seo_analyzer_scan_date":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/michaelrowe01.com\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/michaelrowe01.com\/index.php\/category\/blog\/\" title=\"blog\">blog<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<strong>WWDC 2022 \u2013 Day Four \u2013 The nitty gritty<\/strong>\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/michaelrowe01.com"},{"label":"blog","link":"https:\/\/michaelrowe01.com\/index.php\/category\/blog\/"},{"label":"<strong>WWDC 2022 &#8211; Day Four &#8211; The nitty gritty<\/strong>","link":"https:\/\/michaelrowe01.com\/index.php\/blog\/wwdc-2022-day-four-the-nitty-gritty\/"}],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p2aMa8-Gy","jetpack-related-posts":[],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/michaelrowe01.com\/index.php\/wp-json\/wp\/v2\/posts\/2638","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/michaelrowe01.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/michaelrowe01.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/michaelrowe01.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/michaelrowe01.com\/index.php\/wp-json\/wp\/v2\/comments?post=2638"}],"version-history":[{"count":1,"href":"https:\/\/michaelrowe01.com\/index.php\/wp-json\/wp\/v2\/posts\/2638\/revisions"}],"predecessor-version":[{"id":2653,"href":"https:\/\/michaelrowe01.com\/index.php\/wp-json\/wp\/v2\/posts\/2638\/revisions\/2653"}],"wp:attachment":[{"href":"https:\/\/michaelrowe01.com\/index.php\/wp-json\/wp\/v2\/media?parent=2638"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/michaelrowe01.com\/index.php\/wp-json\/wp\/v2\/categories?post=2638"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/michaelrowe01.com\/index.php\/wp-json\/wp\/v2\/tags?post=2638"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}