I have an app which relies on Apple's JavaScriptCore
heavily.
When I do:
let context = JSContext()
the context
is an optional type.
In what scenarios would it be nil? I need to know how to properly handle this or which devices I should not support.
The Objective-C initialiser is imported into Swift as init!()
- an initialiser that returns an implicitly-unwrapped optional (IUO). When you declare a context
with this as the initialiser expression, the type of context
will be inferred to be an optional type. The idea is that IUOs gets turned into regular optionals whenever possible (see SE-0054).
You can get a non-optional JSContext
just by adding an explicit type annotation:
let context: JSContext = JSContext()
The reason why the initialiser is imported as init!()
and not init()
or init?()
, is likely because the Objective-C header file does not have nullability annotations. That is, the initialiser is declared:
- (id)init;
instead of either of these
- (nullable id)init;
- (nonnull id)init;
This can be seen all over JavaScriptCore. All the parameter types and return value types are all imported into Swift as IUOs.
All this is to say, that it could very well be the case that init
can never return nil - it's just not annotated properly so it is not imported as a init()
into Swift.
Judging from the rest of the documentation in JavaScriptCore, it is highly likely that JSContext.init
will not return nil. In the documentation of many other methods and properties in the module, it is clearly documented when something returns nil if it does. The documentation for JSContext.init
does not mention this.