[69629 Closed] Consuming a static [oxygene] library in Swift on iOS

I have a cross-platform library that targets .Net, iOS, and OSX. It’s kind of a trick to manage this in visual studio, but I can build against all three targets with full-unit tests against my .Net build. I’m now ready to start pounding on my library in iOS using Swift, but there doesn’t seem to be a good tutorial on how to do this. I’m new to XCode, new to iOS, and new to Swift.

Most of the available information on libraries seems to be on consuming 3rd-party libraries into Oxygene. This seems unnatural: since Oxygene provides platform-portability, it is way more natural to consume Oxygene libraries in Swift and/or Objective-C. Such is my goal. I’m assuming that since Objective-C doesn’t distinguish Oxygene libraries from Objective-C libraries, this should be seamless. I’m even open to creating an Objective-C layer over my Oxygene libaries. I’d just like to see a good cookbook-style tutorial on how to consume Oxygene static libraries in an XCode 6 Swift project.

If you enable the “Generate .h File” option (should be on by default for libs), Oxygene will generate a header .h file with Objective-C code, next to the static library .a file. Simply adding this header )(along with the .a) to your Xcode project should make the classes available — both to Objective-C and to Swift, as i understand it.

1 Like

Just adding the .a and .h file did not do it for me. XCode lets me add both of these, but my [Pascal-implemented] classes are not visible to the Swift code. I found on the Apple developer site a mention of a “Bridging Header”, which I also attempted, but when I add a reference to my [Oxygene-generated] header from newly-added bridging header, XCode says that it cannot find it [even though it is in the XCode project:

To use a .h files in Swift you do have to setup the bridge header. It’s a little tricky what directory the base is SRCROOT

But Xcode the xcode templates puts all the code one directory down … so you need to add that directory to your definition of were the file is

dir structure 
MySuperApp/MySuperApp.xcodeproj
MySuperApp/MySuperApp/AppDelegate
MySuperApp/MySuperApp/Bridge.h

In this example SRCROOT isn’t where the name sugests but is the same level as the xcodeproj file. So you would have to make the bridge path: MySuperApp/Bridge.h

https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html

Also you have to set the Bridge Objective-C Bridge Header for the test target as well.

But after further reflection it looks like you have these two items correct.

Hmmm …

ahalls, since you indicated that this looked right, a plugged away on it a bit more. The XCode project structure made it look like my header file was in the proper directory, but the finder showed it up one level. I moved it into the right directory, removed it from XCode and re-added it, so now it can find my header. This is great, but the generated header has problems. It seems that the generated header can’t handle arrays. In Pascal, I have a structure that looks like this:

AVChapter = public record
public
  bits: UInt64;					
  hits: Array [0..SEARCHBIT_ARRAY_SIZE-1] of UInt16;
  matches: UInt16;
  first: UInt32;
  last: UInt32;    
  words: UInt16;
  verses: UInt16;
end;

the generated structure in the header looks like this:

struct AVChapter {
  uint64_t bits;
  uint16_t [64] hits;
  uint16_t matches;
  uint32_t first;
  uint32_t last;
  uint16_t words;
  uint16_t verses;
};

every place I have arrays, it makes this error, but what’s worse is I don’t know how to manually correct it when there are arrays of pointers … such as here:

@interface AVBible: NSObject
{
  NSString *SDK;
  AVEnglish *English;
  AVBook * [66] Book;
  uint64_t [64] SearchBits;
};

I haven’t played around with swift or exporting Oxygene static libs yet, but imho Objective-C doesn’t support dynamic arrays. It supports the dynamic initialization of a static array

(Oxygene:) var myArray := new NSMutableArray() withCapacity(SEARCHBIT_ARRAY_SIZE-1);

For cross platform code or cross language code I’d recommend to use the Sugar List (List<UInt16>) instead of a dynamic array.

sounds like a bug in codegen. That said, i don’t know if Swift can handle C-style arrays (which these would be) anyways. you might need to ex;pose NSArrays, for Swift to handle.

1 Like

Thanks, logged as bugs://69629: Nougat: Bad .h file codegen for language-level array type

bugs://69629 got closed as unknown for release Bradbury Class