This commit is contained in:
Stephen 2026-05-31 20:07:01 -04:00
parent 34d0f80e3a
commit 1faead2751
3 changed files with 132 additions and 19 deletions

View file

@ -482,7 +482,7 @@
"$(PROJECT_DIR)/StikDebug/idevice",
);
MACOSX_DEPLOYMENT_TARGET = 15.1;
MARKETING_VERSION = 3.1.4;
MARKETING_VERSION = 3.1.5;
PRODUCT_BUNDLE_IDENTIFIER = com.stik.stikdebug;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -544,7 +544,7 @@
"$(PROJECT_DIR)/StikDebug/idevice",
);
MACOSX_DEPLOYMENT_TARGET = 15.1;
MARKETING_VERSION = 3.1.4;
MARKETING_VERSION = 3.1.5;
PRODUCT_BUNDLE_IDENTIFIER = com.stik.stikdebug;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";

View file

@ -6,14 +6,19 @@
import Foundation
public extension ProcessInfo {
var hasTXMClassic: Bool {
ProcessInfo.processInfo.isiOSAppOnMac ? false : ProcessInfo.detectLocalTXM()
}
var hasTXM: Bool {
if isTXMOverridden {
return true
}
return ProcessInfo.hasTXMSupport(
operatingSystemVersion: operatingSystemVersion,
localTXMDetector: ProcessInfo.detectLocalTXM
isIOS266OrNewer: ProcessInfo.isIOS266OrNewer,
hasTXMClassic: hasTXMClassic,
hardwareIdentifier: hardwareIdentifier()
)
}
@ -21,14 +26,52 @@ public extension ProcessInfo {
UserDefaults.standard.bool(forKey: UserDefaults.Keys.txmOverride)
}
static func hasTXMSupport(
operatingSystemVersion: OperatingSystemVersion,
localTXMDetector: () -> Bool
internal static func hasTXMSupport(
isIOS266OrNewer: Bool,
hasTXMClassic: Bool,
hardwareIdentifier: String
) -> Bool {
guard operatingSystemVersion.majorVersion >= 26 else {
if isIOS266OrNewer, !hasTXMClassic {
let firstTXM = 14.2
let iPadTXM = 14.5
if let ver = ProcessInfo.processInfo.deviceVersion(from: hardwareIdentifier) {
if hardwareIdentifier.hasPrefix("iPad") {
return ver >= iPadTXM
} else {
return ver >= firstTXM
}
}
return false
}
return localTXMDetector()
return hasTXMClassic
}
func deviceVersion(from identifier: String) -> Double? {
let iPhonePattern = #"iPhone(\d+),(\d+)"#
let iPadPattern = #"iPad(\d+),(\d+)"#
let extractVersion: (_ pattern: String) -> Double? = { pattern in
guard let regex = try? NSRegularExpression(pattern: pattern),
let match = regex.firstMatch(
in: identifier,
range: NSRange(identifier.startIndex..., in: identifier)
),
let majorRange = Range(match.range(at: 1), in: identifier),
let minorRange = Range(match.range(at: 2), in: identifier),
let major = Double(identifier[majorRange]),
let minor = Double(identifier[minorRange])
else {
return nil
}
let divisor = pow(10.0, Double(String(Int(minor)).count))
return major + (minor / divisor)
}
return extractVersion(iPhonePattern) ?? extractVersion(iPadPattern)
}
private static func detectLocalTXM() -> Bool {
@ -41,4 +84,23 @@ public extension ProcessInfo {
access("\($0)/usr/standalone/firmware/FUD/Ap,TrustedExecutionMonitor.img4", F_OK) == 0
} ?? false
}
private static var isIOS266OrNewer: Bool {
if #available(iOS 26.6, *) {
return true
}
return false
}
private func hardwareIdentifier() -> String {
var systemInfo = utsname()
uname(&systemInfo)
return withUnsafePointer(to: &systemInfo.machine) {
$0.withMemoryRebound(to: CChar.self, capacity: 1) {
String(cString: $0)
}
}
}
}

View file

@ -11,20 +11,71 @@ import Testing
struct StikDebugTests {
@Test func txmDetectionIgnoresFirmwareFileBeforeIOS26() async throws {
let isSupported = ProcessInfo.hasTXMSupport(
operatingSystemVersion: OperatingSystemVersion(majorVersion: 18, minorVersion: 7, patchVersion: 2),
localTXMDetector: { true }
@Test func txmDetectionUsesClassicTXMBeforeIOS266() async throws {
#expect(
ProcessInfo.hasTXMSupport(
isIOS266OrNewer: false,
hasTXMClassic: false,
hardwareIdentifier: "iPhone15,2"
) == false
)
#expect(
ProcessInfo.hasTXMSupport(
isIOS266OrNewer: false,
hasTXMClassic: true,
hardwareIdentifier: "iPhone1,1"
) == true
)
#expect(isSupported == false)
}
@Test func txmDetectionRequiresLocalTXMOnIOS26() async throws {
let iOS26 = OperatingSystemVersion(majorVersion: 26, minorVersion: 0, patchVersion: 0)
@Test func txmDetectionUsesClassicTXMWhenAvailableOnIOS266() async throws {
#expect(
ProcessInfo.hasTXMSupport(
isIOS266OrNewer: true,
hasTXMClassic: true,
hardwareIdentifier: "iPhone1,1"
) == true
)
}
#expect(ProcessInfo.hasTXMSupport(operatingSystemVersion: iOS26, localTXMDetector: { false }) == false)
#expect(ProcessInfo.hasTXMSupport(operatingSystemVersion: iOS26, localTXMDetector: { true }) == true)
@Test func txmDetectionFallsBackToIPhoneThresholdOnIOS266() async throws {
#expect(
ProcessInfo.hasTXMSupport(
isIOS266OrNewer: true,
hasTXMClassic: false,
hardwareIdentifier: "iPhone14,1"
) == false
)
#expect(
ProcessInfo.hasTXMSupport(
isIOS266OrNewer: true,
hasTXMClassic: false,
hardwareIdentifier: "iPhone14,2"
) == true
)
}
@Test func txmDetectionFallsBackToIPadThresholdOnIOS266() async throws {
#expect(
ProcessInfo.hasTXMSupport(
isIOS266OrNewer: true,
hasTXMClassic: false,
hardwareIdentifier: "iPad14,4"
) == false
)
#expect(
ProcessInfo.hasTXMSupport(
isIOS266OrNewer: true,
hasTXMClassic: false,
hardwareIdentifier: "iPad14,5"
) == true
)
}
@Test func deviceVersionParsesSupportedIdentifiers() async throws {
#expect(ProcessInfo.processInfo.deviceVersion(from: "iPhone14,2") == 14.2)
#expect(ProcessInfo.processInfo.deviceVersion(from: "iPad14,5") == 14.5)
#expect(ProcessInfo.processInfo.deviceVersion(from: "Mac14,2") == nil)
}
}