Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift 2.0 - `nil` or `0` enum arguments

I've run into this a on a couple functions in Swift 2.0 and wondering if there is a work around. There seems to be no way to not specify enum arguments in Swift 2.0 now. For example, these two methods seem to require something other than nil or 0 be passed in. Is there a way around this?

// Cannot invoke '...' with argument list of type ... options: Int
NSCalendar.currentCalendar().dateByAddingComponents(components, fromDate: self.date, options: 0)
NSJSONSerialization.JSONObjectWithData(data, options: 0)

// Cannot invoke '...' with argument list of type ... options: nil
NSCalendar.currentCalendar().dateByAddingComponents(components, fromDate: self.date, options: nil)
NSJSONSerialization.JSONObjectWithData(data, options: nil)
like image 910
keegan3d Avatar asked Aug 23 '15 17:08

keegan3d


2 Answers

Options are now specified as a set, so just pass an empty set: options: [].

like image 90
Aaron Brager Avatar answered Oct 03 '22 12:10

Aaron Brager


Just to add some more detail: the types in question, like NSJSONReadingOptions, are declared as NS_OPTIONS in Obj-C.

Before Swift 2

Prior to Swift 2, these were imported to Swift as RawOptionSetType, which required BitwiseOperationsType and NilLiteralConvertible. This allowed you to pass nil, and to combine values with operators a | b, a & ~b, etc.

/// Protocol for `NS_OPTIONS` imported from Objective-C
protocol RawOptionSetType : BitwiseOperationsType, NilLiteralConvertible { ...

protocol BitwiseOperationsType {
    func &(lhs: Self, rhs: Self) -> Self
    func |(lhs: Self, rhs: Self) -> Self
    func ^(lhs: Self, rhs: Self) -> Self
    prefix func ~(x: Self) -> Self
    static var allZeros: Self { get }
}

Nowadays

In Swift 2 it's been generalized a bit more. These are now OptionSetType, which requires SetAlgebraType and RawRepresentable. (The underlying RawValue type may or may not be BitwiseOperationsType.)

public protocol OptionSetType : SetAlgebraType, RawRepresentable {
    typealias Element = Self
    public init(rawValue: Self.RawValue)
}

public protocol SetAlgebraType : Equatable, ArrayLiteralConvertible {
    typealias Element
    public init()
    public func contains(member: Self.Element) -> Bool
    public func union(other: Self) -> Self
    public func intersect(other: Self) -> Self
    public func exclusiveOr(other: Self) -> Self
    // and more...
}

SetAlgebraType isn't NilLiteralConvertible anymore, but it is ArrayLiteralConvertible, so you can use [] instead of nil to mean "no options".

And you can combine multiple options in an array: options: [.MutableLeaves, .AllowFragments].

SetAlgebraType also has much more readable function names than those bitwise operators &, |, ^, etc:

public func contains(member: Self.Element) -> Bool
public func union(other: Self) -> Self
public func intersect(other: Self) -> Self
public func exclusiveOr(other: Self) -> Self

So you can use if jsonOptions.contains(.AllowFragments) { ... and such.

like image 43
jtbandes Avatar answered Oct 03 '22 14:10

jtbandes