From d2ada6574390ccdbe202acd16016ec207adff588 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 4 Mar 2026 11:38:12 +0100 Subject: [PATCH 1/5] To make this change clear: - C string functions work with byte arrays and are perfectly happy with UTF-8, which is backward-compatible with ASCII. - iOS file paths support full Unicode. This way we handle the nil properly and also use modern utf8 --- GenericApp/GenericApp/AppDelegate.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/GenericApp/GenericApp/AppDelegate.swift b/GenericApp/GenericApp/AppDelegate.swift index 73ef0ba..9524389 100644 --- a/GenericApp/GenericApp/AppDelegate.swift +++ b/GenericApp/GenericApp/AppDelegate.swift @@ -46,7 +46,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, URLSessionDelegate { let documentsDirectory = paths[0] let fileName = "\(Date()).log" let logFilePath = (documentsDirectory as NSString).appendingPathComponent(fileName) - freopen(logFilePath.cString(using: String.Encoding.ascii)!, "a+", stderr) + if let cPath = logFilePath.cString(using: .utf8) { + freopen(cPath, "a+", stderr) + } if launchOptions?[UIApplication.LaunchOptionsKey.location] != nil { NSLog("%@", "App started from location update") From 38aff3bd14844746bbdcf722379d401d5f4987bf Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 4 Mar 2026 14:02:59 +0100 Subject: [PATCH 2/5] Fixed CI/CD --- .github/workflows/ci_cd.yml | 45 +++++++++---------------------------- 1 file changed, 11 insertions(+), 34 deletions(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 8525b54..e0aaa68 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -30,39 +30,12 @@ jobs: - name: Checkout uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - - name: Install the Apple certificate and provisioning profile + - name: Install App Store Connect API key env: - BUILD_CERTIFICATE_BASE64: ${{ secrets.APPLE_BUILD_CERTIFICATE_BASE64 }} - P12_PASSWORD: ${{ secrets.APPLE_BUILD_CERT_PASSWORD }} - GENERIC_APP_PROVISION_PROFILE: ${{ secrets.APPLE_GENERIC_APP_PROVISION_PROFILE_BASE64 }} - NOTIFICATION_SERVICE_PROVISION_PROFILE: ${{ secrets.APPLE_NOTIFICATION_SERVICE_PROVISION_PROFILE_BASE64 }} - KEYCHAIN_PASSWORD: ${{ secrets.APPLE_KEYCHAIN_PASSWORD }} + APP_STORE_CONNECT_PRIVATE_KEY: ${{ secrets.APP_STORE_CONNECT_PRIVATE_KEY }} run: | - # create variables - CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12 - PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision - NOTIDICATION_SERVICE_PP_PATH=$RUNNER_TEMP/notification_service_pp.mobileprovision - KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db - - # import certificate and provisioning profile from secrets - echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH - echo -n "$GENERIC_APP_PROVISION_PROFILE" | base64 --decode -o $PP_PATH - echo -n "$NOTIFICATION_SERVICE_PROVISION_PROFILE" | base64 --decode -o $NOTIDICATION_SERVICE_PP_PATH - - # create temporary keychain - security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH - security set-keychain-settings -lut 21600 $KEYCHAIN_PATH - security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH - - # import certificate to keychain - security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH - security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH - security list-keychain -d user -s $KEYCHAIN_PATH - - # apply provisioning profile - mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles - cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles - cp $NOTIDICATION_SERVICE_PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles + mkdir -p ~/private_keys + echo -n "$APP_STORE_CONNECT_PRIVATE_KEY" > ~/private_keys/AuthKey_${{ secrets.APP_STORE_CONNECT_KEY_ID }}.p8 - name: Swift Package Manager cache uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4 @@ -79,7 +52,11 @@ jobs: -sdk iphoneos \ -configuration Release \ -destination generic/platform=iOS \ - clean archive + -allowProvisioningUpdates \ + -authenticationKeyPath ~/private_keys/AuthKey_${{ secrets.APP_STORE_CONNECT_KEY_ID }}.p8 \ + -authenticationKeyID ${{ secrets.APP_STORE_CONNECT_KEY_ID }} \ + -authenticationKeyIssuerID ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }} \ + clean archive # - name: Export IPA # env: @@ -87,7 +64,7 @@ jobs: # run: | # EXPORT_OPTS_PATH=$RUNNER_TEMP/ExportOptions.plist # echo -n "$EXPORT_OPTIONS_PLIST" | base64 --decode -o $EXPORT_OPTS_PATH - # xcodebuild -exportArchive -archivePath $RUNNER_TEMP/genericapp.xcarchive -exportOptionsPlist $EXPORT_OPTS_PATH -exportPath $RUNNER_TEMP/build + # xcodebuild -exportArchive -archivePath $RUNNER_TEMP/genericapp.xcarchive -exportOptionsPlist $EXPORT_OPTS_PATH -exportPath $RUNNER_TEMP/build # - name: Upload IPAs # if: success() @@ -95,4 +72,4 @@ jobs: # with: # name: ipas # path: | - # **/*.ipa + # **/*.ipa \ No newline at end of file From 90dd28b07434fd06c9efa3edbc3c395255588dc8 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 4 Mar 2026 14:15:19 +0100 Subject: [PATCH 3/5] Use macos-latest runner now that it points to macos-15 --- .github/workflows/ci_cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index e0aaa68..b8f82bd 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -24,7 +24,7 @@ jobs: build: name: CI/CD - runs-on: macos-15 # is not the macos-latest, which should be by the end of August 2025 + runs-on: macos-latest steps: - name: Checkout From 9b2ea3c1966d684d798fdf1f409d4013bf87225e Mon Sep 17 00:00:00 2001 From: Michael Rademaker Date: Wed, 4 Mar 2026 16:10:56 +0100 Subject: [PATCH 4/5] Update GenericApp/GenericApp/AppDelegate.swift Co-authored-by: Eric Bariaux <375613+ebariaux@users.noreply.github.com> --- GenericApp/GenericApp/AppDelegate.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/GenericApp/GenericApp/AppDelegate.swift b/GenericApp/GenericApp/AppDelegate.swift index 9524389..2a23aea 100644 --- a/GenericApp/GenericApp/AppDelegate.swift +++ b/GenericApp/GenericApp/AppDelegate.swift @@ -42,7 +42,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate, URLSessionDelegate { UNUserNotificationCenter.current().delegate = self // if the app was launched because of geofencing - let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) + + // Redirects NSLog calls to file let documentsDirectory = paths[0] let fileName = "\(Date()).log" let logFilePath = (documentsDirectory as NSString).appendingPathComponent(fileName) From 06d24a3ade07a125191049f517beb186018929b0 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 4 Mar 2026 16:45:39 +0100 Subject: [PATCH 5/5] Replace NSSearchPathForDirectoriesInDomains with FileManager API NSSearchPathForDirectoriesInDomains is no longer available in Swift with the iOS 18.5 SDK (Xcode 16.4), which macos-latest now uses. --- GenericApp/GenericApp/AppDelegate.swift | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/GenericApp/GenericApp/AppDelegate.swift b/GenericApp/GenericApp/AppDelegate.swift index 2a23aea..fc2e5c4 100644 --- a/GenericApp/GenericApp/AppDelegate.swift +++ b/GenericApp/GenericApp/AppDelegate.swift @@ -44,11 +44,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate, URLSessionDelegate { // Redirects NSLog calls to file - let documentsDirectory = paths[0] - let fileName = "\(Date()).log" - let logFilePath = (documentsDirectory as NSString).appendingPathComponent(fileName) - if let cPath = logFilePath.cString(using: .utf8) { - freopen(cPath, "a+", stderr) + if let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first { + let fileName = "\(Date()).log" + let logFilePath = documentsDirectory.appendingPathComponent(fileName).path + if let cPath = logFilePath.cString(using: .utf8) { + freopen(cPath, "a+", stderr) + } } if launchOptions?[UIApplication.LaunchOptionsKey.location] != nil {