From f4037a188afd5e32437f58d5527ee385ff686a6b Mon Sep 17 00:00:00 2001 From: TZGyn Date: Sat, 19 Sep 2026 19:25:01 +0800 Subject: [PATCH] Sign the iOS app for real devices and stop bundling the static archives --- apps/ios/Koins/SelfTest.swift | 39 +++++++++++++++++++++-------------- apps/ios/project.yml | 8 +++++-- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/apps/ios/Koins/SelfTest.swift b/apps/ios/Koins/SelfTest.swift index 3a4660c..1d23dd2 100644 --- a/apps/ios/Koins/SelfTest.swift +++ b/apps/ios/Koins/SelfTest.swift @@ -9,16 +9,27 @@ enum SelfTest { /// Writes to both stdout and the unified log so results are visible however /// the app was launched. + private static var report: [String] = [] + private static func emit(_ line: String) { print(line) os_log("%{public}@", log: log, type: .default, line) + report.append(line) + } + + /// Writes the collected lines into the app container so the result can be + /// read back off the device (console output is not always reachable). + private static func flushReport() { + guard let documents = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return } + let url = documents.appendingPathComponent("koins-selftest.txt") + try? report.joined(separator: "\n").write(to: url, atomically: true, encoding: .utf8) } static func runIfRequested() { if ProcessInfo.processInfo.arguments.contains("-koinsSelfTest") { - print("KOINS_SELFTEST begin") + emit("KOINS_SELFTEST begin") run() - print("KOINS_SELFTEST end") + emit("KOINS_SELFTEST end") } if ProcessInfo.processInfo.arguments.contains("-koinsSelfTestNetwork") { runNetwork() @@ -88,6 +99,7 @@ enum SelfTest { restoreWallets() emit("KOINS_NET end") + flushReport() } } @@ -97,9 +109,7 @@ enum SelfTest { func expect(_ name: String, _ actual: String, _ wanted: String) { let ok = actual.lowercased() == wanted.lowercased() if !ok { failures += 1 } - let line = "KOINS_SELFTEST \(name): \(ok ? "PASS" : "FAIL") \(actual)" - print(line) - os_log("%{public}@", log: log, type: .default, line) + emit("KOINS_SELFTEST \(name): \(ok ? "PASS" : "FAIL") \(actual)") } expect("ripemd160", Hex.encode(RIPEMD160.hash(Array("abc".utf8))), @@ -114,7 +124,7 @@ enum SelfTest { expect("ed25519 address", keypair.address, edAddress) } else { failures += 1 - print("KOINS_SELFTEST ed25519: FAIL keypair threw") + emit("KOINS_SELFTEST ed25519: FAIL keypair threw") } // secp256k1 vector: exercises the OpenSSL-backed derivation on device. @@ -128,7 +138,7 @@ enum SelfTest { expect("secp256k1 address", keypair.address, secpAddress) } catch { failures += 1 - print("KOINS_SELFTEST secp256k1: FAIL \(error)") + emit("KOINS_SELFTEST secp256k1: FAIL \(error)") } // Serialization + hashing reference vector. @@ -189,12 +199,12 @@ enum SelfTest { expect("bip32 level \(level)", Hex.encode(child.privateKey), expected) } else { failures += 1 - print("KOINS_SELFTEST bip32 level \(level): FAIL derivation returned nil") + emit("KOINS_SELFTEST bip32 level \(level): FAIL derivation returned nil") } } } else { failures += 1 - print("KOINS_SELFTEST bip32 master: FAIL") + emit("KOINS_SELFTEST bip32 master: FAIL") } let mnemonicCases: [(String, String, String)] = [ @@ -212,7 +222,7 @@ enum SelfTest { expect("bip44 address #\(position)", keypair.address, vector.2) } catch { failures += 1 - print("KOINS_SELFTEST bip44 #\(position): FAIL \(error)") + emit("KOINS_SELFTEST bip44 #\(position): FAIL \(error)") } } @@ -227,15 +237,14 @@ enum SelfTest { let s = DER.signatureScalar(signature) { expect("secp256k1 signature is low-S", s.lessThanOrEqual(half) ? "yes" : "no", "yes") } - print("KOINS_SELFTEST secp256k1 signature len: \(signature.count)") + emit("KOINS_SELFTEST secp256k1 signature len: \(signature.count)") } else { failures += 1 - print("KOINS_SELFTEST secp256k1 sign: FAIL") + emit("KOINS_SELFTEST secp256k1 sign: FAIL") } - let summary = "KOINS_SELFTEST summary: \(failures == 0 ? "ALL PASS" : "\(failures) FAILURE(S)")" - print(summary) - os_log("%{public}@", log: log, type: .default, summary) + emit("KOINS_SELFTEST summary: \(failures == 0 ? "ALL PASS" : "\(failures) FAILURE(S)")") + flushReport() } } diff --git a/apps/ios/project.yml b/apps/ios/project.yml index 19f7501..4c4e501 100644 --- a/apps/ios/project.yml +++ b/apps/ios/project.yml @@ -18,13 +18,17 @@ targets: type: application platform: iOS sources: - - Koins + - path: Koins + excludes: + # Static archives are linked via LIBRARY_SEARCH_PATHS, not bundled. + - "Monero/libs" settings: base: PRODUCT_BUNDLE_IDENTIFIER: com.koins.app INFOPLIST_FILE: Koins/Info.plist CODE_SIGN_STYLE: Automatic - CODE_SIGNING_ALLOWED: NO + DEVELOPMENT_TEAM: RX6767S6BW + CODE_SIGNING_ALLOWED[sdk=iphonesimulator*]: NO SWIFT_OBJC_BRIDGING_HEADER: Koins/Bridge/Koins-Bridging-Header.h OTHER_LDFLAGS[sdk=iphoneos*]: - "$(inherited)"