Post

Replies

Boosts

Views

Activity

How to read NSUserActivityTypes array?
I've never used NSUserActivityTypes before, and I'm struggling to understand exactly how it works and I'm hoping someone with some experience can shed a bit of light. In particular, as of iOS 13, Apple recommends storing user state using an NSUserActivity object attached to a scene, so I've been trying to a) better understand how NSUserActivity works and b) implement that in my own code. In working through Apple's documentation, I came across this piece of code:class var activityType: String { let activityType = "" // Load our activity type from our Info.plist. if let activityTypes = Bundle.main.infoDictionary?["NSUserActivityTypes"] { if let activityArray = activityTypes as? [String] { return activityArray[0] } } return activityType }I think I understand what this is doing (it looks at the Info.plist file for an entry called "NSUserActivityTypes", if it exists it tries to get the associated array of activityTypes, and then it reads the first item in the array), but what I don't understand is why we're only reading the first item in activityArray. In this case we know the first (and only item) is "com.apple.apple-samplecode.StateRestoration.activity" because we have to manually create that plist entry. But I don't understand why we are hard coding looking at the first item of the array in order to get the activity type, because if we know we're just going to get back the String "com.apple.apple-samplecode.StateRestoration.activity", why not just write the code to be this:class var activityType: String { return "com.apple.apple-samplecode.StateRestoration.activity" }I've never worked with NSUserActivity before, and I understand that it can be (usually is?) used for things other than state preservation/restoration, so there could be many different kinds of useractivities that your app could support (handoff, Siri integration, etc.). So I would assume that we want our code to be as robust as possible in not making any assumptions about the kinds of NSUserActivity objects we might receive.Maybe someone who has more experience with NSUserActivity can help explain the ways in which NSUserActivity might be handed to my app, and why we can hard code in the first element of an array, while in other places we want to check if a passed-in activity is the right kind of activity (even though we know our array of supported activities has only one kind of activity, so presumably there's only one kind of activity we'd receive in the first place?).Also, this isn't unique to Apple's sample code... this blog post also takes a similar approach when reading the Info.plist file:extension Bundle { var activityType: String { return Bundle.main.infoDictionary?["NSUserActivityTypes"].flatMap { ($0 as? [String])?.first } ?? "" } }
0
0
1.3k
Feb ’20
Developing iOS 13 app on Xcode 12 beta?
I'm a new developer who has never gone through the transition from one major release of iOS to another. I've been finishing up work on an app whose deployment target is iOS 13.2. Any tips on how to balance things between now and the fall? In particular, I need to do three things: I want to finish my app and release it, which I can do entirely on Xcode 11, and not have to worry about iOS 14 at all. So that's easy :) I want to test my app against iOS 14 to see how it will run. I assume I need to do this in the beta version of Xcode 12? Can I do my iOS 13 development in Xcode 12 as well, or will I need to go back and forth between two versions of Xcode? And will Xcode 12 try to automatically change my app to iOS 14 when I open it? I'll want to start preparing an iOS 14 version of the app for the fall. I'm the way to do that is to branch my code in git and open that branch in Xcode 12? Any tips or best practices on how to do that? Thanks for the help
7
0
5k
Jun ’20
Migrating existing SwiftUI apps to the new multi platform template
I have an iOS 13 app that I’m hoping to release soon that is written entirely in SwiftUI. If I was starting from scratch today, I’d obviously use the new multi platform template which looks awesome.... But since I’m not starting from scratch, what are the recommendations/best practices for existing apps? Is there a path for migrating existing apps to take advantage of the new app structure (below) when moving to iOS 14? @main struct HelloWorld: App { var body: some Scene { WindowGroup { Text(“Hello, world!”).padding() } } }
2
0
1.8k
Jun ’20
Broken Profile Link?
When I click my avatar in the upper right corner of the Forums, I get a little pop-over that allows me to either click my username to get to my public profile, edit my profile, or sign out. The link to my public profile seems to be broken. That link takes me to https://developer.apple.com/forums/profile/ryanbdevilled which resolves to an Error - Page Not Found. However, the link at the end of posts that I make (like this one) goes to https://developer.apple.com/forums/profile/ryanbdevilled+ which resolves correctly. The only difference is a plus-sign at the end of the URL. Do others have the same issue?
4
0
718
Jun ’20
Connecting SwiftUI app to CoreData
Just finished watching the Data Essentials in SwiftUI session, and I had a few questions relating to connecting the views to the data model. In particular, one example from the video was this: @main struct BookClubApp: App { 		@StateObject private var store = ReadingListStore() 		var body: some Scene { 				WindowGroup { 						ReadingListViewer(store: store) 				} 		} } I assume that the initializer for ReadingListStore() would connect to any arbitrary data backing. If we're using CoreData, how does @StateObject wrapper on the store relate to/impact the use of @FetchRequest property wrapper on CoreData requests? Should we no longer use @FetchRequest because @StateObject is handling ensuring that changes to store are reflected in the UI? Second, the video used this example to emphasize the difference between @ObservedObject and @StateObject: struct ReadingListViewer: View { 		var body: some View { 				NavigationView { 						ReadingList() 						Placeholder() 				} 		} } struct ReadingList: View { 		@StateObject var store = ReadingListStore() 		var body: some View { 				// ... 		} } What I didn't quite understand was whether even with the @StateObject the store was being recreated every time that ReadingList view appeared on screen (but it's preventing the store from being recreated every time the view is redrawn while on screen)? If the store is drawing from some data model elsewhere, either way the issue is one of efficiency, not data loss, right? Finally, I had a question about data relating to the app - scene distinction. If our app doesn't have a need to show the same data side by side in split screen (iPadOS) or in different windows (Mac), where is the best place to do our logic so that we get a new project/document/etc anytime a user opens a new window (ie creates a new scene)? In other words if the data model is for example a canvas with a bunch of shapes on it, where should we put the logic for having the app show a new canvas every time a new scene is created? If we did something like this: @main struct BookClubApp: App { 		var body: some Scene { 				WindowGroup { 						ReadingListViewer() 				} 		} } struct ReadingListViewer: View { @StateObject var store = ReadingListStore() 		var body: some View { 				NavigationView { 						ReadingList() 						Placeholder() 				} 		} } Would that allow us to assume that every time ReadingListStore() is called, we are getting a new scene?
4
0
3.2k
Jun ’20
Help identifying device factors that could cause a SwiftUI view to crash
I'm trying to debug an idiosyncratic crash that is occurring for only one of my TestFlight beta testers. I have an app in TestFlight where one of my testers is having a crash that no one else seems to be having. I could use some help trying to identify device specific factors that could be triggering this issue in my app. My app has a main view, with a few child views reachable through navigation links. For this one tester if they go from the main view, to a list view, back to the main view, and then to a settings view, the whole app crashes. Every single time. If they go to the settings view first, the view loads without crashing. If they then go back to the main view, then to the list, back to the main view, and then to settings, it crashes. None of my other testers are having this issue, which makes me think that there's something specific to this device. What factors should I be investigating? He's tried deleting the app and reinstalling from TestFlight. He's running 13.5.1 (build target is 13.5). FWIW the initial part of the thread dump is this: Exception Type: EXCBREAKPOINT (SIGTRAP) Exception Codes: 0x0000000000000001, 0x000000019f2b3fb4 Termination Signal: Trace/BPT trap: 5 Termination Reason: Namespace SIGNAL, Code 0x5 Terminating Process: exc handler [5190] Triggered by Thread: 0 Thread 0 name: Thread 0 Crashed: 0 libswiftCore.dylib 0x000000019f2b3fb4 assertionFailure(::file:line:flags:) + 800 (AssertCommon.swift:132) 1 libswiftCore.dylib 0x000000019f2b3fb4 assertionFailure(:_:file:line:flags:) + 800 (AssertCommon.swift:132) 2 SwiftUI 0x00000001ca068e70 EnvironmentObject.error() + 220 (EnvironmentObject.swift:55) 3 Unstuck 0x00000001025dd214 closure #1 in closure #1 in SettingsView.body.getter + 1056 (<compiler-generated>:0) 4 Unstuck 0x00000001025dfe74 partial apply for closure #1 in closure #1 in SettingsView.body.getter + 24
0
0
820
Jul ’20
Xcode 12 CoreData Template
I'd love some help trying to understand the CoreDate template that you get when you create a new multiplatform app in Xcode 12 (beta 6 fwiw). In particular, I want to better understand what is happening in the initializer for the PersistenceController: init(inMemory: Bool = false) { container = NSPersistentContainer(name: "CoreDataTest2")         if inMemory {             container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")         }         container.loadPersistentStores(completionHandler: { (storeDescription, error) in             if let error = error as NSError? {                 fatalError("Unresolved error \(error), \(error.userInfo)")             }         })     } In particular, I'm wondering about two things: What purpose does the inMemory Bool serve? It's set to true when the template uses the SwiftUI preview, but when else would you set it to true? When would you set it to false? When it is set to true it then creates the persistent store description to a file URL with path "/dev/null" -- what does this mean? Do we need to set the Persistent Store Description to something else in production code?
1
0
1.4k
Sep ’20