Post

Replies

Boosts

Views

Activity

SwiftData Query not updating after data is loaded from iCloud on initial launch
Apparently the @Query property wrapper from SwiftData does not update when data is loaded from CloudKit. The data can be programmatically be accessed but nothing appears in the view. Steps to reproduce: Create new Xcode project using the SwiftData storage option. Provide a default value for the Item Model. That is required so data can be automatically synced by SwiftData. Enable iCloud -> CloudKit capabilities and choose a container Enable Background Modes -> Remote notification capability Add a toolbar button that prints the number of items from @Query like this: ToolbarItem { Button { print(items.count) } label: { Label("Count", systemImage: "1.circle") } } Install app on a physical device that can sync to iCloud. Add some items using the + in the toolbar Delete app and wait for around a minute Reinstall app with a debugger attached Press the 1.circle button in the toolbar. It will print either 0 or the number of items you previously added. When it does not print 0 the data should be visible but it is not. Once you quit and relaunch the app or press the + button again, all of the items appear. Has anyone else experienced this before? Anything I can do so the data appears / the view reloads once the items are available? I need to update my view once the data has been loaded from iCloud. I already filed a bug report with id FB14619787.
1
2
1.3k
Aug ’24
"Passing argument of non-sendable type 'ContentView' outside of main actor-isolated context may introduce data races"
I'm currently in the process of migrating to Swift 6. A lot of my code triggers the warning from the title. Passing argument of non-sendable type 'ContentView' outside of main actor-isolated context may introduce data races. I depend on the .task/.refreshable modifiers and buttons that trigger asynchronous work that cannot be done on the Main Actor since it takes way to long. The below code demonstrates the problem. Some comments explain my problems further. I read a lot of articles and documentations but couldn't find an answer to such a seemingly simple error struct ContentView: View { // Marking Senable as suggested by the warning causes different warning for @State @State private var authorizationStatus: MusicAuthorization.Status = .notDetermined // Sole purpose to trigger the errors var body: some View { VStack { Text("Hello, world!") Button("Some button") { Task { await doingSomeAsyncWork() // WARNING: Passing argument of non-sendable type 'ContentView' outside of main actor-isolated context may introduce data races } } } .task { // Or refreshable I believe both behave the same await doingSomeAsyncWork() // WARNING: Passing argument of non-sendable type 'ContentView' outside of main actor-isolated context may introduce data races } } // Marking @MainActor is not an option since some of these functions might be running for more than 10 seconds // Tried marking func as nonisolated but that obviously had no effect func doingSomeAsyncWork() async { authorizationStatus = await MusicAuthorization.request() // Just to have a easy asynchronous function. Without some async code in here, the errors disappear } } Thank you
1
0
2.9k
Jul ’24
Outputvolume of AVAudioSession returning rounded values
Using the hardware volume buttons on the iPhone, you have 16 steps you can adjust your volume to. I want to implement a volume control slider in my app. I am updating the value of the slider using AVAudioSession.sharedInstance().outputVolume. The problem is that this returns values rounded to the nearest 0 or 5. This makes the slider jump around. .formatted() is not causing this problem. You can recreate the problem using code below. @main struct VolumeTestApp: App { init() { try? AVAudioSession.sharedInstance().setActive(true) } var body: some Scene { WindowGroup { ContentView() } } } struct ContentView: View { @State private var volume = Double() @State private var difference = Double() var body: some View { VStack { Text("The volume changed by \(difference.formatted())") Slider(value: $volume, in: 0...1) } .onReceive(AVAudioSession.sharedInstance().publisher(for: \.outputVolume), perform: { value in volume = Double(value) }) .onChange(of: volume) { oldValue, newValue in // Only used to make the problem more obvious if oldValue > newValue { difference = oldValue - newValue } else { difference = newValue - oldValue } } } } Here is a video of the problem in action: https://share.icloud.com/photos/00fmp7Vq1AkRetxcIP5EXeAZA What am I doing wrong or what can I do to avoid this? Thank you
1
0
1.3k
Jun ’24
MusicKit Content Rights, Age Rating and App Encryption
I built an app that makes playing audio plays easier using MusicKit. Now I am about to release the app to the app store. Following questions occured while doing so: Am I accessing/showing third party content in my app when I am music (in this case radio plays) from MusicKit? I am getting all of that data directly from Apple. Is Apple a third party in this case? The publisher has an app that can playback all of the content that can be accessed in my app. This app has an age rating of 4+ years. Can I just copy that? I've heard that referring to other apps doesn't convince the App Review Team if they disagree. None of the titles are marked explicit in Apple Music. Under the hood MusicKit is using HTTPS to get the data from Apple's servers. I have no code that has anything to do with encryption or HTTPS. Does my app still uses Non Exempt Encryption because MusicKit does so? Can I access music through MusicKit that is otherwise not available in this region or does MusicKit take care of this for me? In other words do I have to restrict the availability of my app to certain regions so I don't bypass any geo blockings by accident? Thank you
0
0
700
May ’24
Memory usage unstoppably increasing when updating SwiftData Object from Timer
For a kind of podcast player I need to periodically update a swiftData object to keep track of the listening progress. (Happy to hear if there are better ways) I need to do this in many places in my app so I wanted to extract the modelContext into a Singleton so I can write a global function that starts the timer. In doing so I stumbled upon a problem: The memory used by my app is steadily increasing and the device is turning hot. @Observable class Helper { static let shared = Helper() var modelContext: ModelContext? } @main struct SingletontestApp: App { let modelContainer: ModelContainer init() { do { modelContainer = try ModelContainer( for: Item.self, Item.self ) } catch { fatalError("Could not initialize ModelContainer") } Helper.shared.modelContext = modelContainer.mainContext } var body: some Scene { WindowGroup { ContentView() } .modelContainer(modelContainer) } } struct ContentView: View { @Query private var items: [Item] var body: some View { NavigationSplitView { List { ForEach(items) { item in Text(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard)) } } .toolbar { ToolbarItem { Button(action: addItem) { Label("Add Item", systemImage: "plus") } } ToolbarItem { Button(action: updateItemPeriodically) { Label("Change random", systemImage: "dice") } } } } detail: { Text("Select an item") } } func addItem() { withAnimation { let newItem = Item(timestamp: Date()) Helper.shared.modelContext!.insert(newItem) } } @MainActor func updateItemPeriodically() { // Doesn't matter if run as global or local func let descriptor = FetchDescriptor<Item>(sortBy: [SortDescriptor(\.timestamp)]) let results = (try? Helper.shared.modelContext?.fetch(descriptor)) ?? [] let element = results.randomElement() let timer = Timer.scheduledTimer(withTimeInterval: 2, repeats: true) { timer in // Smaller time intervals worsen the problem element?.timestamp = Date.now } } } Calling save() manually or automatically in the timer does not have any effect. I am not sure about my general way of keeping track of listening process so if you think there is a better way, feel free to correct me. Thanks for your help
3
0
1.1k
May ’24
Widgets not showing up on macOS
I am trying to bring my iOS App to native macOS. I am using exactly the same TimelineProvider and widgets (the ones not supported on macOS surrounded by #if(os)). Running the whole app or just the WidgetExtension on iOS works perfectly fine. Running the mac app works perfectly fine apart from missing Widgets. When running the WidgetExtension on My Mac, the WidgetKit Simulator opens and only presents Failed to load widget. The operation couldn't be completed. (WidgetKit_Simulator.WidgetDocument.Error error 4.) The code compiles fine without any warnings, only a file path is printed into the console. file:///Users/myName/Library/Developer/Xcode/DerivedData/MyAppName-dfsiuexplidieybwvbkqofchxirp/Build/Products/Debug/MyApp.app/Contents/PlugIns/MyAppNameWidgetExtensionExtension.appex/ Shortly after I get a log entry Logging Error: Failed to initialize logging system. Log messages may be missing. If this issue persists, try setting IDEPreferLogStreaming=YES in the active scheme actions environment variables. I am not sure which further Informationen I can give to solve my problem. Destinations on main App and Widget Extension is both set to Mac (no suffix). The mac is running 14.4.1 and Xcode 15.3. I am really thankful for any assistance you can give me to fix this problem. Thanks
3
4
1.2k
May ’24
SwiftData not syncing with iCloud
Hello everyone, I followed this (https://www.hackingwithswift.com/quick-start/swiftdata/how-to-sync-swiftdata-with-icloud) guide from Paul Hudson on how to sync swiftdata with iCloud. I tried it on my device directly and it worked exactly as I would expect. Now I tried the same version of the app on another device installed through TestFlight external tester group. It no longer works. When deleting the app, the alert reads "Deleting this app will also delete its data, but any documents or data will be stored in iCloud will not be deleted" so the app should have said something in iCloud. When looking in Settings -> Your Name -> iCloud -> Manage Account Storage, on the working device I can see around 300 KB saved in iCloud, on the other device my app is not listed. Both have a fast and working internet connection, almost fully charged, low data mode turned off, running 17.4.1, Background modes enabled, Mobile data enabled, more than enough unused iCloud storage and plenty of time to sync. I was streaming the logs from the Cloudkit dashboard but nothing appeared there. The data saved neither syncs to another device of the same apple id nor reappears after app removal. The model Container is initialized without any configuration, the only relationship is optional and every value has a default value. There is A LOT of log noise when launching the app and I am unable to get any meaningful information from that. I can only get the log from the device where it is working as expected. I have triple checked that it is exactly the same app version and no debug conditions anywhere. I have absolutely no idea what is causing this. Thanks for any help :)
2
0
3.1k
Mar ’24