Compare Objective-C enum values in Swift - swift

I am attempting to do this in Swift:
var netStatus:NetworkStatus = reachability.currentReachabilityStatus();
if (!netStatus) { // error here says network status not convertible to bool
....
}
typedef enum : NSInteger {
NotReachable = 0,
ReachableViaWiFi,
ReachableViaWWAN
} NetworkStatus;
I've also tried
if (netStatus ==0)
if (netStatus == NetworkStatus.NotReachable) // NetworkStatus.type does not have a member named 'NotReachable'
etc.

Try using modern objective-c practices:
typedef NS_ENUM(NSInteger, NetworkStatus) {
NetworkStatusNotReachable,
NetworkStatusReachableViaWiFi,
NetworkStatusReachableViaWAN
};
Adopting Modern Objective-C

Read the Swift manual on how to define enum. it's more like
enum NetworkStatus:Int {
case NotReachable = 0
case Reach....
}

Unfortunately an enum is not transferrable to Swift from Objective-C, it needs to be an NS_ENUM.
If you can change the definition of the enum, then Daniel T.'s solution is best.
However, if you cannot change the enum definition, then you can create an intermediary class to provide an NS_ENUM and a mapping to the enum values.
See: https://stackoverflow.com/a/24950414/600753 for more details.

Related

How are Swift enums implemented internally?

I recently asked a question around sort of generic enum/structs in C and realized that although I brought up a comparison with the enum possibilities in e.g. Swift and Rust, I don't really understand how those are handled internally to those languages.
For Rust, I found a (rather roundabout) article titled Peeking inside a Rust enum
— look for the "But Rust enums aren't just that." heading and then keep scrolling until the "In Rust, it's called a discriminant." part. Eventually that part gets around to basically saying that Rust enums are sort of equivalent to something like this in C:
struct {
enum actual_options discriminant;
union {
/* … various data types/sub-structs corresponding to each option's need… */
};
};
Is it basically the same with a Swift enum under the hood? I.e. that I should expect an enum to have basically the same memory overhead as a struct of the largest possible option in my enum, plus at least one extra byte to store the tag/discriminant of the overarching case?
I'm also interested in what code gets generated to use whatever sort of underlying structure. I'm assuming it can't really much more fancy/optimized than what you'd do in C for the structure shown above? E.g.
struct raw_enum {
enum { case1, case2, case3 } tag;
union {
struct { int x; int y; } case1_data;
const char* case2_data;
struct { float a; double b; void* c; char d; } case3_data;
};
};
struct raw_enum d;
fill_in_some_value(&d);
if (d.tag == case1) {
// use `d.case1_data`…
} else if (d.tag == case2) {
// use `d.case2_data`…
} else if (d.tag == case3) {
// use `d.case3_data`…
} else {
// any runtime assertion for an unknown tag that could somehow sneak in???
}
Is that a reasonable approximation to what Swift does in the code it generates around enums?

How to reinterpret_cast in Swift?

Our project depends on a C library that declares a general struct
typedef struct
{
SomeType a_field;
char payload[248];
} GeneralStruct
and a more specific one:
typedef struct
{
SomeType a_field;
OtherType other_field;
AnotherType another_file;
YetAnotherType yet_another_field;
} SpecificStruct
We have some examples of its usage in C++ and in some cases it's needed to cast the general one to the specific one like:
GeneralStruct generalStruct = // ...
SpecificStruct specificStruct = reinterpret_cast<SpecificStruct&>(generalStruct)
Is it something like reinterpret_cast available in Swift? I guess I could read the bytes from payload manually, but I'm looking for an idiomatic way
withMemoryRebound(to:capacity:_:) can be used
... when you have a pointer to memory bound to one type and you need to access that memory as instances of another type.
Example: Take the address of the general struct, then rebind and dereference the pointer:
let general = GeneralStruct()
let specific = withUnsafePointer(to: general) {
$0.withMemoryRebound(to: SpecificStruct.self, capacity: 1) {
$0.pointee
}
}
If both types have the same size and a compatible memory layout then you can also use unsafeBitCast(_:to:):
Use this function only to convert the instance passed as x to a layout-compatible type when conversion through other means is not possible.
Warning: Calling this function breaks the guarantees of the Swift type system; use with extreme care.
Example:
let specific = unsafeBitCast(general, to: SpecificStruct.self)

How to compare Associated enums that has no associated value in it

Can I compare associated enum case that has no associated value. Let check the below snippet of code
//Declare associated enum
enum Example
{
case test(x:Int)
case test1(x:String)
}
//Creating enum with associated value
let testWithAssociatedValue = Example.test(x:0)
if case .test = testWithAssociatedValue { //WorksFine
}
//Now having enum with no associated value
let testWithNoAssociatedValue = Example.test
Now Why comparing enum that has no associated value like below,gives me compile error?.
if case .test = testWithNoAssociatedValue {
}
Because Example.test is not an enum case. Try either putting your code in a playground, or checking type(of: Example.test). It will give you (Int) -> Example. That is, under the hood, Example.test behaves like a function that requires an Int and gives you back an Example object. That's why Example.test(x: 10) gives you that enum case.
The notion of "having an associated enum that has no associated value" doesn't make sense. It sounds like you want to make the associated type optional, so you can say Example.test(x: nil).

Choosing a random enum in Objective-C

I've created a typedef enum for my iPhone app...
typedef enum {
FirstType,
SecondType,
ThirdType
} type;
Just for testing I'd like to be able to pick a random type from these.
I was going to use arc4random() % 4 to do it and just use the int in its place but wanted to check if there was a better way of doing this.
typedef enum {
FirstType = 0,
SecondType,
ThirdType,
EnumTypeMax
} EnumType;
EnumType randomType = (EnumType) (arc4random() % (int) EnumTypeMax);
Note that EnumTypeMax is equal to 3, not 4 and that is correct.
EnumTypeMax is considered to be an invalid value.
Also, see my answer here about an X-Macros solution.

Objective C - Getter and setter properties for enum

I am a complete newbie at Objective-C. I have an enum as follows:
typedef enum _XLBadgeManagedType {
XLInboxManagedMethod = 0,
XLDeveloperManagedMethod = 1
} XLBadgeManagedType ;
I want to have getter and setter methods for it, such that if something happens, I set XLInboxManagedMethod to 1. How would I go about doing it?
Your code is just defining an enum type. It's a static, compile-time constant that is not changed. You use enums by declaring an instance of one, then changing it to one of the constant values you defined. If your enum looks like:
typedef enum _XLBadgeManagedType {
XLInboxManagedMethod = 0,
XLDeveloperManagedMethod = 1
} XLBadgeManagedType;
Then your property could look like:
#property (nonatomic, assign) XLBadgeManagedType myEnum;
And its use may look like:
- (void)someMethod {
self.myEnum = XLInboxManagedMethod;
self.myEnum = XLDeveloperManagedMethod;
// etc...
}
You do not change the values of enums. They stay as they are.
They are symbolic constants. You can not change it.