After moving to Xcode 14 I'm getting inconsistent behavior in my throwing functions. This call works sometimes, and other times it behaves completely differently despite all the inputs and runtime conditions being the same.
And it always worked in previous versions of Swift/Xcode 13.
The method is properly translated to a throwing method in Swift. When the ObjC code runs, Swift is indeed generating an NSError** and passsing it into the ObjC method. On inspection I can see it properly sets the NSError*. Stepping through instructions it never hits the return SecureFile statement as expected.
And yet the Swift code receives a SecureFile object that is not initialized and proceeds to crash.
If I return NULL in the error path, the error is successfully caught. Someone pointed out that it seems to be behavior like swift_error(null_result)
instead of swift_error(nonnull_error)
SomeAPI.h
- (nonnull SecureFile *)getSecureFile:(nonnull NSString *)fileName
:(NSError **)error
__attribute__((swift_error(nonnull_error)));
SomeAPI.m
- (nonnull SecureFile *)getSecureFile:(nonnull NSString *)fileName
:(NSError **)error {
// Some code up here that fails
if (secureFile != NULL) {
return secureFile;
} else {
*error = [NSError errorWithDomain: MyErrorDomain
code: NotLoggedIn
userInfo:@{
NSLocalizedDescriptionKey : @"User is not logged in!"
}];
}
}
SomeClass.swift
do {
let secureFile = try someAPI.getSecureFile("test")
return secureFile.decode()
} catch {
// Some recovery code here
}