I am trying out the new AttributedString binding with SwiftUI’s TextEditor in iOS26. I need to save this to a Core Data database. Core Data has no AttributedString type, so I set the type of the field to “Transformable”, give it a custom class of NSAttributedString, and set the transformer to NSSecureUnarchiveFromData
When I try to save, I first convert the Swift AttributedString to NSAttributedString, and then save the context. Unfortunately I get this error when saving the context, and the save isn't persisted:
CoreData: error: SQLCore dispatchRequest: exception handling request: <NSSQLSaveChangesRequestContext: 0x600003721140> , <shared NSSecureUnarchiveFromData transformer> threw while encoding a value. with userInfo of (null)
Here's the code that tries to save the attributed string:
struct AttributedDetailView: View {
@ObservedObject var item: Item
@State private var notesText = AttributedString()
var body: some View {
VStack {
TextEditor(text: $notesText)
.padding()
.onChange(of: notesText) {
item.attributedString = NSAttributedString(notesText)
}
}
.onAppear {
if let nsattributed = item.attributedString {
notesText = AttributedString(nsattributed)
} else {
notesText = ""
}
}
.task {
item.attributedString = NSAttributedString(notesText)
do {
try item.managedObjectContext?.save()
} catch {
print("core data save error = \(error)")
}
}
}
}
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Created
I just adding a way to donate my app's data to Core Spotlight using CSSearchableIndex, but I'm finding that spotlight is only searching for the title of the CSSearchableItem I create. I know the index is working, because it always finds the item through the title property, but nothing else.
This is how I'm creating the CSSearchableItem:
- (CSSearchableItem *) createSearchableItem {
CSSearchableItemAttributeSet* attributeSet = [[CSSearchableItemAttributeSet alloc] initWithContentType: UTTypeText];
attributeSet.title = [self titleForIndex];
attributeSet.displayName = [self titleForIndex];
attributeSet.contentDescription = [self contentDescriptionForIndex];
attributeSet.thumbnailData = [self thumbnailDataForIndex];
attributeSet.textContent = [self contentDescriptionForIndex];
CSSearchableItem *item = [[CSSearchableItem alloc] initWithUniqueIdentifier: [self referenceURLString] domainIdentifier:@"com.cjournal.cjournal-Logs" attributeSet:attributeSet];
item.expirationDate = [NSDate distantFuture];
return item;
}
There's a lot of confusing tips around which say specifying the 'textContent' should work, and/or setting the displayName is essential, but none of these are working.
Is there something I'm missing with my setup?
Thanks.
I am trying out the new AttributedString binding with SwiftUI’s TextEditor in iOS26. I need to save this to a Core Data database. Core Data has no AttributedString type, so I set the type of the field to “Transformable”, give it a custom class of NSAttributedString, and set the transformer to NSSecureUnarchiveFromData
When I try to save, I first convert the Swift AttributedString to NSAttributedString, and then save the context. Unfortunately I get this error when saving the context, and the save isn't persisted:
CoreData: error: SQLCore dispatchRequest: exception handling request: <NSSQLSaveChangesRequestContext: 0x600003721140> , <shared NSSecureUnarchiveFromData transformer> threw while encoding a value. with userInfo of (null)
Here's the code that tries to save the attributed string:
struct AttributedDetailView: View {
@ObservedObject var item: Item
@State private var notesText = AttributedString()
var body: some View {
VStack {
TextEditor(text: $notesText)
.padding()
.onChange(of: notesText) {
item.attributedString = NSAttributedString(notesText)
}
}
.onAppear {
if let nsattributed = item.attributedString {
notesText = AttributedString(nsattributed)
} else {
notesText = ""
}
}
.task {
item.attributedString = NSAttributedString(notesText)
do {
try item.managedObjectContext?.save()
} catch {
print("core data save error = \(error)")
}
}
}
}
This is the attribute setup in the Core Data model editor:
Is there a workaround for this?
I filed FB17943846 if someone can take a look.
Thanks.
Hi,
I have an app that uses Core Data to store user information and display it in various views. I want to know if it's possible to easily integrate this setup with FoundationModels to make it easier for the user to query and manipulate the information, and if so, how would I go about it? Can the model be pointed to the database schema file and the SQLite file sitting in the user's app group container to parse out the information needed? And/or should the NSManagedObjects be made @Generable for better output? Any guidance about this would be useful.
With iPadOS26, if I create a UITabBar, and use that to switch between views, the selected state never updates. I created this simple UIViewController to demonstrate the issue:
class SimpleTabBarController: UIViewController, UITabBarDelegate {
let tabBar = UITabBar()
let redItem = UITabBarItem(title: "Red", image: nil, tag: 0)
let blueItem = UITabBarItem(title: "Blue", image: nil, tag: 1)
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
tabBar.items = [redItem, blueItem]
tabBar.selectedItem = redItem
tabBar.delegate = self
tabBar.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(tabBar)
NSLayoutConstraint.activate([
tabBar.leadingAnchor.constraint(equalTo: view.leadingAnchor),
tabBar.trailingAnchor.constraint(equalTo: view.trailingAnchor),
tabBar.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
])
updateBackground(for: redItem)
}
func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
updateBackground(for: item)
}
private func updateBackground(for item: UITabBarItem) {
switch item.tag {
case 0: view.backgroundColor = .systemRed
case 1: view.backgroundColor = .systemBlue
default: view.backgroundColor = .white
}
}
}
The tabBar didSelect item method is called, and the background color gets updated as expected, but the selected state of the UITabBar stays the same.
I files a feedback for a related issue: FB17841678
I just downloaded Xcode26, and am trying to download the new simulator to be able to run and test my app. But the downloads folder just shows that it's stuck on "Fetching download information ..." even 15 minutes after it started. I tried restarting Xcode but didn't help. Internet connection is good. Any tips to get it working?
I am working with a simple SwiftUI List and I want to enable functionality that allows files and images to be dropped onto the List from outside the app. There is an onInsert modifier with List that allows for this, but I found that it works on macOS, but not when running the same view on iOS.
I have sample code that I can't seem to post on this forum because it keeps giving me a validation error about "This post contains sensitive language". Maybe this will work:
Code to reproduce issue
Is there anything I can do to make this work on iOS?
Hi,
I have an existing Mac app on the App Store with a couple of widgets as part of the app. I want to now add a new widget to the WidgetBundle. When I build the updated app with Xcode, and then run the updated app, the widgets list doesn't seem to get updated in Notification Center or in the WidgetKit Simulator.
I do have the App Store version installed in the /Applications folder as well, so there might be some conflict. What's the trick to getting the widgets list to run the debug version?
I have a SwiftUI List (on macOS) where I want to display a few TextFields in each row, and observe how the focus changes as an individual text field is selected or unselected. This seems to work fine if I just have the List display a pure TextField in each row, but if I embed the TextField inside a Button view, the focus change notifications stop working. I want the 'button' functionality so that the user can tap anywhere on the row and have the text field activated, instead of tapping exactly on the text field boundary.
Here is some code to demonstrate the problem. In the List if you have RowView uncommented out (1), then the focus change notifications work. If you comment that out and uncomment the RowViewWithButton (2), then the button functionality works, but I can't get focus change notifications anymore.
Here is the code to reproduce the issue. Interestingly, when I test this on iOS, it works fine in both cases. But I need the solution for macOS.
import SwiftUI
// test on macOS target
struct ContentView: View {
@State private var textFields = Array(repeating: "", count: 4)
@FocusState private var focusedField: Int?
var body: some View {
List(0..<4, id: \.self) { index in
// 1. works with focus notification changes
RowView(index: index, text: $textFields[index], focusedField: $focusedField)
// 2. button works, but no focus notifications on text field
//RowViewWithButton(index: index, text: $textFields[index], focusedField: $focusedField)
}
}
}
struct RowView: View {
let index: Int
@Binding var text: String
@FocusState.Binding var focusedField: Int?
var body: some View {
HStack {
Text("Row \(index + 1):")
TextField("", text: $text)
.multilineTextAlignment(.leading)
.focused($focusedField, equals: index)
}
.onChange(of: focusedField) { newFocus in
if newFocus == index {
print("TextField \(index) is in focus")
} else {
print("TextField \(index) lost focus")
}
}
.padding(.vertical, 4)
}
}
struct RowViewWithButton: View {
let index: Int
@Binding var text: String
@FocusState.Binding var focusedField: Int?
var body: some View {
Button (action: {
print("RowView - button selected at index \(index)")
focusedField = index
}) {
HStack {
Text("Row \(index + 1):")
TextField("", text: $text)
.multilineTextAlignment(.leading)
.focused($focusedField, equals: index)
}
.onChange(of: focusedField) { newFocus in
if newFocus == index {
print("TextField \(index) is in focus")
} else {
print("TextField \(index) lost focus")
}
}
.foregroundColor(.primary)
}
.buttonStyle(BorderlessButtonStyle())
.padding(.vertical, 4)
}
}
#Preview {
ContentView()
.frame(width: 320, height: 250)
}
Hi,
I have noticed a major change to a SwiftUI API behavior in iOS18.4beta1 which breaks my app's functionality, and I've started hearing from users running the new beta that the app doesn't correctly work for them anymore.
The problem is with views that contain a List with multiple-selection, and the contextMenu API applied with the ‘primaryAction’ callback that is triggered when the user taps on a row. Previously, if the user tapped on a row, this callback was triggered with the 'selectedItems' showing the tapped item. With iOS18.4beta, the same callback is triggered with ‘selectedItems’ being empty.
I have the code to demonstrate the problem:
struct ListSelectionTestView: View {
@State private var items: [TimedItem] = [
TimedItem(number: 1, timestamp: "2024-11-20 10:00"),
TimedItem(number: 2, timestamp: "2024-11-20 11:00"),
TimedItem(number: 3, timestamp: "2024-11-20 12:00")
]
@State var selectedItems = Set<TimedItem.ID>()
var body: some View {
NavigationStack {
List(selection: $selectedItems) {
ForEach(items) { item in
Text("Item \(item.number) - \(item.timestamp)")
}
}
.contextMenu(forSelectionType: TimedItem.ID.self, menu: {_ in
Button(action: {
print("button called - count = \(selectedItems.count)")
}) {
Label("Add Item", systemImage: "square.and.pencil")
}
}, primaryAction: {_ in
print("primaryAction called - count = \(selectedItems.count)")
})
}
}
}
struct TimedItem: Identifiable {
let id = UUID()
let number: Int
let timestamp: String
}
#Preview {
ListSelectionTestView()
}
Running the same code on iOS18.2, and tapping on a row will print this to the console:
primaryAction called - count = 1
Running the same code on iOS18.4 beta1, and tapping on a row will print this to the console:
primaryAction called - count = 0
So users who were previously selecting an item from the row, and then seeing expected behavior with the selected item, will now suddenly tap on a row and see nothing. My app's functionality relies on the user selecting an item from a list to see another detailed view with the selected item's contents, and it doesn't work anymore.
This is a major regression issue. Please confirm and let me know. I have filed a feedback: FB16593120
I am trying to support dragging out a 'file' object from my app into Finder, on macOS. I have my object conform to Transferable and the files are saved on disk locally, so I just want to pass it the URL. This works fine when dragging out to other apps, like Notes or Mail, but not in Finder. I setup a ProxyRepresentation as well, as suggested by another thread, but it doesn't seem to help. Is there any other setup I need to do in the Xcode project file for it to work, or is there something else that I'm missing?
@available(iOSApplicationExtension 17.0, macOSApplicationExtension 14.0, *)
extension FileAttachments: Transferable {
public static var transferRepresentation: some TransferRepresentation {
FileRepresentation(exportedContentType: UTType.content) { content in
SentTransferredFile(content.fullFileURL(), allowAccessingOriginalFile: false)
}
.exportingCondition { file in
if let fileUTI = UTType(filenameExtension: file.fullFileURL().pathExtension), let fileURL = file.fullFileURL() {
print("FileAttachments: FileRepresentation exportingCondition fileUTI: \(fileUTI) for file: \(fileURL)")
return fileUTI.conforms(to: UTType.content)
}
return false
}
.suggestedFileName{$0.fileRenamedName}
ProxyRepresentation { file in
if let fileURL = file.fullFileURL() {
print("FileAttachments: ProxyRepresentation returning file")
return fileURL
}
return file.fullFileURL()!
}
}
}
Hi,
On macOS, there seems to be a NSTableViewDiffableDataSource and an NSCollectionViewDiffableDataSource, but there seems to be nothing for NSOutlineView. Is it possible to somehow use NSTableViewDiffableDataSource with NSOutlineView that I'm missing?
If not, is it possible to use NSTableView with NSTableViewDiffableDataSource to show a 'table' with section headers?
Hi,
With UIDocumentPickerViewController, there is a directoryURL property that says we can use to 'specify the starting directory for the document picker'. But it's not clear how to get the directory of a folder in iCloud Drive / Files app. How can I get the 'root' directory for a user's iCloud Drive or Dropbox folder, or the Downloads folder on their device, that I could pass to this directoryURL to make it easier for the user to pick their files?
Thanks.
Hi,
In my app, I have an option to remove a contact from a contact group (using the Contacts framework), and it's been working fine till recently users of the macOS version reported that it's not working. I have been using the CNSaveRequest removeMember(contact, from: group) API. The same API works fine on iOS. I'm not sure when it started but it seems to be affecting macOS14.6 as well as 15.1.
I was able to reproduce it in a small test project as well, and have the same experience (the API works on iOS but not on macOS), so it definitely seems like a problem with the framework. Can someone confirm this, and/or suggest a workaround?
Here's the code I run to test it out ...a simple SwiftUI view that has 4 buttons:
Create contact and group
Add contact to group
Remove contact from group
(optional) cleanup by deleting contact and group
It's the 3rd step that seems to fail on macOS, but works fine on iOS.
Here's the code to test it out:
struct ContentView: View {
let contactsModel = ContactsStoreModel()
var body: some View {
VStack (alignment: .center, spacing: 15){
Button ("1. Add Contact And Group") {
print("add contact button pressed")
contactsModel.addTestContact()
if let _ = contactsModel.createdContact {
print("created contact success")
}
}
Button ("2. Add Contact To Group") {
print("add to group button pressed")
contactsModel.addContactToGroup()
}
Button ("3. Remove Contact From Group") {
print("remove from group button pressed")
contactsModel.removeContactFromGroup()
}
Button ("4. Delete Contact and Group") {
print("remove from group button pressed")
contactsModel.deleteContactAndGroup()
}
}
.padding()
}
}
#Preview {
ContentView()
}
@available(iOS 13.0, *)
@objc final class ContactsStoreModel: NSObject, ObservableObject {
let contactStore = CNContactStore()
var createdContact : CNContact?
var createdGroup : CNGroup?
public func addTestContact() {
let storeContainer = contactStore.defaultContainerIdentifier()
let contact = CNMutableContact()
contact.givenName = "Testing"
contact.familyName = "User"
contact.phoneNumbers = [CNLabeledValue(label: "Cell", value: CNPhoneNumber(stringValue: "1234567890"))]
let group = CNMutableGroup()
group.name = "Testing Group"
print("create contact id = \(contact.identifier)")
print("create group id = \(group.identifier)")
do {
let saveRequest = CNSaveRequest()
saveRequest.transactionAuthor = "TestApp"
saveRequest.add(contact, toContainerWithIdentifier: storeContainer)
saveRequest.add(group, toContainerWithIdentifier: storeContainer)
try contactStore.execute(saveRequest)
createdContact = contact
createdGroup = group
} catch {
print("error in store execute = \(error)")
}
}
public func addContactToGroup() {
if let contact = createdContact, let group = createdGroup {
do {
let saveRequest = CNSaveRequest()
saveRequest.transactionAuthor = "TestApp"
saveRequest.addMember(contact, to: group)
try contactStore.execute(saveRequest)
}
catch {
print("error in store execute = \(error)")
}
}
}
public func removeContactFromGroup() {
if let contact = createdContact, let group = createdGroup {
do {
let saveRequest = CNSaveRequest()
saveRequest.transactionAuthor = "TestApp"
saveRequest.removeMember(contact, from: group)
try contactStore.execute(saveRequest)
}
catch {
print("error in store execute = \(error)")
}
}
}
public func addGroupAndContact() {
let storeContainer = contactStore.defaultContainerIdentifier()
let group = CNMutableGroup()
group.name = "Test Group"
print("create group id = \(group.identifier)")
if let contact = createdContact {
do {
let saveRequest = CNSaveRequest()
saveRequest.transactionAuthor = "TestApp"
saveRequest.add(group, toContainerWithIdentifier: storeContainer)
saveRequest.addMember(contact, to: group)
try contactStore.execute(saveRequest)
createdGroup = group
} catch {
print("error in store execute = \(error)")
}
}
}
public func deleteContactAndGroup() {
if let contact = createdContact, let group = createdGroup {
do {
let mutableGroup = group.mutableCopy() as! CNMutableGroup
let mutableContact = contact.mutableCopy() as! CNMutableContact
let saveRequest = CNSaveRequest()
saveRequest.transactionAuthor = "TestApp"
saveRequest.delete(mutableContact)
saveRequest.delete(mutableGroup)
try contactStore.execute(saveRequest)
}
catch {
print("error in deleting store execute = \(error)")
}
}
}
}
Hi,
A new "Featuring Nominations" workflow was introduced at WWDC24, to help nominate our apps to be potentially featured on the App Store. When is that expected to arrive? The WWDC video didn't mention any expected release dates. Would love to be able to use this for an upcoming update.
Thanks.