mzaks / FlatBuffersSwift

This project brings FlatBuffers (an efficient cross platform serialization library) to Swift.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cast from 'X' to unrelated type 'T' always fails

alexanderwe opened this issue · comments

Hey,
at first thank you a lot for providing Flatbuffers support in Swift, I really like the library.

Currently I have an issue where I am using a Union type but I am not able to decode the Union type correctly.

Flatbuffers file:

table A {}
table B {}
union Test {
  A,
  B
}

table Root{
  test:Test;
}
 if let test = root.test {
  switch test {
  case let test as A:
    print("A")
  case let test as B:
    print("B")
  default:
    print("none")
  }
}

If I try to convert test as A or B I get the following error message:
"Cast from 'Test' to unrelated type 'A' always fails" and it indeed fails and it prints "none". Do you have a suggestion why this could be the case?

I am using Swift v4.2

Thanks in advance :)

Hey,

thanks for the kind words.

For a union defined in fbs file like this:

union Test {
  A,
  B
}

the code generator will generate an enum with associated value for every case. This is why you can't just cast it to the value type. But the enum has helper functions to "unwrap" the value.
Please have a look at unit tests.
Here you can see how a typical union -> enum is implemented under the hood:
https://github.com/mzaks/FlatBuffersSwift/blob/master/FlatBuffersSwiftTests/contacts_fb.swift#L537
And in this unit tests you can see how such enum can be used for read:
https://github.com/mzaks/FlatBuffersSwift/blob/master/FlatBuffersSwiftTests/ContactsTest.swift#L44

And create:
https://github.com/mzaks/FlatBuffersSwift/blob/master/FlatBuffersSwiftTests/ContactsTest.swift#L267

Hope it helps.
Let me know if you have any further questions.

Btw. if you want to use switch statement, you can, but than you need to pattern match on cases.

Wow, I never expected such a fast answer. Thanks a lot !

I just wrote the issue while being on my way to work, so I will fully test the things when I am back home. What I remember is that I saw those helper methods in the generated source code. Something like

*.asA()
*.asB()

But as I tried those Xcode reported that I can not access them due to internal security restrictions? I think it has something to do with public/private etc.

I have to mention that I wrapped the generated source code into a CocoaPod and then use that pod in my project. Maybe this is not intended ?

Ah yes, the computed properties are not public, but there is actually no reason why they should not be. So I guess I need to change the code generator a bit. Meanwhile you can use pattern matching on the enum itself similar to how it is done in the computed property:
https://github.com/mzaks/FlatBuffersSwift/blob/master/FlatBuffersSwiftTests/contacts_fb.swift#L659

Ah I see. I am fairly new to Swift and iOS that's why I was confused about it. But thanks a lot for your fast and great help ! The pattern matching case works like a charm and I can successfully deserialise my union types.

But it would be nice to make all the computed properties public in the future.

I think the issue can be closed then