Post

Replies

Boosts

Views

Activity

Reply to SwiftUI NavigationLink pops out by itself
Another approach to the navigation link workaround collection is placing a hidden NavigationLink in the background that is shared across a few buttons, instead of each button being a NavigationLink: swift extension View {     func navigateDestination: View(         isActive: BindingBool,         destination: Destination?     ) - some View {         background(             NavigationLink(                 destination: destination,                 isActive: isActive,                 label: EmptyView.init             )             .hidden()         )     } } extension View {     func navigateItem, Destination: View(         item: BindingItem?,         destination: (Item) - Destination     ) - some View {         navigate(             isActive: Binding(                 get: { item.wrappedValue != nil },                 set: { if !$0 { item.wrappedValue = nil } }             ),             destination: Group {                 if let item = item.wrappedValue {                     destination(item)                 }             }         )     } } Then you can use it like this: swift struct ShowMoreView: View {     @State private var isLinkActive = false     var body: some View {         List {             Button(action: { isLinkActive = true })                 Text("Start navigation 1")             }             Button(action: { isLinkActive = true })                 Text("Start navigation 2")             }             Button(action: { isLinkActive = true })                 Text("Start navigation 3")             }         }         .navigate(isActive: $isLinkActive, destination: makeDestination())     } } struct ShowMoreView: View {     @State private var date: Date?     var body: some View {         List {             Button(action: { date = Date() })                 Text("Start navigation 1")             }             Button(action: { date = Date() + 100 })                 Text("Start navigation 2")             }             Button(action: { date = Date() + 1000 })                 Text("Start navigation 3")             }         }         .navigate(item: $date, destination: makeDestination)     }     func makeDestination(for date: Date) - some View {         ...     } } This source is from SwiftWithMajid's blog (for some reason the forums is not allowing me to link to it, but search for "swiftui majid lazy navigation" and you'll find it).
Topic: UI Frameworks SubTopic: SwiftUI Tags:
May ’21
Reply to Localization in Xcode
I was surprised from this too when I saw the Apple examples not using keys, ever since SwiftUI was released and even in Xcode 13. I've always used strongly-typed keys in production apps because changing the text would break all my translations. I'm really trying to see how Apple sees it and use the English translations right in the view as the keys. I even refactored one of my production apps like this to get a true sense. Translation breaks much more frequently on copy changes, but I can see the argument that it's expected since the other languages should change too, and importing them gives the warning to catch those that break, although a compiler warning would be nice because Missing Localizability never really catches anything because LocalizedStringKey conforms to ExpressibleByStringLiteral so Xcode will always assume you're using a localized entry. The other thing from here that's hard to accept is the localization comments crowding up the views badly. I've wondered why the localization comments and even table names weren't applied to LocalizedStringKey instead of the Text view so I can do something like below which seems to be the best of both worlds while also keeping views succinct. It also allows me to distribute and pass around the localization entry even in places that don't accept a Text view (so I don't have to make a Label the long way for example): extension LocalizedStringKey {     static let fuelPurchase = LocalizedStringKey(         "This purchase gives you fuel for your car",         tableName: "StoreProducts",         bundle: .storeProducts, comments: "This is the text that's displayed for fuel purchases"     ) } Text(.fuelPurchase) Label(.fuelPurchase, systemImage: "bell") I submitted this feedback in #FB9169281 but wanted to share here to get thoughts from others and if maybe there's something I'm missing. PS - I'm not sure if the Apple team has examined how Android Studio handles localizations but it has always been a dream. It allows you to right click on English words and extract to localization. It uses keys behind the scenes to keep all the languages in sync, but during development time, the real English value get super imposed in the editor. So even in my example, I would see Text("This purchase gives you fuel for your car") in the editor based on my dev environment, but clicking on it would show the true code of Text(.fuelPurchase).
Jun ’21
Reply to Localization in Xcode
Discussed this more with cross-functional teams and not using keys a no-go. This will not work if you want to share localization efforts across platforms beyond Apple which is more of a real-world scenario especially in enterprise settings. For example, Android requires localization keys to not have dots and other kinds of characters, also we found many 3rd party localization services had a character limit on key length. And when looking at very long localization entries, using the value as the key just doesn't make sense. I think sticking with my first intuition in using localization keys is the right way despite all the Apple sessions and samples showing otherwise. Also, just to share I was able to achieve isolating localization configurations by extending Text views to initialize from other Text views. This way, I can offload the localization configurations off the view by creating a bunch of static Text views and let the rest of the app pick them off the shelf. First I create the simple but awkward Text extension: public extension Text {     /// Creates a text view from another text view for isolating localization entries.     init(_ text: Text) {         self = text     } } Then create the static Text views with all localization configurations: extension Text {     static let notificationTitle = Text(         "Notifications",         tableName: "NotificationSettings",         comment: "The section title for notifications group on the settings screen"     )     static let snoozeTime = Text(         "Snooze time",         tableName: "NotificationSettings",         comment: "The title of the snooze time in the notifications section of the settings screen"     )     static let snoozeHelp = Text(         "The number of minutes to remind you again later for action, like the functionality of an alarm clock.",         tableName: "NotificationSettings",         comment: "This is the comment for this localized entry"     ) } Then elsewhere in a view, I can do this: struct ContentView: View { var body: some View { VStack { Text(.snoozeTime) Text(.snoozeHelp) } .navigationTitle(.notificationTitle) } } This still lets the localization to be exported properly since the static Text views aren't dynamically generated from variables. I still wish the localization configurations weren't in the Text view itself but in the LocalizedStringKey or a new type such as LocalizedString, since this is the way that String(localized:table:bundle:locale:comments:) works and would just need a SwiftUI counterpart to it.
Jun ’21
Reply to iOS 15 Notification Content not working?
I found the default project that Xcode 13 beta 1 creates for Notification Content with the incorrect filtering of platforms for the UserNotification framework and was crashing with this: Unable to find NSExtensionContextClass (_UNNotificationContentExtensionVendorContext) in extension bundle - did you link the framework that declares the extension point? What fixed is selecting all platforms for the framework:
Topic: App & System Services SubTopic: Core OS Tags:
Jun ’21
Reply to swift-frontend memory usage
Still happening with Xcode 13.1 official release :( The other thread doesn't seem to be related, but wondering if there's something in the Xcode build settings that can be disabled until Apple fixes this debilitating issue?
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Nov ’21
Reply to swift-frontend memory usage
Seems like SwiftUI is tripping up Xcode 13 a lot. Commenting out a random ScrollView or other view sometimes works. swift-frontend process has gone so high to 145GB at one point and I only have 32GB RAM on this machine (Big Sur 11.6.1 / Xcode 13.1).
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Nov ’21
Reply to CloudKit watchOS 6 silent notification problem
I'm having the same problem on watchOS 8.4.. silent notifications are not being sent to the watch but works perfectly for iOS. let zoneID = CKRecordZone.ID(zoneName: "Settings", ownerName: CKCurrentUserDefaultName) let subscriptionID = "settings-subscription-id let subscription = CKRecordZoneSubscription(zoneID: zoneID, subscriptionID: subscriptionID) let notificationInfo = CKSubscription.NotificationInfo() notificationInfo.shouldSendContentAvailable = true subscription.notificationInfo  let subscription = try await database.save(subscription) I call WKExtension.shared().registerForRemoteNotifications() in applicationDidBecomeActive and didRegisterForRemoteNotifications(deviceToken:) does fire. However, didReceiveRemoteNotification does not fire. I also tried some suggestions here like updating the provisioning profile at AppConnect for watch app and extension which makes sense. Looking at the iCloud console though, the watch is never able to create subscriptions at iCloud at all! I query "Data > Subscriptions" section in console and only see the iOS subscription created. Does each device need to have their own unique subscription? Because I also tried this by putting the vendor device identifier in the subscription ID so each device creates their own, but the watch still never creates a subscription at the server nor does it error on database.save(subscription). Is there a trick for the watch to create subscriptions at iCloud? I'm using the above code but no errors result from it, but the subscription records never shows up on the iCloud console (but iOS does and receives silent fine). I also have "Supports Running without iOS app" checked if that makes a difference.
Jan ’22