Calling NSException.raise() in Swift
The problem seems to have been that I didn't treat the error as an optional. The following works:
var error: NSError?
NSException.raise("Exception", format:"Error: %@", arguments:getVaList([error!]))
Or you could do the following in case error is nil:
NSException.raise("Exception", format:"Error: %@", arguments:getVaList([error ?? "nil"]))
Manually throw exception instead of returning value in Swift
I needed fatalError("")
func head<T>(xs: [T]) -> T {
if (xs.count > 0) {
return xs.first!
} else {
fatalError("list is empty")
}
}
this code works just fine.
Catching NSException in Swift
Here is some code, that converts NSExceptions to Swift 2 errors.
Now you can use
do {
try ObjC.catchException {
/* calls that might throw an NSException */
}
}
catch {
print("An error ocurred: \(error)")
}
ObjC.h:
#import <Foundation/Foundation.h>
@interface ObjC : NSObject
+ (BOOL)catchException:(void(^)(void))tryBlock error:(__autoreleasing NSError **)error;
@end
ObjC.m
#import "ObjC.h"
@implementation ObjC
+ (BOOL)catchException:(void(^)(void))tryBlock error:(__autoreleasing NSError **)error {
@try {
tryBlock();
return YES;
}
@catch (NSException *exception) {
*error = [[NSError alloc] initWithDomain:exception.name code:0 userInfo:exception.userInfo];
return NO;
}
}
@end
Don't forget to add this to your "*-Bridging-Header.h":
#import "ObjC.h"
How should I use NSSetUncaughtExceptionHandler in Swift
Update
With Swift 2, you can pass Swift functions and closures as C function pointer. See Martin R's answer below.
Original answer
You can't, as of Xcode 6 beta 6.
Swift does support passing around function pointers, but they're treated pretty much like opaque pointers. You can't neither define a C function pointer to a Swift function nor can you call a C function pointer in Swift.
That means you call NSSetUncaughtExceptionHandler()
from Swift, but the handler must be implemented in Objective-C. You need a header file like this:
volatile void exceptionHandler(NSException *exception);
extern NSUncaughtExceptionHandler *exceptionHandlerPtr;
and in the implementation, you need something like this:
volatile void exceptionHandler(NSException *exception) {
// Do stuff
}
NSUncaughtExceptionHandler *exceptionHandlerPtr = &exceptionHandler;
After you imported the header file in the Swift bridging header, you can set up the exception handler as usual:
NSSetUncaughtExceptionHandler(exceptionHandlerPtr)
Is it possible to throw a RuntimeException in Swift without declaring it?
The error handling mechanism in Swift does not involve raising unchecked (runtime) exceptions. Instead, explicit error handling is required. Swift is certainly not the only recently designed language to go for this design – for instance Rust and Go also in their own ways also require explicitly describing the error paths in your code. In Objective-C the unchecked exception feature exists, but is largely used only for communicating programmer errors, with the notable exception of a few key Cocoa classes such as NSFileHandle
which tends to catch people out.
Technically you do have the ability to raise Objective-C exceptions in Swift with the use of NSException(name: "SomeName", reason: "SomeReason", userInfo: nil).raise()
as is explained in this excellent answer to this question, arguably a duplicate of your question. You really shouldn't raise NSExceptions though (not least because you have no Objective-C exception catching language feature available to you in Swift).
Why did they go with this design? Apple's "Error Handling in Swift 2.0" document explains the rationale clearly. Quoting from there:
This approach […] is very similar to the error handling model manually
implemented in Objective-C with the NSError convention. Notably, the
approach preserves these advantages of this convention:
- Whether a method produces an error (or not) is an explicit part of its API contract.
- Methods default to not producing errors unless they are explicitly marked.
- The control flow within a function is still mostly explicit: a maintainer can tell exactly which statements can produce an error, and
a simple inspection reveals how the function reacts to the error.- Throwing an error provides similar performance to allocating an error and returning it – it isn’t an expensive, table-based stack
unwinding process. Cocoa APIs using standard NSError patterns can be
imported into this world automatically. Other common patterns (e.g.
CFError, errno) can be added to the model in future versions of Swift.
[…]
As to basic syntax, we decided to stick with the familiar language of
exception handling. […] by and large, error propagation in this
proposal works like it does in exception handling, and people are
inevitably going to make the connection.
Getting a Swift run-time error (NSException)
You have outlets defined for your view controller in a storyboard or .xib file. One of them is called "btnRoll" and was linked to the controller at some point. The matching property does not exist in code.
Possible reasons are: you deleted the code without unlinking the outlet or you have the wrong view controller defined as the view's owner.
Catch Objective-C exception in Swift
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;
}
Related Topics
How to Hash a String to Sha512 in Swift
Identify Mkpointannotation in Mapview
Workarounds for Generic Variable in Swift
How to Grant Discoveruserinfowithuserrecordid Permission
How to Remove Top Space of 'Form' in Swiftui
How to Add Floating Button on Top of the Uitableview
How to Draw Two Polylines in Different Colors in Mapkit
Combining Custom Property Wrapper with @Published
Using a Metal Shader in Scenekit
Swiftui Scroll/List Scrolling Events
Nspopover to Start in a Detached State
Correct Way to Call "Realloc" in Swift with a Float Array
Shared Cookies with Wkprocesspool for Wkwebview in Swift
Problems Accessing Calendar Using Ekeventstore on Osx Sierra with Swift 3
Does Untimeintervalnotificationtrigger Nexttriggerdate() Give the Wrong Date