I recently wanted to get rid of Carthage in an iOS application I work on so I can use Xcode 12.
The application previously used Carthage to build binaries for iOS and watchOS platforms. When I try to run Carthage bootstrap using the Xcode 12 build tools I got complaints around duplicate architectures for arm64. Issue discussed here; https://github.com/Carthage/Carthage/blob/master/Documentation/Xcode12Workaround.md
So I would like to just get rid of Carthage entirely and with the move to Swift 5.3 in Xcode 12 we could now use binary dependencies through SPM.
I went through each of the dependencies and started to build them as XCFrameworks because that is required by SPM. I then collected all the frameworks together into a single repo and inside that repo I had a Package.swift like so;
// swift-tools-version:5.3 import PackageDescription let package = Package( name: "LegacyKit", products: [ .library( name: "LegacyKit-iOS", targets: ["DepA", "DepB", "DepC"]), .library( name: "LegacyKit-watchOS", targets: ["DepA", "DepB"]) ], targets: [ .target( name: "LegacyKit", dependencies: ), .binaryTarget(name: "DepA", path: "DepA.xcframework"), .binaryTarget(name: "DepB", path: "DepB.xcframework"), .binaryTarget(name: "DepC", path: "DepC.xcframework"), ] )
So then in my main app I create a new framework called LegacyKitWrapper and LegacyKitWatchOSWrapper than added the libraries from LegacyKit and linked that inside each of my targets (iOS App, watchOS app, Siri intent).
This works fine for development. My code runs and does everything it needs to. But when I sent my app to TestFlight to be distributed to internal testers the App was rejected by Apple for the following reason;
ITMS-90338: Non-public API usage - The app references non-public selectors in MyApp: arrival, currentConfiguration, dataContainerURL, departure, destinationStop, dismissNotification, expand, initWithDataSources:, initWithUrl:, labelWithType:, originStop, removeItemForKey:, rowItems, scheduled, scheduledDate, sectionControllers, sectionOffset, setAnalytics:, setDownloading:, setFinalDestinations:, setMessagingDelegate:, setRoundedCorners:, setSectionControllers:, setString:forKey:error:, setTextFontSize:, stations, stops, transform:, validationBlock, zipArchiveDidUnzipArchiveAtPath:zipInformation:unzippedPath:, zipArchiveDidUnzipFileAtIndex:totalFiles:archivePath:fileInformation:, zipArchiveDidUnzipFileAtIndex:totalFiles:archivePath:unzippedFilePath:, zipArchiveProgressEvent:total:, zipArchiveShouldUnzipFileAtIndex:totalFiles:archivePath:fileInformation:, zipArchiveWillUnzipArchiveAtPath:zipInformation:, zipArchiveWillUnzipFileAtIndex:totalFiles:archivePath:fileInformation:. If method names in your source code match the private Apple APIs listed above, altering your method names will help prevent this app from being flagged in future submissions. In addition, note that one or more of the above APIs may be located in a static library that was included with your app. If so, they must be removed. For further information, visit the Technical Support Information
Some of those symbols I can see in my swift interface files inside my XCFrameworks, for example stations, arrivals, etc - but here is my question - why is this a problem with my new configuration (Binary dependencies through Swift Package Manager) when it worked before with my Carthage setup.
Is there something I can do to fix this? Or is it due to the libraries in Swift Package Manager being statically imported inside that framework I've made in my app? As far as I can tell Swift Package Manager decides this for you, and there is no way to force it to be dynamic to make it replicate the previous Carthage setup.
I mention this as the complaint from apple mentions
that one of the above APIs may be located in a static library that was included with your app.
This apparently seems to be a "bug" caused by SPM from Xcode 11.4 and up: https://github.com/renaudjenny/Swift-Package-Manager-Static-Dynamic-Xcode-Bug
Could anyone shed some light on why this error now occurs?