Swift is a powerful and intuitive programming language for Apple platforms and beyond.

Posts under Swift tag

200 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

Interacting with the Notes application
Hello, Relatively new to AppleScripts in current gen (I've used it back in 2010s) and would like some help if someone can point me in the right direction. Is AppleScript the best/only way to interact with Notes application? (I'm on Sequioa) 1.1 I've tried to use LLM to generate a Swift app, but it still calls out to AppleScripts, so I'm wondering if I'm missing something. 1.2 If I'm going down a rabbit hole, I'd like to stop since I want to finish this quick task and move on and or fall deeply in love with AppleScripts... whichever comes first. Is There a better way to write notes? Script Editor is still a minimal IDE, I'd love to find something that will do some auto completion/suggestions because the documentation in the Script Editor is still a tad weak. (I'm used to interpreted languages like bash, ruby, etc...) where if I don't understand something I just dig into the code instead of turse documentation that just exposes public end points and does not tell you much more :( My problem: I'd like to set up a cron that periodically checks my notes, and cleans up the shared notes. Basically it's a shared set of notes that have checklist on it and cleans up. (weekly chores etc...) I want to read the notes, find out which ones have been marked checked. Reset the ones that are done, leave unfinished ones alone and reset the old ones. This is how far I've gotten: let appleScript = """``` tell application "Notes" set targetNote to note "\Test" of default account return body of targetNote end tell That works like a charm, Kind of dumb because I rather use and ID of the note not the name :( It returns the following <div><b><span style=\\"font-size: 24px\\">Test</span></b></div> <div><br></div> <ul> <li> Not Done</li> <li>Done</li> <li>Not Done yet</li> </ul> <div><br></div> <div>Single line</div> Which is a good start! Issues: There is no way to tell which Item is marked "Checked" and which one is not :( Any helps is greatly appreciated!
1
0
269
Mar ’25
iOS Share Extension Warning: Passing argument of non-sendable type outside of main actor-isolated context may introduce data races
Consider this simple miniature of my iOS Share Extension: import SwiftUI import Photos class ShareViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() if let itemProviders = (extensionContext?.inputItems.first as? NSExtensionItem)?.attachments { let hostingView = UIHostingController(rootView: ShareView(extensionContext: extensionContext, itemProviders: itemProviders)) hostingView.view.frame = view.frame view.addSubview(hostingView.view) } } } struct ShareView: View { var extensionContext: NSExtensionContext? var itemProviders: [NSItemProvider] var body: some View { VStack{} .task{ await extractItems() } } func extractItems() async { guard let itemProvider = itemProviders.first else { return } guard itemProvider.hasItemConformingToTypeIdentifier(UTType.url.identifier) else { return } do { guard let url = try await itemProvider.loadItem(forTypeIdentifier: UTType.url.identifier) as? URL else { return } try await downloadAndSaveMedia(reelURL: url.absoluteString) extensionContext?.completeRequest(returningItems: []) } catch {} } } On the line 34 guard let url = try await itemProvider.loadItem ... I get these warnings: Passing argument of non-sendable type '[AnyHashable : Any]?' outside of main actor-isolated context may introduce data races; this is an error in the Swift 6 language mode 1.1. Generic enum 'Optional' does not conform to the 'Sendable' protocol (Swift.Optional) Passing argument of non-sendable type 'NSItemProvider' outside of main actor-isolated context may introduce data races; this is an error in the Swift 6 language mode 2.2. Class 'NSItemProvider' does not conform to the 'Sendable' protocol (Foundation.NSItemProvider) How to fix them in Xcode 16? Please provide a solution which works, and not the one which might (meaning you run the same code in Xcode, add your solution and see no warnings). I tried Decorating everything with @MainActors Using @MainActor in the .task @preconcurrency import Decorating everything with @preconcurrency Playing around with nonisolated
2
0
479
Mar ’25
Swift 6 Concurrency errors with ModelActor, or Core Data actors
In my app, I've been using ModelActors in SwiftData, and using actors with a custom executor in Core Data to create concurrency safe services. I have multiple actor services that relate to different data model components or features, each that have their own internally managed state (DocumentService, ImportService, etc). The problem I've ran into, is that I need to be able to use multiple of these services within another service, and those services need to share the same context. Swift 6 doesn't allow passing contexts across actors. The specific problem I have is that I need a master service that makes multiple unrelated changes without saving them to the main context until approved by the user. I've tried to find a solution in SwiftData and Core Data, but both have the same problem which is contexts are not sendable. Read the comments in the code to see the issue: /// This actor does multiple things without saving, until committed in SwiftData. @ModelActor actor DatabaseHelper { func commitChange() throws { try modelContext.save() } func makeChanges() async throws { // Do unrelated expensive tasks on the child context... // Next, use our item service let service = ItemService(modelContainer: SwiftDataStack.shared.container) let id = try await service.expensiveBackgroundTask(saveChanges: false) // Now that we've used the service, we need to access something the service created. // However, because the service created its own context and it was never saved, we can't access it. let itemFromService = context.fetch(id) // fails // We need to be able to access changes made from the service within this service, /// so instead I tried to create the service by passing the current service context, however that results in: // ERROR: Sending 'self.modelContext' risks causing data races let serviceFromContext = ItemService(context: modelContext) // Swift Data doesn't let you create child contexts, so the same context must be used in order to change data without saving. } } @ModelActor actor ItemService { init(context: ModelContext) { modelContainer = SwiftDataStack.shared.container modelExecutor = DefaultSerialModelExecutor(modelContext: context) } func expensiveBackgroundTask(saveChanges: Bool = true) async throws -> PersistentIdentifier? { // Do something expensive... return nil } } Core Data has the same problem: /// This actor does multiple things without saving, until committed in Core Data. actor CoreDataHelper { let parentContext: NSManagedObjectContext let context: NSManagedObjectContext /// In Core Data, I can create a child context from a background context. /// This lets you modify the context and save it without updating the main context. init(progress: Progress = Progress()) { parentContext = CoreDataStack.shared.newBackgroundContext() let childContext = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType) childContext.parent = parentContext self.context = childContext } /// To commit changes, save the parent context pushing them to the main context. func commitChange() async throws { // ERROR: Sending 'self.parentContext' risks causing data races try await parentContext.perform { try self.parentContext.save() } } func makeChanges() async throws { // Do unrelated expensive tasks on the child context... // As with the Swift Data example, I am unable to create a service that uses the current actors context from here. // ERROR: Sending 'self.context' risks causing data races let service = ItemService(context: self.context) } } Am I going about this wrong, or is there a solution to fix these errors? Some services are very large and have their own internal state. So it would be very difficult to merge all of them into a single service. I also am using Core Data, and SwiftData extensively so I need a solution for both. I seem to have trapped myself into a corner trying to make everything concurrency save, so any help would be appreciated!
6
0
761
Mar ’25
Change app language on Apple Watch simulator
I feel a bit dumb now. I once succeeded to change the language of an app on Watch simulator. So it is possible. And I'm not able to repeat (fool of me I did not took note of how I did it). I just remember it was simply through some language settings selection, may be rebooting the Mac, but not by changing anything in code. Does someone know how to do ?
3
0
451
Mar ’25
Why is this causing my app to crash?
I'm developing an app for my watch and have a list of different classes (referred to as 'courses' to avoid confusion) that I take in school, eg: struct Course { let name: String let icon: String let room: String let colour: String let listName: String let listIcon: String init(name: String, icon: String, room: String? = nil, colour: String, listName: String? = nil, listIcon: String? = nil) { self.name = name self.icon = icon self.room = room ?? "None" self.colour = colour self.listName = listName ?? name self.listIcon = listIcon ?? icon+".circle.fill" } } // here's a few of my Course variables (there are lots more I've excluded) let MathsCourse = Course(name: "Maths", icon: "number", room: "FT5", colour: "Rose") let English6 = Course(name: "English", icon: "book.closed", room: "BT6", colour: "Lemon") let LunchPeriod = Course(name: "Lunch", icon: "fork.knife", room: "food", colour: "White") and I have designed a 'list view' of all the courses I have on whatever day it is. I used to define a different View for every course I defined but I merged the list data with the overall Course and replaced the Views with something that I should be able to call repeatedly and pass in a course to use, but unfortunately it's not working. (yes, I'm making a timetable app) This is the template for a 'list view' for a class: struct courseListView: View { var localcourse: Course var localtime: String var body: some View { HStack{ Image(systemName: localcourse.listIcon) .foregroundColor(Color(localcourse.colour)) .padding(.leading, 5) Text(localcourse.name) .bold() Spacer() Text(localtime) Text(roomOrBlank(course: localcourse)).bold().padding(.trailing, 5) } .padding(.bottom, 1) .background(currentCourse.name==localcourse.name ? Color(localcourse.colour).colorInvert(): nil) } } Then I should be able to programmatically work out what courses I have that day (I haven't scripted that bit yet), and compose a view containing all the courses: struct ListView: View { var body: some View { ScrollView { VStack(alignment: .leading) { courseListView(localcourse: MathsCourse, localtime: "10:00") // ^^^ note above line; I'll come back to this // the idea is I can repeat that for a bunch of courses: courseListView(localcourse: English6, localtime: "11:00") courseListView(localcourse: LunchPeriod, localtime: "12:00") } } } } Then be able to call all that in my @main: @main struct Timetaber_Watch_AppApp: App { var body: some Scene { WindowGroup { TabView{ HomeView() ListView() SettingsView() } .tabViewStyle(.carousel) .onAppear() { log() } } } } Unfortunately, each time I try to get a list view for a course, // if you need a reminder: courseListView(localcourse: MathsCourse, localtime: "10:00") ...even only calling it once causes my entire app to crash. Here's an excerpt from the crash report: Exception Type: EXC_BREAKPOINT (SIGTRAP) Exception Codes: 0x0000000000000001, 0x0000000180210194 Termination Reason: SIGNAL 5 Trace/BPT trap: 5 Terminating Process: exc handler [14932] Triggered by Thread: 0 Thread 0 Crashed:: Dispatch queue: com.apple.main-thread 0 libdispatch.dylib 0x180210194 _dispatch_once_wait.cold.1 + 28 1 libdispatch.dylib 0x1801db4f4 _dispatch_once_wait + 184 2 ??? 0x3400200d0 ??? 3 ??? 0x340020198 ??? 4 ... So... Anyone know what's happening?
3
0
265
Mar ’25
NSTextAttachment lagging in textkit 2
I have an attributedString with 100 NSTextAttachments(contains image of 400kb). When i scroll the textview, it is lagging, When i did the same in textkit 1, it is butter smooth. It can be because of how textkit 1 & 2 layout the elements. let attachment = NSTextAttachment() attachment.image = UIImage(named: "image2") let attachmentString = NSAttributedString(attachment: attachment) let mutableAttributedString = NSMutableAttributedString(attributedString: textView.attributedText) for _ in 0...100 { mutableAttributedString.append(NSAttributedString(string: "\n")) mutableAttributedString.append(attachmentString) } textView.attributedText = mutableAttributedString How to handle images in textkit 2 so that it feels smooth while scrolling textview?
1
0
442
Feb ’25
Lazy cell registration causes crash while dequeue the collectionview cell in collectionview
Cell Registration lazy var headerCell: UICollectionView.SupplementaryRegistration<UICollectionReusableView> = .init(elementKind: UICollectionView.elementKindSectionHeader) { supplementaryView, elementKind, indexPath in } and Cell Dequeue datasource.supplementaryViewProvider = { [weak self] collectionView, kind, indexPath in return collectionView.dequeueConfiguredReusableSupplementary(using: headerCell, for: indexPath) } I am registering a collectionview cell or collwctionview reusable view as lazy variable. It causes a crash like Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Attempted to dequeue a supplementary view using a registration that was created inside -collectionView:viewForSupplementaryElementOfKind:atIndexPath: or inside a UICollectionViewDiffableDataSource supplementary view provider. Creating a new registration each time a supplementary view is requested will prevent reuse and cause created supplementary views to remain inaccessible in memory for the lifetime of the collection view. Registrations should be created up front and reused. Registration: <UICollectionViewSupplementaryRegistration: 0x600001798a00>
2
0
309
Feb ’25
Why Actor-isolated property cannot be passed 'inout' to 'async' function call?
Considering below dummy codes: @MainActor var globalNumber = 0 @MainActor func increase(_ number: inout Int) async { // some async code excluded number += 1 } class Dummy: @unchecked Sendable { @MainActor var number: Int { get { globalNumber } set { globalNumber = newValue } } @MainActor func change() async { await increase(&number) //Actor-isolated property 'number' cannot be passed 'inout' to 'async' function call } } I'm not really trying to make an increasing function like that, this is just an example to make everything happen. As for why number is a computed property, this is to trigger the actor-isolated condition (otherwise, if the property is stored and is a value type, this condition will not be triggered). Under these conditions, in function change(), I got the error: Actor-isolated property 'number' cannot be passed 'inout' to 'async' function call. My question is: Why Actor-isolated property cannot be passed 'inout' to 'async' function call? What is the purpose of this design? If this were allowed, what problems might it cause?
0
0
377
Feb ’25
Persistent View Failure After Saving Edits in SwiftUI iOS App
Hello Apple Developer Community, I’m facing a recurring issue in my SwiftUI iOS app where a specific view fails to reload correctly after saving edits and navigating back to it. The failure happens consistently post-save, and I’m looking for insights from the community. 🛠 App Overview Purpose A SwiftUI app that manages user-created data, including images, text fields, and completion tracking. Tech Stack: SwiftUI, Swift 5.x MSAL for authentication Azure Cosmos DB (NoSQL) for backend data Azure Blob Storage for images Environment: Xcode 15.x iOS 17 (tested on iOS 18.2 simulator and iPhone 16 Pro) User Context: Users authenticate via MSAL. Data is fetched via Azure Functions, stored in Cosmos DB, and displayed dynamically. 🚨 Issue Description 🔁 Steps to Reproduce Open a SwiftUI view (e.g., a dashboard displaying a user’s saved data). Edit an item (e.g., update a name, upload a new image, modify completion progress). Save changes via an API call (sendDataToBackend). The view navigates back, but the image URL loses its SAS token. Navigate away (e.g., back to the home screen or another tab). Return to the view. ❌ Result The view crashes, displays blank, or fails to load updated data. SwiftUI refreshes text-based data correctly, but AsyncImage does not. Printing the image URL post-save shows that the SAS token (?sv=...) is missing. ❓ Question How can I properly reload AsyncImage after saving, without losing the SAS token? 🛠 What I’ve Tried ✅ Verified JSON Structure Debugged pre- and post-save JSON. Confirmed field names match the Codable model. ✅ Forced SwiftUI to Refresh Tried .id(UUID()) on NavigationStack: NavigationStack { ProjectDashboardView() .id(UUID()) // Forces reinit } Still fails intermittently. ✅ Forced AsyncImage to Reload Tried appending a UUID() to the image URL: AsyncImage(url: URL(string: "\(imageUrl)?cacheBust=\(UUID().uuidString)")) Still fails when URL query parameters (?sv=...) are trimmed. I’d greatly appreciate any insights, code snippets, or debugging suggestions! Let me know if more logs or sample code would help. Thanks in advance!
1
0
294
Mar ’25
CloudKit Sharing Issue: "Unknown client: ChoreOrganizer"
I'm experiencing a persistent issue with CloudKit sharing in my iOS application. When attempting to present a UICloudSharingController, I receive the error message "Unknown client: ChoreOrganizer" in the console. App Configuration Details: App Name: ChoreOrganizer Bundle ID: com.ProgressByBits.ChoreOrganizer CloudKit Container ID: iCloud.com.ProgressByBits.ChoreOrganizer Core Data Model Name: ChoreOrganizer.xcdatamodeld Core Data Entity: Chore Error Details: The error "Unknown client: ChoreOrganizer" occurs when I present the UICloudSharingController This happens only on the first attempt to share; subsequent attempts during the same app session don't show the error but sharing still doesn't work All my code executes successfully without errors until UICloudSharingController is presented Implementation Details: I'm using NSPersistentCloudKitContainer for Core Data synchronization and UICloudSharingController for sharing. My implementation creates a custom CloudKit zone, saves both a record and a CKShare in that zone, and then presents the sharing controller. Here's the relevant code: @MainActor func presentSharing(from viewController: UIViewController) async throws { // Create CloudKit container let container = CKContainer(identifier: containerIdentifier) let database = container.privateCloudDatabase // Define custom zone ID let zoneID = CKRecordZone.ID(zoneName: "SharedChores", ownerName: CKCurrentUserDefaultName) do { // Check if zone exists, create if necessary do { _ = try await database.recordZone(for: zoneID) } catch { let newZone = CKRecordZone(zoneID: zoneID) _ = try await database.save(newZone) } // Create record in custom zone let recordID = CKRecord.ID(recordName: "SharedChoresRoot", zoneID: zoneID) let rootRecord = CKRecord(recordType: "ChoreRoot", recordID: recordID) rootRecord["name"] = "Shared Chores Root" as CKRecordValue // Create share let share = CKShare(rootRecord: rootRecord) share[CKShare.SystemFieldKey.title] = "Shared Tasks" as CKRecordValue // Save both record and share in same operation let recordsToSave: [CKRecord] = [rootRecord, share] _ = try await database.modifyRecords(saving: recordsToSave, deleting: []) // Present sharing controller let sharingController = UICloudSharingController(share: share, container: container) sharingController.delegate = shareDelegate // Configure popover if let popover = sharingController.popoverPresentationController { popover.sourceView = viewController.view popover.sourceRect = CGRect( x: viewController.view.bounds.midX, y: viewController.view.bounds.midY, width: 1, height: 1 ) popover.permittedArrowDirections = [] } viewController.present(sharingController, animated: true) } catch { throw error } } Steps I've already tried: Verified correct bundle ID and container ID match in all places (code, entitlements file, Developer Portal) Added NSUbiquitousContainers configuration to Info.plist Ensured proper entitlements in the app Created and configured proper provisioning profiles Tried both default zone and custom zone for sharing Various ways of saving the record and share (separate operations, same operation) Cleaned build folder, deleted derived data, reinstalled the app Tried on both simulator and physical device Confirmed CloudKit container exists in CloudKit Dashboard with correct schema Verified iCloud is properly signed in on test devices Console Output: 1. Starting sharing process 2. Created CKContainer with ID: iCloud.com.ProgressByBits.ChoreOrganizer 3. Using zone: SharedChores 4. Checking if zone exists 5. Zone exists 7. Created record with ID: <CKRecordID: 0x3033ebd80; recordName=SharedChoresRoot, zoneID=SharedChores:__defaultOwner__> 8. Created share with ID: <CKRecordID: 0x3033ea920; recordName=Share-C4701F43-7591-4436-BBF4-6FA8AF3DF532, zoneID=SharedChores:__defaultOwner__> 9. About to save record and share 10. Records saved successfully 11. Creating UICloudSharingController 12. About to present UICloudSharingController 13. UICloudSharingController presented Unknown client: ChoreOrganizer Additional Information: When accessing the CloudKit Dashboard, I can see that data is being properly synced to the cloud, indicating that the basic CloudKit integration is working. The issue appears to be specific to the sharing functionality. I would greatly appreciate any insights or solutions to resolve this persistent "Unknown client" error. Thank you for your assistance.
5
0
661
Mar ’25
Command Line Tool Embedding in SwiftUI App
I have added 2 command line tools in my swiftUI app for macOS, it was working fine locally, but it gives error when i try to make archive of it. I am not sure about the reason, but it was related to sandboxing the command line tools, after this i have tried multiple solutions but i am unable to resolve this issue, how should i handle the helper command line tools
2
0
391
Feb ’25
Searchable list with binding causes indexOutOfRange crash on iOS 18 physical device
Hi folks, Unsure if I've implemented some sort of anti-pattern here, but any help or feedback would be great. I've created a minimal reproducible sample below that lets you filter a list of people and mark individuals as a favourite. When invoking the search function on a physical device running iOS 18.3.1, it crashes with Swift/ContiguousArrayBuffer.swift:675: Fatal error: Index out of range. It runs fine on iOS 17 (physical device) and also on the various simulators I've tried (iOS 18.0, iOS 18.2, iOS 18.3.1). If I remove the toggle binding, the crash doesn't occur (but I also can't update the toggles in the view model). I'm expecting to be able to filter the list without a crash occurring and retain the ability to have the toggle switches update the view model. Sample code is below. Thanks for your time 🙏! import SwiftUI struct Person { let name: String var isFavorite = false } @MainActor class ViewModel: ObservableObject { private let originalPeople: [Person] = [ .init(name: "Holly"), .init(name: "Josh"), .init(name: "Rhonda"), .init(name: "Ted") ] @Published var filteredPeople: [Person] = [] @Published var searchText: String = "" { didSet { if searchText.isEmpty { filteredPeople = originalPeople } else { filteredPeople = originalPeople.filter { $0.name.lowercased().contains(searchText.lowercased()) } } } } init() { self.filteredPeople = originalPeople } } struct ContentView: View { @ObservedObject var viewModel = ViewModel() var body: some View { NavigationStack { List { ForEach($viewModel.filteredPeople, id: \.name) { person in VStack(alignment: .leading) { Text(person.wrappedValue.name) Toggle("Favorite", isOn: person.isFavorite) } } } .navigationTitle("Contacts") } .searchable(text: $viewModel.searchText) } } #Preview { ContentView() }```
5
2
356
Feb ’25
Simple console display test - preview not working as expected
Just learning Swift and SwiftUI, having fun in Xcode. I have the following custom view defined, but when I try to test it, the information doesn't get updated as I expect. When I use the button defined INSIDE the custom view, the update works as expected. When I use the button defined in the Preview body, it doesn't. The "lines" variable of the custom view appears not to be updated in that case. I know I'm missing something fundamental here about either view state binding or the preview environment, but I'm stumped. Any ideas? import SwiftUI struct ConsoleView: View { var maxLines : Int = 26 private enum someIDs { case textID} @State private var numLines : Int = 0 @State var lines = "a\nb\nc\n" var body: some View { VStack(alignment: .leading, spacing:0 ) { ScrollViewReader { proxy in ScrollView { Button("Scroll to Bottom") { withAnimation { proxy.scrollTo(someIDs.textID, anchor: .bottom) } } Text(lines) .id(someIDs.textID) .multilineTextAlignment(.leading) .frame(maxWidth: .infinity, alignment: .bottomLeading) .padding() .onChange ( of: lines) { withAnimation { proxy.scrollTo( someIDs.textID, anchor: .bottom) } } } Button("Add more") { writeln("More") //writeln(response) } } } } private func clipIfNeeded () { if (numLines>=maxLines) { if let i = lines.firstIndex(of: "\n") { lines = String(lines.suffix( from: lines.index(after:i))) } } } func writeln ( _ newText : String) { print("adding '\(newText)' to lines") //clipIfNeeded() write( newText ) write("\n") numLines += 1 print(lines) } func write ( _ newText : String) { lines += newText } } #Preview { VStack() { var myConsole = ConsoleView(lines: "x\ny\nz\n") myConsole Button("Add stuff") { myConsole.writeln("Stuff") } } }
2
0
347
Feb ’25
How to reduce CMSampleBuffer volume
Hello, Basically, I am reading and writing an asset. To simplify, I am just reading the asset and rewriting it into an output video without any modifications. However, I want to add a fade-out effect to the last three seconds of the output video. I don’t know how to do this. So far, before adding the CMSampleBuffer to the output video, I tried reducing its volume using an extension on CMSampleBuffer. In the extension, I passed 0.4 for testing, aiming to reduce the video's overall volume by 60%. My question is: How can I directly adjust the volume of a CMSampleBuffer? Here is the extension: extension CMSampleBuffer { func adjustVolume(by factor: Float) -> CMSampleBuffer? { guard let blockBuffer = CMSampleBufferGetDataBuffer(self) else { return nil } var length = 0 var dataPointer: UnsafeMutablePointer<Int8>? guard CMBlockBufferGetDataPointer(blockBuffer, atOffset: 0, lengthAtOffsetOut: nil, totalLengthOut: &length, dataPointerOut: &dataPointer) == kCMBlockBufferNoErr else { return nil } guard let dataPointer = dataPointer else { return nil } let sampleCount = length / MemoryLayout<Int16>.size dataPointer.withMemoryRebound(to: Int16.self, capacity: sampleCount) { pointer in for i in 0..<sampleCount { let sample = Float(pointer[i]) pointer[i] = Int16(sample * factor) } } return self } }
4
0
366
May ’25
.fileImporter not working on iPhone
I've been running into an issue using .fileImporter in SwiftUI already for a year. On iPhone simulator, Mac Catalyst and real iPad it works as expected, but when it comes to the test on a real iPhone, the picker just won't let you select files. It's not the permission issue, the sheet won't close at all and the callback isn't called. At the same time, if you use UIKits DocumentPickerViewController, everything starts working as expected, on Mac Catalyst/Simulator/iPad as well as on a real iPhone. Steps to reproduce: Create a new Xcode project using SwiftUI. Paste following code: import SwiftUI struct ContentView: View { @State var sShowing = false @State var uShowing = false @State var showAlert = false @State var alertText = "" var body: some View { VStack { VStack { Button("Test SWIFTUI") { sShowing = true } } .fileImporter(isPresented: $sShowing, allowedContentTypes: [.item]) {result in alertText = String(describing: result) showAlert = true } VStack { Button("Test UIKIT") { uShowing = true } } .sheet(isPresented: $uShowing) { DocumentPicker(contentTypes: [.item]) {url in alertText = String(describing: url) showAlert = true } } .padding(.top, 50) } .padding() .alert(isPresented: $showAlert) { Alert(title: Text("Result"), message: Text(alertText)) } } } DocumentPicker.swift: import SwiftUI import UniformTypeIdentifiers struct DocumentPicker: UIViewControllerRepresentable { let contentTypes: [UTType] let onPicked: (URL) -> Void func makeCoordinator() -> Coordinator { Coordinator(self) } func makeUIViewController(context: Context) -> UIDocumentPickerViewController { let documentPicker = UIDocumentPickerViewController(forOpeningContentTypes: contentTypes, asCopy: true) documentPicker.delegate = context.coordinator documentPicker.modalPresentationStyle = .formSheet return documentPicker } func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: Context) {} class Coordinator: NSObject, UIDocumentPickerDelegate { var parent: DocumentPicker init(_ parent: DocumentPicker) { self.parent = parent } func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) { print("Success!", urls) guard let url = urls.first else { return } parent.onPicked(url) } func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) { print("Picker was cancelled") } } } Run the project on Mac Catalyst to confirm it working. Try it out on a real iPhone. For some reason, I can't attach a video, so I can only show a screenshot
1
0
389
Feb ’25
Is Metal usable from Swift 6?
Hello ladies and gentlemen, I'm writing a simple renderer on the main actor using Metal and Swift 6. I am at the stage now where I want to create a render pipeline state using asynchronous API: @MainActor class Renderer { let opaqueMeshRPS: MTLRenderPipelineState init(/*...*/) async throws { let descriptor = MTLRenderPipelineDescriptor() // ... opaqueMeshRPS = try await device.makeRenderPipelineState(descriptor: descriptor) } } I get a compilation error if try to use the asynchronous version of the makeRenderPipelineState method: Non-sendable type 'any MTLRenderPipelineState' returned by implicitly asynchronous call to nonisolated function cannot cross actor boundary Which is understandable, since MTLRenderPipelineState is not Sendable. But it looks like no matter where or how I try to access this method, I just can't do it - you have this API, but you can't use it, you can only use the synchronous versions. Am I missing something or is Metal just not usable with Swift 6 right now?
1
0
569
Mar ’25