I am trying to set the value of an @objc
object in my Swift code using obj.setValue(value, forKey: key)
.
It works fine when the object has the
Swift 5 version with utility error type:
NS_INLINE NSException * _Nullable ExecuteWithObjCExceptionHandling(void(NS_NOESCAPE^_Nonnull tryBlock)(void)) {
@try {
tryBlock();
}
@catch (NSException *exception) {
return exception;
}
return nil;
}
public struct NSExceptionError: Swift.Error {
public let exception: NSException
public init(exception: NSException) {
self.exception = exception
}
}
public struct ObjC {
public static func perform(workItem: () -> Void) throws {
let exception = ExecuteWithObjCExceptionHandling {
workItem()
}
if let exception = exception {
throw NSExceptionError(exception: exception)
}
}
}
Not the answer I was hoping for, unfortunately:
Although Swift error handling resembles exception handling in Objective-C, it is entirely separate functionality. If an Objective-C method throws an exception during runtime, Swift triggers a runtime error. There is no way to recover from Objective-C exceptions directly in Swift. Any exception handling behavior must be implemented in Objective-C code used by Swift.
Excerpt From: Apple Inc. “Using Swift with Cocoa and Objective-C (Swift 2.1).” iBooks. https://itun.es/ca/1u3-0.l
My next plan of attack is to add an Objective-C function I can call out to that will wrap the attempt in @try
/@catch
. This really sucks, Apple.
I wanted to call out the answer given in this question:
Catching NSException in Swift
as you can still use the Swift do/catch with the call in a natural fashion, the next best thing to Swift actually catching ObjC exceptions as it should.
see this answer:
//
// ExceptionCatcher.h
//
#import <Foundation/Foundation.h>
NS_INLINE NSException * _Nullable tryBlock(void(^_Nonnull tryBlock)(void)) {
@try {
tryBlock();
}
@catch (NSException *exception) {
return exception;
}
return nil;
}