2 Replies
      Latest reply on Mar 21, 2016 6:29 AM by Martin CR
      Martin CR Level 1 Level 1 (0 points)

        In my SWIFT code I need to switch based on the ended-ness of the local host, so I call CFByteOrderGetCurrent():

         

        import Framework
        let localMachineByteOrder = CFByteOrderGetCurrent()
        

         

        So far, so good - but I'm struggling to find a readible way to interpret the results. I was expecting to be able to say this:

         

        if localMachineByteOrder == .CFByteOrderLittleEndian { ... }
        

         

        However Xcode doesn't like it: "type of expression is ambiguous without more context". The best I've been able to achieve so far, with help from a developer on another forum, is this:

         

        if localMachineByteOrder == CFByteOrder(1)     // 1 is the index of 'CFByteOrderLittleEndian' in the CFByteOrder enum
        

         

        But that seems like rather unreadable code, and it would fail if the ordering of the constants in CFByteOrder changed.

         

        Surely there must be a way to do this with symbolic constants!! Maybe I am reading the documentation wrongly but I am finding this very opaque... I would be very grateful for some guidance on this

         

        Thanks in advance, Martin

        • Re: How to evalute the result of CFByteOrderGetCurrent()
          OOPer Level 8 Level 8 (5,435 points)

          You'd better know two things:

          - Currently Swift supports only little endinan platforms.

          - Integer types of Swift have many methods to support endianness without CFByteOrder functions

          For example, you can write your own endian detection like this:

          var isLittleEndian: Bool { return Int(littleEndian: 1) == 1 }
          

           

          Back to your issue:

          Surely there must be a way to do this with symbolic constants!!

          Surely. You need to write someting like this:

          if localMachineByteOrder == CFByteOrder(CFByteOrderLittleEndian.rawValue) {
              print("little endian")
          }
          

          You can get some hints by Cmd-clicking on the `CFByteOrderGetCurrent` and looking into the generated header:

          public struct __CFByteOrder : RawRepresentable, Equatable {
              public init(_ rawValue: UInt32)
              public init(rawValue: UInt32)
              public var rawValue: UInt32
          }
          public var CFByteOrderUnknown: __CFByteOrder { get }
          public var CFByteOrderLittleEndian: __CFByteOrder { get }
          public var CFByteOrderBigEndian: __CFByteOrder { get }
          public typealias CFByteOrder = CFIndex
          public func CFByteOrderGetCurrent() -> CFByteOrder
          

          The return type of CFByteOrderGetCurrent() is `CFByteOrder`, which actually is Int in Swift. And the symbol values are typed as `__CFByteOrder`, which is imported as a struct irrelevant to `CFByteOrder`.

          In C/Objective-C world, they were both integer types and automatically converted to each other, and in Swift world...as you see.

            • Re: How to evalute the result of CFByteOrderGetCurrent()
              Martin CR Level 1 Level 1 (0 points)

              Thanks OOPer -

               

              I did eventually find a solution by converting the result of CFByteOrderGetCurrent() to a UInt32 and then comparing it to the raw value of the enumeration in a similar way. Your way of using the raw value to initialise an instance of CFByteOrder is more elegant though.

               

              I had looked at the headers, but all those double underscores are too confusing for my small brain