Post

Replies

Boosts

Views

Activity

Distributing Swift Package, without remote repo
Hi, I am working on distributing a 'framework' I made to a client. The framework itself has a couple of dependencies on a couple of 3rd-party frameworks. Also, I don't want to disclose my source code to the client. So after doing some research, it seems like the best way to do this would be to use Swift Packages, and make it a binary distribution, which would basically wrap a .xcframework (which I would generate with my source code). But I'm confused about the next steps ... how would I go about sharing the 'package' with the client? Would I just zip up the 'package' folder and email it to them, and they can unzip it on their end, and add it to their project by using "Add local package"? Or is there a more elegant way to do this, which doesn't require publishing a package publicly?
0
0
578
May ’23
Create Swift Package with 3rd party dependencies
I am trying to create a Swift Package for a custom framework I'm building for a client. The framework has a dependency on a couple of 3rd party frameworks. I've read about how even though binary frameworks don't support dependencies directly, there is way to do this with a 'wrapper' target, so this is what I came up with for Package.swift: let package = Package( name: "SBCardScannerFramework", platforms: [ .iOS(.v16) ], products: [ // Products define the executables and libraries a package produces, and make them visible to other packages. .library( name: "SBCardScannerFramework", targets: ["SBCardScannerFramework-Target"]), ], dependencies: [ // Dependencies declare other packages that this package depends on. .package(url: "https://github.com/apple/swift-algorithms.git", from: "1.0.0"), .package(url: "https://github.com/marmelroy/PhoneNumberKit.git", from: "3.3.3") ], targets: [ .target(name: "SBCardScannerFramework-Target", dependencies: [ .target(name: "SBCardScannerFramework", condition: .when(platforms: [.iOS])), .product(name: "Algorithms", package: "swift-algorithms"), .product(name: "PhoneNumberKit", package: "PhoneNumberKit") ] ), .binaryTarget(name: "SBCardScannerFramework", path: "SBCardScannerFramework.xcframework") ] ) This works, and I can add the package to my test project and import the framework and it links against the dependancies as well, and works correctly. The problem is that every time I run the app, it also shows these messages in the Xcode console: objc[845]: Class _TtC14PhoneNumberKitP33_0FE53357E470A64027C8F0CAF7B114C812BundleFinder is implemented in both /private/var/containers/Bundle/Application/EEE0C0A6-4FF5-44BC-B81A-F95401219D32/TestSBCardScannerFrameworkImport.app/Frameworks/SBCardScannerFramework.framework/SBCardScannerFramework (0x100f4aaf0) and /private/var/containers/Bundle/Application/EEE0C0A6-4FF5-44BC-B81A-F95401219D32/TestSBCardScannerFrameworkImport.app/TestSBCardScannerFrameworkImport (0x10069b778). One of the two will be used. Which one is undefined. There's multiple lines for different classes that show the "Class X is implemented in both [.../MyApp.app/Frameworks/MyFramework.frameworkMyFramework/] and [.../MyApp.app/MyApp]". I'm not sure how to avoid this problem, and whether this could cause a problem down the line. The framework that is the basis for this Swift Package is linked against the two dependencies, because I wouldn't be able to build the framework without them. But they also need to be added to the app target (at least, and if I don't, I get a run-time crash when using the PhoneNumberKit initializer. PhoneNumberKit/resource_bundle_accessor.swift:40: Fatal error: unable to find bundle named PhoneNumberKit_PhoneNumberKit Is there a good way to resolve this issue? I'm worried this will could be a problem for the client when they integrate it into their app, and the app is deployed to 1000s of devices.
0
0
1.3k
May ’23
iOS extensions - order of installation
Hi, I have a few extensions for my iOS app: Share Extension, Widget extensions, Notification Extensions, Today Extension, WatchKit app. My app and all the extensions share data by loading the same Core Data sqlite database from a shared folder. One problem I'm having with this setup is with a Core Data lightweight migration. On updating the app to the new database model, I would like my main app to first make a backup of the database before the migration runs. But one of the app extensions always seems to run before the main app, and ends up performing the lightweight migration on the database file before the main app has a chance to backup the database sqlite file. I can just prevent the lightweight migration from happening when an app extension loads the persistent store (and only do lightweight migrations from the main app), but it might end up in a situation with incompatible formats for the extension, so I'm looking for a sturdier solution. When an app is installed (or an update to the app is installed), is there a way to check and control the order of the extensions that is installed / loaded by the system? That would help control the problem.
0
0
601
Jan ’24
SwiftUI: List onInsert to accept all data types
Hi, I am building a List with a list of files saved in my app. I also want this to accept drops of multiple types of files (images, audio, PDFs, Excel, Pages etc) ... basically anything that be dragged-and-dropped from the iOS system or apps like Mail, iCloud Drive etc. I'm trying to find a good way to handle this. The best I've come across is adding the onInsert option to accept UTTypes, like this: List { ... } .onInsert(of: [UTType.data], perform: dropAction) But now I'm not sure how I can load the object that was dropped here. From some examples I've seen, If I registered the UTType.image instead, I could load it in the dropAction handler like this: item.loadObject(ofClass: UIImage.self) { image, _ in DispatchQueue.main.async { print("Image type dropped") } } But how does that work for 'data' types. Or am I supposed to list out all the data types separately?
0
0
538
Mar ’24
SwiftUI List with Core Data / SwiftData - memory usage while scrolling
I want to display a list of 'contacts' in my app, loaded from a local Core Data sqlite database. Currently, I use UIKit, and with UITableView's cell reuse, even with 5000+ rows, the memory usage is great ... it loads at about 80MB and stays around that no matter how much I scroll up or down the list. I implemented the same list with SwiftUI List, and the memory usage while scrolling is very different ... the initial load is about the same, but each time I go down the whole list, it adds 20-30MB to the memory usage (according to Xcode). Is this a side-effect of using SwiftUI's List, or am I doing something wrong here? Here's the implementation: struct CJContactsListView: View { @SectionedFetchRequest var sectionContacts: SectionedFetchResults<String, Person> init() { let fetchRequest = Person.allContactsFetchRequest() _sectionContacts = SectionedFetchRequest(fetchRequest: fetchRequest, sectionIdentifier: \.normalizedSectionLetter!, animation: .default) } var body: some View { List { ForEach(sectionContacts) { section in Section(header: Text(section.id)) { ForEach(section) { person in CJContactsListLabelRowView(person: person) } } } } .listStyle(.plain) } } struct CJContactsListLabelRowView: View { @ObservedObject var person: Person var body: some View { HStack (alignment: .center, spacing: 8) { VStack (alignment: .leading){ if let displayName = person.displayName { Text(displayName).font(.headline) } if let companyName = person.companyName { Text(companyName).font(.subheadline).foregroundColor(.secondary) } } } } } extension Person: Identifiable { public var id: String { return self.objectID.uriRepresentation().absoluteString } public static func allContactsFetchRequest() -> NSFetchRequest<Person> { let request = Person.fetchRequest() request.sortDescriptors = Person.makeSortDescriptors() request.predicate = NSPredicate(format: "(isContactArchived == nil || isContactArchived == 0)") request.fetchBatchSize = 100 request.relationshipKeyPathsForPrefetching = ["tags"] return request } } There isn't a visible performance issue in my testing (i.e. I don't see a 'stutter' when scrolling really fast), but the memory profile growing does concern me, especially when this isn't a problem in UIKit. I've tested the "Earthquakes" sample project from Apple and it seems to display the same issue (memory profile grows substantially as the user scrolls down the list). Would love to know if there's a way to avoid this issue.
0
3
866
Mar ’24
Deep links for In-app Event page
Hi, I am planning to add a In-App Event for a major update to my app. The Create In-App Event page in App Store Connect seems to want a "Event Deep Link", and I'm not sure how to generate that. I've read about universal links but they seem complicated, and I just want the users to be able to open my app, I don't want a custom landing page in the app. Can I pass in the URL scheme for my app, or something else that's super-simple and gets the job done (like the App Store URL for the app)?
0
2
819
Jun ’24
Using OpenIntents with voice
Hi, I am working with AppIntents, and have created an OpenIntent with a target using a MyAppContact AppEntity that I have created. This works fine when running from Shortcuts because it pops up a list of options from the 'suggestedEntities` method. But It doesn't work well when using with Siri. It invokes the AppIntent, but keeps repeatedly asking for the value of the 'target' entity, which you can't really pass in with voice. What's the workaround here? Can an OpenIntent be activated by voice as well?
0
0
803
Aug ’24
Using AssistantEntity with existing AppEntities for iOS17
Hi, I have an existing app with AppEntities defined, that works on iOS16 and iOS17. The AppEntities also have EntityPropertyQuery defined, so they work as 'find intents'. I want to use the new @AssistantEntity on iOS18, while supporting the previous versions. What's the best way to do this? For e.g. I have a 'person' AppEntity: @available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, *) struct CJLogAppEntity: AppEntity { static var defaultQuery = CJLogAppEntityQuery() .... } struct CJLogAppEntityQuery: EntityPropertyQuery { ... } How do I adopt this with @AssistantEntity(schema: .journal.entry) for iOS18, while maintaining compatibility with iOS16 and 17?
0
1
631
Sep ’24
SwiftUI warning for "Publishing changes from within view updates" on macOS
I have a simple example of a List with multiple selection. When I run it on macOS, and select an item from the list, it works fine but I get a warning in the console: Publishing changes from within view updates is not allowed, this will cause undefined behavior Interestingly, it doesn't produce a purple 'issue' in the Issues navigator, but as I change selection, I keep getting this warning. Also, the warning doesn't show when running the same code on iOS. Here is code to reproduce it: struct TestListSelection: View { let testArray = [TestItem(itemValue: 1), TestItem(itemValue: 2), TestItem(itemValue: 3), TestItem(itemValue: 4)] @ObservedObject var listOptions: TestListViewModel var body: some View { List (selection: $listOptions.multipleSelection) { Section("Header") { ForEach (testArray, id: \.self) { item in Button { print("row tapped - \(item.itemValue)") } label: { VStack { HStack { Text(item.itemString) } } } .buttonStyle(.plain) } } } .listStyle(.plain) } } public struct TestItem: Identifiable, Hashable { public let id = UUID() let itemValue: Int var itemString: String { get { return "test \(itemValue)" } } } @MainActor public class TestListViewModel: NSObject, ObservableObject { @Published public var multipleSelection = Set<TestItem>() } I annotated the view model with @MainActor as suggested in other threads, but it doesn't silence the warning. If I move the multipleSelection into the view itself, and make it a @State variable (bypassing the viewModel completely), it works and doesn't produce a warning. But I need it work so I can pass in selection from the UIKit part of the app as well. I also can't migrate to @Observable because my main project has to support iOS15 and above. Any clue why this is happening on macOS specifically, and what I can do to avoid it?
0
0
571
Oct ’24
UIDocumentPickerViewController: open to specific folder
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.
0
0
491
Dec ’24
WidgetKit: add new widget to bundle
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?
0
0
80
Mar ’25
Core Spotlight searching only for title
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.
0
0
125
Jun ’25
UITabBarController not allowing scroll content behind it
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
0
0
208
Aug ’25
Issue with iOS26 and hiding UITabBar
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
0
0
252
Aug ’25
iPadOS keyboard formatting options
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
0
0
149
Sep ’25