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)")
}
}
}
}
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Hi,
I have been using Claude with Xcode 26.1.1 and it was working fine till a couple of days ago, when it started giving me an error message on every query:
"Message from Anthropic: This request would exceed your account's rate limit. Please try again later."
I am on the Pro model, and I can use the Claude.ai website just fine. The usage limits on the website show I've used only 11% of the weekly limit, and 4% of the 'current session'. So I'm wondering if this is an Xcode bug / issue, and if there is a workaround.
I have restarted Xcode, restarted the Mac, logged out of Anthropic and logged back in, tried Xcode 26.2 beta as well, but no luck.
Topic:
Developer Tools & Services
SubTopic:
Xcode
Hi,
I have been working with an implementation of MapKit which show custom annotations with a detailCalloutAccessoryView built using SwiftUI. This has been working fine for many years, but starting with macOS Tahoe, somehow the SwiftUI buttons in this view have stopped being tappable.
I have reproduced the issue in the code below ... same code works fine in macOS14 and macOS15 now doesn't work correctly in macOS26:
import Cocoa
import MapKit
import SwiftUI
class ViewController: NSViewController {
private var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
setupMapView()
}
private func setupMapView() {
// Create and configure the map view
mapView = MKMapView()
mapView.translatesAutoresizingMaskIntoConstraints = false
mapView.delegate = self
view.addSubview(mapView)
// Pin the map to all edges of the view
NSLayoutConstraint.activate([
mapView.topAnchor.constraint(equalTo: view.topAnchor),
mapView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
mapView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
mapView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
// Create an annotation for San Francisco
let sanFranciscoCoordinate = CLLocationCoordinate2D(latitude: 37.7749, longitude: -122.4194)
let annotation = MKPointAnnotation()
annotation.coordinate = sanFranciscoCoordinate
annotation.title = "San Francisco"
annotation.subtitle = "The City by the Bay"
// Add the annotation to the map
mapView.addAnnotation(annotation)
// Center the map on San Francisco
let region = MKCoordinateRegion(center: sanFranciscoCoordinate,
latitudinalMeters: 5000,
longitudinalMeters: 5000)
mapView.setRegion(region, animated: false)
}
}
// MARK: - MKMapViewDelegate
extension ViewController: MKMapViewDelegate {
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let identifier = "CustomAnnotation"
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKMarkerAnnotationView
if annotationView == nil {
annotationView = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: identifier)
annotationView?.canShowCallout = true
// Create the SwiftUI view for the callout
let calloutView = CalloutContentView()
let hostingView = NSHostingView(rootView: calloutView)
hostingView.frame = NSRect(x: 0, y: 0, width: 200, height: 100)
// Set the SwiftUI view as the detail callout accessory
annotationView?.detailCalloutAccessoryView = hostingView
} else {
annotationView?.annotation = annotation
}
return annotationView
}
}
// MARK: - SwiftUI Callout View
struct CalloutContentView: View {
var body: some View {
VStack(spacing: 12) {
Text("Welcome to San Francisco!")
.font(.headline)
.multilineTextAlignment(.center)
HStack(spacing: 12) {
Button(action: {
print("Directions button tapped")
}) {
Label("Directions", systemImage: "arrow.triangle.turn.up.right.circle.fill")
.font(.caption)
}
.buttonStyle(.borderedProminent)
Button(action: {
print("Info button tapped")
}) {
Label("Info", systemImage: "info.circle.fill")
.font(.caption)
}
.buttonStyle(.bordered)
}
}
.padding()
.frame(width: 200)
}
}
I've looked at other problems with Map and onTap handlers not getting called, but this is a SwiftUI view inside an AppKit MapKit annotation's callout view.
Any idea of how to handle this?
Hi,
I'm running Xcode version 26.0.1 (17A400). Every time I restart Xcode, it seems to not recognize my Claude login anymore, and I have to go through the whole authentication flow again. It's quite annoying. Does anyone have a solution for it?
Topic:
Developer Tools & Services
SubTopic:
Xcode
Hi,
Ever since I updated to macOS Tahoe and started using Xcode 26 daily, I've run into an issue where it gets stuck very frequently when launching and running my app in the simulator. It happens with the main app target as well as when running unit tests. If I restart Xcode and the simulator app, it works fine again for a while, but after some use, it goes back to the same situation. In Activity Monitor, Xcode ends up at 1000% CPU utilization for a minute or more, basically rendering the simulator and the debugger stuck. If I untick the "Debug Executable" option in the scheme editor, it works fine as well.
Anyone else run into the same situation, or are there any tips I can follow to fix this issue? It makes it really tedious to make changes and then be stalled for a minute or more to see the app run. I've restarted the Mac, erased the booted simulator as well. I'm on a MacBook Pro M4 Pro. Everything used to run fine before macOS Tahoe / Xcode 26 on my main device. In fact, I used to run macOS Tahoe / Xcode 26 beta versions on a separate partition without any problems.
In my UIKit app, in my view controller, I have a toolbar at the bottom of the screen and a UITextView, and I need to get the size of the toolbar to calculate the correct keyboard intersection, and change my text view layout so that the text doesn't get obscured when the keyboard is shown on screen. It's been working fine till now, but with iOS26, I am running into an issue, because the toolbar size is completely different.
For this code:
NSInteger offset = (self.navigationController.isToolbarHidden == NO)? (self.navigationController.toolbar.frame.size.height): 0;
iOS18 returns '49'
iOS26 returns ''812'.
This obviously throws off the calculations for keyboard avoidance.
Is there a way to overcome this, other than ignoring or hard-coding toolbar height?
Topic:
UI Frameworks
SubTopic:
UIKit
Hi,
I am setting up the iPadOS26 Menu Bar, and it comes with some existing menu items that don't make sense for my app. For example, under "File" menu, there are options for New Window, Duplicate, Move, Rename and Export that I would like to remove (which keeping the Close Window option).
What's the best way to do this?
Topic:
UI Frameworks
SubTopic:
UIKit
Hi,
When I have a UITextView displayed on screen and in focus, the iPad keyboard shows buttons to Bold, Italics and Underline text (since it supports attributed text), and also a 'formatting' button that allows the user to change the font, color and size of the text, as well as justify text and add numbered lists and bullet points.
Is there any way to disable or remove this 'formatting' button? My app doesn't support saving these options (other than bold, italics and underline), so it confuses users to see this option.
Thanks.
Topic:
UI Frameworks
SubTopic:
UIKit
I have a strange issue for iOS26. I have a UITabBarController at the root view of the app, but on certain actions, I want to hide it temporarily, and then have some options where the user can press a button which display some options using UIAlertController. It used to work fine before, but with iOS26, when the UIAlertController is presented, the tab bar (which is hidden by setting the ‘frame’) suddenly pops back into view automatically, when I don't want it to.
Here's an example that reproduces the issue:
class TestTableViewController: UITableViewController {
private var isEditMode: Bool = false
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Change", style: .plain, target: self, action: #selector(changeMode))
}
@objc func changeMode() {
print("change mode called")
if isEditMode == false {
isEditMode = true
// hide tab bar
setEditingBarVisible(true, animated: true)
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Action", style: .plain, target: self, action: #selector(showActionsList))
} else {
isEditMode = false
// show tab bar
setEditingBarVisible(false, animated: true)
self.navigationItem.rightBarButtonItem = nil
}
}
@objc func showActionsList() {
let alert = UIAlertController(title: "Action", message: "showing message", preferredStyle: .actionSheet)
alert.addAction(UIAlertAction.init(title: "Cancel", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
}
@objc func setEditingBarVisible(_ visible: Bool, animated: Bool) {
guard let tabBar = tabBarController?.tabBar else {
return
}
let performChanges = {
// Slide the tab bar off/on screen by adjusting its frame’s y.
// This is safe because UITabBar is frame-managed, not Auto Layout constrained.
var frame = tabBar.frame
let height = frame.size.height
if visible {
// push it down if not already
if frame.origin.y < self.view.bounds.height {
frame.origin.y = self.view.bounds.height + self.view.safeAreaInsets.bottom
}
// Give our content its full height back (remove bottom safe-area padding that tab bar created)
self.additionalSafeAreaInsets.bottom = 0
} else {
// bring it back to its normal spot
frame.origin.y = self.view.bounds.height - height
// Re-apply bottom safe-area so content clears the tab bar again
self.additionalSafeAreaInsets.bottom = height
}
tabBar.frame = frame
// Ensure layout updates during animation
self.tabBarController?.view.layoutIfNeeded()
self.view.layoutIfNeeded()
}
if animated {
UIView.animate(withDuration: 0.28, delay: 0, options: [.curveEaseInOut]) {
performChanges()
}
} else {
performChanges()
}
}
}
I have a bar button called 'Change', and selecting it should hide/show the UITabBar at the bottom, and show/hide a different bar button called 'Action'. Selecting the 'Action' button shows an alert.
With iOS26, with the tab bar moved out of view, when the 'Action' button is called, the alert shows but the tab bar automatically moves into view as well.
Is this a known issue? Any workaround for it?
I filed FB19954757 just in case.
Topic:
UI Frameworks
SubTopic:
UIKit
I am trying out iOS26 with my existing app. I have a UITabBarController which is set to the main window's rootViewController, and I setup my UITabBar viewControllers programmatically. The first tab's root view has a UITableView with 100s of rows. When I build and run with the new Xcode, the app has the iOS26 look, but the table view doesn't seem to scroll behind the tab bar. The tab bar seems to have a hard edge and the content doesn't show through behind that.
I have tried setting up the UITabBarController with the UITab items from iOS18 as well, but that doesn't help either.
If I build a new project using the Xcode template, with storyboards, it works as expected and table view content shows through the UITabBar.
What could be causing this? Is there something I need to configure to get the correct effect in iOS26?
--
Figure it out: I needed to pin the bottomAnchor of the view controller to view's bottomAnchor (not safeAreaLayoutGuide.bottomAnchor)
Topic:
UI Frameworks
SubTopic:
UIKit
Hi,
Is it possible to use the iOS26 Liquid Glass icon on iOS 26 (built with Icon Composer), and use the old icon on iOS18 devices? I imported the icon file into my Xcode project and it seems to use the new icon on iOS18 (and earlier) devices as well.
Thanks.
Hi,
I am trying to implement the UIMainMenuSystem for showing the menu bar in my iPad app in iOS26. I would like to be able to disable some elements when a particular UIViewController is displayed on the screen, and I can't figure out the best way to do this. I tried overriding the 'validateCommand' method in my view controller, but it doesn't seem to invoke the validation for menu items that are in the main menu.
Any tips on how to do this?
I'm using the #Playground macro in Xcode 26.0, running on macOS 26.0. I can get the basics working, but I don't understand how it hooks into the rest of the app, like the App Delete or the Core Data stack. Do we have to create a new Core Data stack, like for SwiftUI Previews, or can it hook into the stack from the main app (if so, how)?
I'm trying to use the new #Playground feature in Xcode, but it keeps crashing in the canvas. I am testing on Xcode 26.0 beta 4, on both macOS 15 and macOS26 beta 4. How do I figure out what's going on?
I also have a few SwiftUI previews in my project, which also crashes if I try to preview them. They're not in any active tab right now in Xcode. But the #Playground feature still doesn't work.
I also don't get a crash when working on a #Playground in a different project.
I've tried cleaning out Derived Data and restarting the Mac / Xcode, all with no avail. How do I track down what's causing this? Do previews and playground run on the same engine?
System Integrity Protection: enabled
Triggered by Thread: 0
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Termination Reason: Namespace OBJC, Code 1,
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x100634ad0 __abort_with_payload + 8
1 libsystem_kernel.dylib 0x100659dc0 abort_with_payload_wrapper_internal + 100
2 libsystem_kernel.dylib 0x100659d5c abort_with_reason + 28
3 libobjc.A.dylib 0x18009bd08 _objc_fatalv(unsigned long long, unsigned long long, char const*, char*) + 112
4 libobjc.A.dylib 0x18009bc98 _objc_fatal(char const*, ...) + 28
5 libobjc.A.dylib 0x18008be14 lookUpImpOrForward + 580
6 libobjc.A.dylib 0x180072f00 _objc_msgSend_uncached + 64
7 ??? 0x340a44048 ???
8 CJournal 0x1001c54c4 __debug_blank_executor_run_user_entry_point + 152
9 PreviewsInjection 0x241623bf4 0x2415ff000 + 150516
10 PreviewsInjection 0x24162481c 0x2415ff000 + 153628
11 PreviewsInjection 0x241624740 __previews_injection_run_user_entrypoint + 12
12 XOJITExecutor 0x25543ad48 __xojit_executor_run_program_wrapper + 1460
13 XOJITExecutor 0x25543725c 0x255435000 + 8796
14 PreviewsInjection 0x24162468c 0x2415ff000 + 153228
15 CJournal 0x1001c4c7c __debug_blank_executor_main + 996
16 ??? 0x1003e13d0 ???
17 dyld 0x100218924 start + 6400
Hi,
I am testing a situation with shared CKRecords where the data in the CKRecord syncs fine, but the creatorUserRecordID.recordName and lastModifiedUserRecordID.recordName shows "defaultOwner" (which maps to the CKCurrentUserDefaultName constant) even though I made sure I edit the CKRecord value from a different iCloud account. In fact, on the CloudKit dashboard, it shows the correct user recordIDs in the metadata for the 'Created' and 'Modified' fields, but not in the CKRecord.
I am mostly testing this on the iPhone simulator with the debugger attached. Is that a possible reason for this, or is there some other reason the lastModifiedUserRecordID is showing the value for 'CKCurrentUserDefaultName'? It would be pretty difficult to build in functionality to look up changes by a different userID if this is the case.