Post

Replies

Boosts

Views

Activity

Different toolbar item placement for iPhone vs iPad
On iPhone, I would like to have a more button at the top right of the navigation bar, a search field in the bottom toolbar, and a plus button to the right of the search field. I've achieved this via the code below. But on iPad they should be in the navigation bar at the trailing edge from left to right: plus, more, search field. Just like the Shortcuts app, if there's not enough horizontal space, the search field should collapse into a button, and with even smaller space the search bar should become full-width under the navigation bar. Right now on iPad the search bar is full width under the navigation bar, more at top right, plus at bottom middle, no matter how big the window is. How can I achieve that? Any way to specify them for the system to more automatically do the right thing, or would I need to check specifically for iPhone vs iPad UIDevice to change the code? struct ContentView: View { @State private var searchText = "" var body: some View { NavigationStack { VStack { Text("Hello, world!") } .navigationTitle("Test App") .searchable(text: $searchText) .toolbar { ToolbarItem { Menu { //... } label: { Label("More", systemImage: "ellipsis") } } DefaultToolbarItem(kind: .search, placement: .bottomBar) ToolbarSpacer(.fixed, placement: .bottomBar) ToolbarItem(placement: .bottomBar) { Button { print("Add tapped") } label: { Label("Add", systemImage: "plus") } } } } } }
3
0
291
Aug ’25
BGContinuedProcessingTask launchHandler invocation
I'm trying to understand how the API works to perform a function that can continue running if the user closes the app. For a very simple example, consider a function that increments a number on screen every second, counting from 1 to 100, reaching completion at 100. The user can stay in the app for 100s watching it work to completion, or the user can close the app say after 2s and do other things while watching it work to completion in the Live Activity. To do this when the user taps a Start Counting button, you'd 1 Call BGTaskScheduler.shared.register(forTaskWithIdentifier:using:launchHandler:). Question 1: Do I understand correctly, all of the logic to perform this counting operation would exist entirely in the launchHandler block (noting you could call another function you define passing it the task to be able to update its progress)? I am confused because the documentation states "The system runs the block of code for the launch handler when it launches the app in the background." but the app is already open in the foreground. This made me think this block is not going to be invoked until the user closes the app to inform you it's okay to continue processing in the background, but how would you know where to pick up. I want to confirm my thinking was wrong, that all the logic should be in this block from start to completion of the operation, and it's fine even if the app stays in the foreground the whole time. 2 Then you'd create a BGContinuedProcessingTaskRequest and set request.strategy = .fail for this example because you need it to start immediately per the user's explicit tap on the Start Counting button. 3 Call BGTaskScheduler.shared.submit(request). Question 2: If the submit function throws an error, should you handle it by just performing the counting operation logic (call your function without passing a task)? I understand this can happen if for some reason the system couldn't immediately run it, like if there's already too many pending task requests. Seems you should not show an error message to the user, should still perform the request and just not support background continued processing for it (and perhaps consider showing a light warning "this operation can't be continued in the background so keep the app open"). Or should you still queue it up even though the user wants to start counting now? That leads to my next question Question 3: In what scenario would you not want the operation to start immediately (the queue behavior which is the default), given the app is already in the foreground and the user requested some operation? I'm struggling to think of an example, like a button titled Compress Photos Whenever You Can, and it may start immediately or maybe it won't? While waiting for the launchHandler to be invoked, should the UI just show 0% progress or "Pending" until the system can get to this task in the queue? Struggling to understand the use cases here, why make the user wait to start processing when they might not even intend to close the app during the operation? Thanks for any insights! As an aside, a sample project with a couple use cases would have been incredibly helpful to understand how the API is expected to be used.
8
0
411
Oct ’25
App Store Connect release notes RSS feed
I want to keep an eye on the App Store Connect release notes to find out when builds created with Xcode 26.2 RC will be accepted. I tried to add https://developer.apple.com/help/app-store-connect/release-notes/ to my RSS reeder but the items listed are not the same, it’s the items from the latest news from Apple Developer instead. Can we get an RSS feed please? Seems will be useful to monitor these release notes over time.
4
0
271
Dec ’25
How to use AccessoryWidgetBackground with containerBackground API on iOS 17
I have an accessoryCircular Lock Screen widget built for iOS 16: ZStack { AccessoryWidgetBackground() VStack { Text("MON") .font(.caption) Text("6") .font(.title) } } When run on iOS 17 it renders an error “Please adopt containerBackground API”. So I changed it to: VStack { Text("MON") .font(.caption) Text("6") .font(.title) } .containerBackground(for: .widget) { AccessoryWidgetBackground() } This causes the error to go away but the circular background is no longer visible (tested with iPadOS 17b2). What’s the right way to implement this?
2
1
2.5k
Sep ’23
How to sync NSPersistentCloudKitContainer in background after performing AppIntent from widget
I have an app that uses NSPersistentCloudKitContainer and a widget that displays a record. I want to add a button with interactive widgets in iOS 17 to modify the visible record via an AppIntent. When I do this the app logs: CoreData: debug: CoreData+CloudKit: -[NSCloudKitMirroringDelegate managedObjectContextSaved:](2945): <NSCloudKitMirroringDelegate: 0x2818002a0>: Observed context save: <NSPersistentStoreCoordinator: 0x280a05180> - <NSManagedObjectContext: 0x281a00410> It does not automatically sync this change to iCloud, not until I manually return the app to the foreground, even if I delay returning from the perform() function. Is there a way to sync NSPersistentCloudKitContainer while the app is in the background as a result of this change triggered in the widget? Thanks!
2
1
931
Jul ’23
Display HDR images for PhotoKit assets
In my app I get a UIImage for a PHAsset via PHImageManager.requestImage(for:targetSize:contentMode:options:resultHandler:). I directly display that image in a UIImageView that has preferredImageDynamicRange set to .high. The problem is I do not see the high dynamic range. I see the HDRDemo23 sample code uses PhotosPicker to get a UIImage from Data through UIImageReader whose config enables prefersHighDynamicRange. Is there a way to support HDR when using the Photos APIs to request display images? And is there support for PHLivePhoto displayed in PHLivePhotoView retrieved via PHImageManager.requestLivePhoto?
4
1
1.8k
Apr ’24
Sort user library assets by date captured instead of recently added
Is it possible to sort the user library assets by date captured? The Photos app in iOS 18 lets you choose between Date Captured and Recently Added and I want to offer that same choice in my app. This seems to always sort them by creation date (which I believe is the same as recently added): let assetCollection = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .smartAlbumUserLibrary, options: nil).firstObject! let fetchResult = PHAsset.fetchAssets(in: assetCollection, options: PHFetchOptions.imageMediaType())
0
1
686
Jun ’24
Build XCFramework from source that has dependencies on Swift Packages
I’m looking into building a closed source XCFramework from a local Swift package that has dependencies on other packages, which can later be distributed via Swift Package Manager. In initial discussions, we thought xcodebuild does not support linking the dependencies externally, it always includes them statically in the built framework. It's my understanding this is because we're asking xcodebuild to build a framework from a local Swift Package. Is there another way this can be achieved? To explain in more detail: I have built a closed source SDK for other developers to integrate in their apps, currently distributed as an XCFramework. The interesting thing about the SDK is it has dependencies on other libraries, which need to be resolved when adding this SDK as a dependency to an app. The SDK’s dependencies should not be baked into our XCFramework. CocoaPods has worked well for that but we want to instead use SPM. The current project setup is an iOS framework Xcode project and an app Xcode workspace. The framework project is included in the app workspace and is in the same repo as the app, which allows me to modify the framework source code then run the app to test it. The framework project can also be opened independently and built to verify it doesn’t have any errors, but to verify it’s working I run it with the app. To distribute a new release I use xcodebuild to create an XCFramework and then deploy that. For this to work with CocoaPods I had to add a Podfile to the app directly as well as the framework directory so both have the dependencies available. This means I have an xcworkspace for the framework and not just a xcodeproj. I specify the framework workspace file in the xcodebuild command. To switch to a setup that utilizes Swift Package Manager, I created a Package.swift in the iOS framework project’s directory that specifies its dependencies, removed CocoaPods integration including deleting the workspace file, removed the framework project from the app’s workspace, added the Package as a local package to the app project, and added the framework directory via + > Add Files to “App” which adds the package to the top of the sidebar, making its source code available to edit within the app workspace. Everything is working when I run the app. Xcode properly resolves the dependencies for the local package and I can run the app to develop it. Now to create an XCFramework I run the following command in the framework directory (which contains the Package.swift): xcodebuild archive -workspace . -scheme FrameworkName -configuration Release -destination 'generic/platform=iOS' -archivePath './build/FrameworkName.framework-iphoneos.xcarchive' SKIP_INSTALL=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES ENABLE_USER_SCRIPT_SANDBOXING=NO This succeeds however the dependencies have been linked statically thus included in our SDK. We need to only include the code from our framework and link to external dependencies, like it does with our current CocoaPods setup. I'm wondering what options there are to achieve this. Even if I need to change the project setup locally, for example to continue using a framework project/workspace instead of a local Swift package. It seems I just need xcodebuild to be able to create an XCFramework which can then be distributed with its own Package.swift file that specifies its dependencies. If it's not possible to link the dependencies externally, could you help me to understand the implications of including them statically? I don't know what problems could arise as a result of that or other concerns this would bring. Thanks!
1
1
3.7k
Jun ’24
Reverse geocoding rate limit of MKReverseGeocodingRequest compared to CLGeocoder
The documentation for CLGeocoder states Geocoding requests are rate-limited for each app, so making too many requests in a short period of time may cause some of the requests to fail. (When the maximum rate is exceeded, the geocoder returns an error object with the CLError.Code.network error to the associated completion handler.) And it provides helpful guidance on how and when to submit geocoding requests. The documentation for MKReverseGeocodingRequest does not mention requests are rate-limited. Does this mean it is not rate-limited? If it is rate-limited, is it similar to CLGeocoder, what is its behavior? It is important to understand behavior of the API in order to understand impact on my app’s use case and how users will be affected should I change the implementation. Thanks!
2
1
583
Dec ’25
MKReverseGeocodingRequest and CNPostalAddress from MKMapItem
My app is currently using CLGeocoder to get a CLPlacemark, then using placemark.postalAddress with CNPostalAddressFormatter to get an attributed string for the full address, I then enumerate its attributes to pull out specific elements like just the street or state or zip etc. This is deprecated in iOS 26 with MKReverseGeocodingRequest being the intended replacement. This API returns an MKMapItem which doesn’t provide a CNPostalAddress - you can get a full address as a String but not structured address data that I’m seeing. Am I missing some way to get the postal address? Or is it a non-goal to provide that anymore? Thanks!
8
2
656
Jan ’26
How to add view below navigation bar to extend scroll edge effect
Hello! What UIKit API enables you to add a view below the navigation bar and extend the scroll edge effect below it in iOS 26? safeAreaBar is how you do it in SwiftUI but I need to achieve this design in my UIKit app (which has a collection view in a view controller in a navigation controller). struct ContentView: View { let segments = ["First", "Second", "Third"] @State private var selectedSegment = "First" var body: some View { NavigationStack { List(0..<50, id: \.self) { i in Text("Row \(i + 1)") } .safeAreaBar(edge: .top) { Picker("Segment", selection: $selectedSegment) { ForEach(segments, id: \.self) { Text($0) } } .pickerStyle(.segmented) .padding(.horizontal) .padding(.bottom, 8) } .navigationTitle("Title") .navigationBarTitleDisplayMode(.inline) } } }
3
1
535
Dec ’25
String Catalog stops updating upon changing source code
If you add a new string in your app (for example String(localized: "contact_support_message", defaultValue: "Please contact support")), then later you change that default value and rebuild, the string catalog updates to match as expected. But once that string is translated, changing the default value in code and rebuilding does not update the catalog. You seemingly have to go manually change the default value for English in the catalog to match the code (which marks the translation as Needs Review). Is there a better way? Or is there a way to determine what strings have default values in code that do not match the catalog values to see if any were missed as wording was tweaked over time?
3
0
182
Feb ’26
How to add Paste button in UIMenu such that the system "allow app to paste" prompt does not appear
Apps that try to access the contents of the pasteboard cause a system prompt to appear asking the user "AppName" would like to paste from "OtherAppName" Do you want to allow this? Don't Allow Paste Allow Paste This prompt does not appear if you implement a UIPasteControl and the user taps it to signal intent to paste, but this control cannot be placed into a UIMenu. I read this could be achieved with UIAction.Identifiers like .paste or .newFromPasteboard but the prompt still appears with the following code. What's the trick? override func viewDidLoad() { super.viewDidLoad() title = "TestPaste" view.backgroundColor = .systemBackground let imageView = UIImageView() imageView.translatesAutoresizingMaskIntoConstraints = false imageView.contentMode = .scaleAspectFit imageView.clipsToBounds = true view.addSubview(imageView) NSLayoutConstraint.activate([ imageView.topAnchor.constraint(equalTo: view.topAnchor), imageView.leadingAnchor.constraint(equalTo: view.leadingAnchor), imageView.trailingAnchor.constraint(equalTo: view.trailingAnchor), imageView.bottomAnchor.constraint(equalTo: view.bottomAnchor) ]) navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Add", image: UIImage(systemName: "plus"), menu: UIMenu(children: [ UIAction(identifier: .paste) { _ in imageView.image = UIPasteboard.general.image } ])) }
4
0
454
6d
Test Swift Package that vends XCFramework and has dependencies in example app before distribution
I've created a closed source iOS SDK from a local Swift package, which has dependencies on other Swift packages, and successfully created a binary XCFramework following the solution from my previous post. I would now like to create a Package.swift to vend this XCFramework and test it in an example app to verify it works as expected before I upload it to a public repo for distribution. I understand that binaryTarget does not support dependencies so we need to use a wrapper. I created a directory containing the following: Package.swift MyFramework.xcframework/ MyFrameworkWrapper/ ├─ dummy.swift Package.swift contains: // swift-tools-version: 5.10 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription let package = Package( name: "MyFramework", platforms: [ .iOS(.v14) ], products: [ .library( name: "MyFramework", targets: ["MyFramework", "MyFrameworkWrapper"] ) ], dependencies: [ .package(url: "https://github.com/gordontucker/FittedSheets.git", from: "2.6.1") ], targets: [ .target( name: "MyFrameworkWrapper", dependencies: [ "FittedSheets" ], path: "MyFrameworkWrapper" ), .binaryTarget( name: "MyFramework", path: "MyFramework.xcframework" ) ] ) I created a new iOS app, selected the project, Package Dependencies > + > Add Local, and added the directory containing this Package.swift. Xcode resolves the dependencies and lists them in the sidebar. I added code to import and use the framework. It builds successfully but the app crashes when run: dyld[63959]: Library not loaded: @rpath/FittedSheets.framework/FittedSheets Referenced from: <7DE247FC-DAFF-3946-AD21-E80F5AF841C9> /Users/Jordan/Library/Developer/Xcode/DerivedData/MyFramework-Example-gaeeymnqzenzrbbmhuebpodqctsz/Build/Products/Debug-iphonesimulator/MyFramework.framework/MyFramework How do I get this working? I'm wondering is my package set up properly to vend the framework specifying its dependencies, and is my XCFramework created correctly? The Package.swift for the framework's source code contains: // swift-tools-version: 5.10 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription let package = Package( name: "MyFramework", platforms: [ .iOS(.v14) ], products: [ .library( name: "MyFramework", type: .dynamic, targets: ["MyFramework"] ) ], dependencies: [ .package(url: "https://github.com/gordontucker/FittedSheets.git", from: "2.6.1") ], targets: [ .target( name: "MyFramework", dependencies: [ "FittedSheets" ], path: "Sources" ) ] ) And I created the XCFramework following the steps in that previous thread: Create archive from package via xcodebuild archive -workspace "$PACKAGE_PATH" -scheme "$FRAMEWORK_NAME" -destination 'generic/platform=iOS' -archivePath "$ARCHIVE_PATH/iOS" SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES ENABLE_USER_SCRIPT_SANDBOXING=NO ENABLE_MODULE_VERIFIER=NO OTHER_SWIFT_FLAGS=-no-verify-emitted-module-interface Create the Modules directory in the framework via mkdir -p "$ARCHIVE_PATH/iOS.xcarchive/Products/usr/local/lib/$FRAMEWORK_NAME.framework/Modules" Copy the Swift interface files into the framework from the build in DerivedData via cp -a "$BUILD_PRODUCTS_PATH/Build/Intermediates.noindex/ArchiveIntermediates/$FRAMEWORK_NAME/BuildProductsPath/Release-iphoneos/$FRAMEWORK_NAME.swiftmodule" "$ARCHIVE_PATH/iOS.xcarchive/Products/usr/local/lib/$FRAMEWORK_NAME.framework/Modules" Repeat 1-3 for iOS Simulator Create an XCFramework via xcodebuild -create-xcframework -framework "$ARCHIVE_PATH/iOS.xcarchive/Products/usr/local/lib/$FRAMEWORK_NAME.framework" -framework "$ARCHIVE_PATH/iOS_Simulator.xcarchive/Products/usr/local/lib/$FRAMEWORK_NAME.framework" -output "$ARCHIVE_PATH/$FRAMEWORK_NAME.xcframework"
0
2
937
Jun ’24
Different toolbar item placement for iPhone vs iPad
On iPhone, I would like to have a more button at the top right of the navigation bar, a search field in the bottom toolbar, and a plus button to the right of the search field. I've achieved this via the code below. But on iPad they should be in the navigation bar at the trailing edge from left to right: plus, more, search field. Just like the Shortcuts app, if there's not enough horizontal space, the search field should collapse into a button, and with even smaller space the search bar should become full-width under the navigation bar. Right now on iPad the search bar is full width under the navigation bar, more at top right, plus at bottom middle, no matter how big the window is. How can I achieve that? Any way to specify them for the system to more automatically do the right thing, or would I need to check specifically for iPhone vs iPad UIDevice to change the code? struct ContentView: View { @State private var searchText = "" var body: some View { NavigationStack { VStack { Text("Hello, world!") } .navigationTitle("Test App") .searchable(text: $searchText) .toolbar { ToolbarItem { Menu { //... } label: { Label("More", systemImage: "ellipsis") } } DefaultToolbarItem(kind: .search, placement: .bottomBar) ToolbarSpacer(.fixed, placement: .bottomBar) ToolbarItem(placement: .bottomBar) { Button { print("Add tapped") } label: { Label("Add", systemImage: "plus") } } } } } }
Replies
3
Boosts
0
Views
291
Activity
Aug ’25
BGContinuedProcessingTask launchHandler invocation
I'm trying to understand how the API works to perform a function that can continue running if the user closes the app. For a very simple example, consider a function that increments a number on screen every second, counting from 1 to 100, reaching completion at 100. The user can stay in the app for 100s watching it work to completion, or the user can close the app say after 2s and do other things while watching it work to completion in the Live Activity. To do this when the user taps a Start Counting button, you'd 1 Call BGTaskScheduler.shared.register(forTaskWithIdentifier:using:launchHandler:). Question 1: Do I understand correctly, all of the logic to perform this counting operation would exist entirely in the launchHandler block (noting you could call another function you define passing it the task to be able to update its progress)? I am confused because the documentation states "The system runs the block of code for the launch handler when it launches the app in the background." but the app is already open in the foreground. This made me think this block is not going to be invoked until the user closes the app to inform you it's okay to continue processing in the background, but how would you know where to pick up. I want to confirm my thinking was wrong, that all the logic should be in this block from start to completion of the operation, and it's fine even if the app stays in the foreground the whole time. 2 Then you'd create a BGContinuedProcessingTaskRequest and set request.strategy = .fail for this example because you need it to start immediately per the user's explicit tap on the Start Counting button. 3 Call BGTaskScheduler.shared.submit(request). Question 2: If the submit function throws an error, should you handle it by just performing the counting operation logic (call your function without passing a task)? I understand this can happen if for some reason the system couldn't immediately run it, like if there's already too many pending task requests. Seems you should not show an error message to the user, should still perform the request and just not support background continued processing for it (and perhaps consider showing a light warning "this operation can't be continued in the background so keep the app open"). Or should you still queue it up even though the user wants to start counting now? That leads to my next question Question 3: In what scenario would you not want the operation to start immediately (the queue behavior which is the default), given the app is already in the foreground and the user requested some operation? I'm struggling to think of an example, like a button titled Compress Photos Whenever You Can, and it may start immediately or maybe it won't? While waiting for the launchHandler to be invoked, should the UI just show 0% progress or "Pending" until the system can get to this task in the queue? Struggling to understand the use cases here, why make the user wait to start processing when they might not even intend to close the app during the operation? Thanks for any insights! As an aside, a sample project with a couple use cases would have been incredibly helpful to understand how the API is expected to be used.
Replies
8
Boosts
0
Views
411
Activity
Oct ’25
App Store Connect release notes RSS feed
I want to keep an eye on the App Store Connect release notes to find out when builds created with Xcode 26.2 RC will be accepted. I tried to add https://developer.apple.com/help/app-store-connect/release-notes/ to my RSS reeder but the items listed are not the same, it’s the items from the latest news from Apple Developer instead. Can we get an RSS feed please? Seems will be useful to monitor these release notes over time.
Replies
4
Boosts
0
Views
271
Activity
Dec ’25
How to use AccessoryWidgetBackground with containerBackground API on iOS 17
I have an accessoryCircular Lock Screen widget built for iOS 16: ZStack { AccessoryWidgetBackground() VStack { Text("MON") .font(.caption) Text("6") .font(.title) } } When run on iOS 17 it renders an error “Please adopt containerBackground API”. So I changed it to: VStack { Text("MON") .font(.caption) Text("6") .font(.title) } .containerBackground(for: .widget) { AccessoryWidgetBackground() } This causes the error to go away but the circular background is no longer visible (tested with iPadOS 17b2). What’s the right way to implement this?
Replies
2
Boosts
1
Views
2.5k
Activity
Sep ’23
How to sync NSPersistentCloudKitContainer in background after performing AppIntent from widget
I have an app that uses NSPersistentCloudKitContainer and a widget that displays a record. I want to add a button with interactive widgets in iOS 17 to modify the visible record via an AppIntent. When I do this the app logs: CoreData: debug: CoreData+CloudKit: -[NSCloudKitMirroringDelegate managedObjectContextSaved:](2945): <NSCloudKitMirroringDelegate: 0x2818002a0>: Observed context save: <NSPersistentStoreCoordinator: 0x280a05180> - <NSManagedObjectContext: 0x281a00410> It does not automatically sync this change to iCloud, not until I manually return the app to the foreground, even if I delay returning from the perform() function. Is there a way to sync NSPersistentCloudKitContainer while the app is in the background as a result of this change triggered in the widget? Thanks!
Replies
2
Boosts
1
Views
931
Activity
Jul ’23
Display HDR images for PhotoKit assets
In my app I get a UIImage for a PHAsset via PHImageManager.requestImage(for:targetSize:contentMode:options:resultHandler:). I directly display that image in a UIImageView that has preferredImageDynamicRange set to .high. The problem is I do not see the high dynamic range. I see the HDRDemo23 sample code uses PhotosPicker to get a UIImage from Data through UIImageReader whose config enables prefersHighDynamicRange. Is there a way to support HDR when using the Photos APIs to request display images? And is there support for PHLivePhoto displayed in PHLivePhotoView retrieved via PHImageManager.requestLivePhoto?
Replies
4
Boosts
1
Views
1.8k
Activity
Apr ’24
Drag and drop to open window in SwiftUI app
With UIKit you can open a window via drag and drop by creating a UIDragItem with an NSItemProvider and NSUserActivity object in a collection view. Is there a similar SwiftUI API to open a window by dragging out a view from a grid? Or can we only manually invoke openWindow from a button?
Replies
2
Boosts
1
Views
1.5k
Activity
Jan ’24
Sort user library assets by date captured instead of recently added
Is it possible to sort the user library assets by date captured? The Photos app in iOS 18 lets you choose between Date Captured and Recently Added and I want to offer that same choice in my app. This seems to always sort them by creation date (which I believe is the same as recently added): let assetCollection = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .smartAlbumUserLibrary, options: nil).firstObject! let fetchResult = PHAsset.fetchAssets(in: assetCollection, options: PHFetchOptions.imageMediaType())
Replies
0
Boosts
1
Views
686
Activity
Jun ’24
Build XCFramework from source that has dependencies on Swift Packages
I’m looking into building a closed source XCFramework from a local Swift package that has dependencies on other packages, which can later be distributed via Swift Package Manager. In initial discussions, we thought xcodebuild does not support linking the dependencies externally, it always includes them statically in the built framework. It's my understanding this is because we're asking xcodebuild to build a framework from a local Swift Package. Is there another way this can be achieved? To explain in more detail: I have built a closed source SDK for other developers to integrate in their apps, currently distributed as an XCFramework. The interesting thing about the SDK is it has dependencies on other libraries, which need to be resolved when adding this SDK as a dependency to an app. The SDK’s dependencies should not be baked into our XCFramework. CocoaPods has worked well for that but we want to instead use SPM. The current project setup is an iOS framework Xcode project and an app Xcode workspace. The framework project is included in the app workspace and is in the same repo as the app, which allows me to modify the framework source code then run the app to test it. The framework project can also be opened independently and built to verify it doesn’t have any errors, but to verify it’s working I run it with the app. To distribute a new release I use xcodebuild to create an XCFramework and then deploy that. For this to work with CocoaPods I had to add a Podfile to the app directly as well as the framework directory so both have the dependencies available. This means I have an xcworkspace for the framework and not just a xcodeproj. I specify the framework workspace file in the xcodebuild command. To switch to a setup that utilizes Swift Package Manager, I created a Package.swift in the iOS framework project’s directory that specifies its dependencies, removed CocoaPods integration including deleting the workspace file, removed the framework project from the app’s workspace, added the Package as a local package to the app project, and added the framework directory via + > Add Files to “App” which adds the package to the top of the sidebar, making its source code available to edit within the app workspace. Everything is working when I run the app. Xcode properly resolves the dependencies for the local package and I can run the app to develop it. Now to create an XCFramework I run the following command in the framework directory (which contains the Package.swift): xcodebuild archive -workspace . -scheme FrameworkName -configuration Release -destination 'generic/platform=iOS' -archivePath './build/FrameworkName.framework-iphoneos.xcarchive' SKIP_INSTALL=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES ENABLE_USER_SCRIPT_SANDBOXING=NO This succeeds however the dependencies have been linked statically thus included in our SDK. We need to only include the code from our framework and link to external dependencies, like it does with our current CocoaPods setup. I'm wondering what options there are to achieve this. Even if I need to change the project setup locally, for example to continue using a framework project/workspace instead of a local Swift package. It seems I just need xcodebuild to be able to create an XCFramework which can then be distributed with its own Package.swift file that specifies its dependencies. If it's not possible to link the dependencies externally, could you help me to understand the implications of including them statically? I don't know what problems could arise as a result of that or other concerns this would bring. Thanks!
Replies
1
Boosts
1
Views
3.7k
Activity
Jun ’24
Reverse geocoding rate limit of MKReverseGeocodingRequest compared to CLGeocoder
The documentation for CLGeocoder states Geocoding requests are rate-limited for each app, so making too many requests in a short period of time may cause some of the requests to fail. (When the maximum rate is exceeded, the geocoder returns an error object with the CLError.Code.network error to the associated completion handler.) And it provides helpful guidance on how and when to submit geocoding requests. The documentation for MKReverseGeocodingRequest does not mention requests are rate-limited. Does this mean it is not rate-limited? If it is rate-limited, is it similar to CLGeocoder, what is its behavior? It is important to understand behavior of the API in order to understand impact on my app’s use case and how users will be affected should I change the implementation. Thanks!
Replies
2
Boosts
1
Views
583
Activity
Dec ’25
MKReverseGeocodingRequest and CNPostalAddress from MKMapItem
My app is currently using CLGeocoder to get a CLPlacemark, then using placemark.postalAddress with CNPostalAddressFormatter to get an attributed string for the full address, I then enumerate its attributes to pull out specific elements like just the street or state or zip etc. This is deprecated in iOS 26 with MKReverseGeocodingRequest being the intended replacement. This API returns an MKMapItem which doesn’t provide a CNPostalAddress - you can get a full address as a String but not structured address data that I’m seeing. Am I missing some way to get the postal address? Or is it a non-goal to provide that anymore? Thanks!
Replies
8
Boosts
2
Views
656
Activity
Jan ’26
How to add view below navigation bar to extend scroll edge effect
Hello! What UIKit API enables you to add a view below the navigation bar and extend the scroll edge effect below it in iOS 26? safeAreaBar is how you do it in SwiftUI but I need to achieve this design in my UIKit app (which has a collection view in a view controller in a navigation controller). struct ContentView: View { let segments = ["First", "Second", "Third"] @State private var selectedSegment = "First" var body: some View { NavigationStack { List(0..<50, id: \.self) { i in Text("Row \(i + 1)") } .safeAreaBar(edge: .top) { Picker("Segment", selection: $selectedSegment) { ForEach(segments, id: \.self) { Text($0) } } .pickerStyle(.segmented) .padding(.horizontal) .padding(.bottom, 8) } .navigationTitle("Title") .navigationBarTitleDisplayMode(.inline) } } }
Replies
3
Boosts
1
Views
535
Activity
Dec ’25
String Catalog stops updating upon changing source code
If you add a new string in your app (for example String(localized: "contact_support_message", defaultValue: "Please contact support")), then later you change that default value and rebuild, the string catalog updates to match as expected. But once that string is translated, changing the default value in code and rebuilding does not update the catalog. You seemingly have to go manually change the default value for English in the catalog to match the code (which marks the translation as Needs Review). Is there a better way? Or is there a way to determine what strings have default values in code that do not match the catalog values to see if any were missed as wording was tweaked over time?
Replies
3
Boosts
0
Views
182
Activity
Feb ’26
How to add Paste button in UIMenu such that the system "allow app to paste" prompt does not appear
Apps that try to access the contents of the pasteboard cause a system prompt to appear asking the user "AppName" would like to paste from "OtherAppName" Do you want to allow this? Don't Allow Paste Allow Paste This prompt does not appear if you implement a UIPasteControl and the user taps it to signal intent to paste, but this control cannot be placed into a UIMenu. I read this could be achieved with UIAction.Identifiers like .paste or .newFromPasteboard but the prompt still appears with the following code. What's the trick? override func viewDidLoad() { super.viewDidLoad() title = "TestPaste" view.backgroundColor = .systemBackground let imageView = UIImageView() imageView.translatesAutoresizingMaskIntoConstraints = false imageView.contentMode = .scaleAspectFit imageView.clipsToBounds = true view.addSubview(imageView) NSLayoutConstraint.activate([ imageView.topAnchor.constraint(equalTo: view.topAnchor), imageView.leadingAnchor.constraint(equalTo: view.leadingAnchor), imageView.trailingAnchor.constraint(equalTo: view.trailingAnchor), imageView.bottomAnchor.constraint(equalTo: view.bottomAnchor) ]) navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Add", image: UIImage(systemName: "plus"), menu: UIMenu(children: [ UIAction(identifier: .paste) { _ in imageView.image = UIPasteboard.general.image } ])) }
Replies
4
Boosts
0
Views
454
Activity
6d
Test Swift Package that vends XCFramework and has dependencies in example app before distribution
I've created a closed source iOS SDK from a local Swift package, which has dependencies on other Swift packages, and successfully created a binary XCFramework following the solution from my previous post. I would now like to create a Package.swift to vend this XCFramework and test it in an example app to verify it works as expected before I upload it to a public repo for distribution. I understand that binaryTarget does not support dependencies so we need to use a wrapper. I created a directory containing the following: Package.swift MyFramework.xcframework/ MyFrameworkWrapper/ ├─ dummy.swift Package.swift contains: // swift-tools-version: 5.10 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription let package = Package( name: "MyFramework", platforms: [ .iOS(.v14) ], products: [ .library( name: "MyFramework", targets: ["MyFramework", "MyFrameworkWrapper"] ) ], dependencies: [ .package(url: "https://github.com/gordontucker/FittedSheets.git", from: "2.6.1") ], targets: [ .target( name: "MyFrameworkWrapper", dependencies: [ "FittedSheets" ], path: "MyFrameworkWrapper" ), .binaryTarget( name: "MyFramework", path: "MyFramework.xcframework" ) ] ) I created a new iOS app, selected the project, Package Dependencies > + > Add Local, and added the directory containing this Package.swift. Xcode resolves the dependencies and lists them in the sidebar. I added code to import and use the framework. It builds successfully but the app crashes when run: dyld[63959]: Library not loaded: @rpath/FittedSheets.framework/FittedSheets Referenced from: <7DE247FC-DAFF-3946-AD21-E80F5AF841C9> /Users/Jordan/Library/Developer/Xcode/DerivedData/MyFramework-Example-gaeeymnqzenzrbbmhuebpodqctsz/Build/Products/Debug-iphonesimulator/MyFramework.framework/MyFramework How do I get this working? I'm wondering is my package set up properly to vend the framework specifying its dependencies, and is my XCFramework created correctly? The Package.swift for the framework's source code contains: // swift-tools-version: 5.10 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription let package = Package( name: "MyFramework", platforms: [ .iOS(.v14) ], products: [ .library( name: "MyFramework", type: .dynamic, targets: ["MyFramework"] ) ], dependencies: [ .package(url: "https://github.com/gordontucker/FittedSheets.git", from: "2.6.1") ], targets: [ .target( name: "MyFramework", dependencies: [ "FittedSheets" ], path: "Sources" ) ] ) And I created the XCFramework following the steps in that previous thread: Create archive from package via xcodebuild archive -workspace "$PACKAGE_PATH" -scheme "$FRAMEWORK_NAME" -destination 'generic/platform=iOS' -archivePath "$ARCHIVE_PATH/iOS" SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES ENABLE_USER_SCRIPT_SANDBOXING=NO ENABLE_MODULE_VERIFIER=NO OTHER_SWIFT_FLAGS=-no-verify-emitted-module-interface Create the Modules directory in the framework via mkdir -p "$ARCHIVE_PATH/iOS.xcarchive/Products/usr/local/lib/$FRAMEWORK_NAME.framework/Modules" Copy the Swift interface files into the framework from the build in DerivedData via cp -a "$BUILD_PRODUCTS_PATH/Build/Intermediates.noindex/ArchiveIntermediates/$FRAMEWORK_NAME/BuildProductsPath/Release-iphoneos/$FRAMEWORK_NAME.swiftmodule" "$ARCHIVE_PATH/iOS.xcarchive/Products/usr/local/lib/$FRAMEWORK_NAME.framework/Modules" Repeat 1-3 for iOS Simulator Create an XCFramework via xcodebuild -create-xcframework -framework "$ARCHIVE_PATH/iOS.xcarchive/Products/usr/local/lib/$FRAMEWORK_NAME.framework" -framework "$ARCHIVE_PATH/iOS_Simulator.xcarchive/Products/usr/local/lib/$FRAMEWORK_NAME.framework" -output "$ARCHIVE_PATH/$FRAMEWORK_NAME.xcframework"
Replies
0
Boosts
2
Views
937
Activity
Jun ’24