How to package a C library with dependencies to swift package - ios

I have a C library that contains other C library (WolfSSL, nanopb) dependencies.
I want to (ideally) build a swift package that contains my code referencing the main C library. I would then be able to distribute this package for others to integrate my library into their code.
There is a lot of information between using SPM, XCFramework, and other avenues but nothing that points to the scenario that I am trying to work with.
Is there a standardized way of accomplishing what I want?

Related

Linking C files with a pre-built static library and compile the Swift project in Xcode

I am new to iOS development. I have ample experience with Android Development.
In Android, I have a bunch of pre-built C static libraries. I also have C source code for another component. I build with the help of Android.mk in Android. As a part of the make file, I build a shared library(.so) by linking the static libraries and in turn use with JNI.
The following is a sample code in Android.mk
include $(CLEAR_VARS)
LOCAL_MODULE:= module_name
LOCAL_C_INCLUDES := $(LOCAL_PATH)/filepath/include
LOCAL_SRC_FILES:= $(LOCAL_PATH)/filePath/filename1.c
LOCAL_SRC_FILES:= $(LOCAL_PATH)/filePath/filename2.c
LOCAL_LDLIBS:= -lm
LOCAL_STATIC_LIBRARIES:= static_lib1 static_lib2 ssl crypto
include $(BUILD_SHARED_LIBRARY)
I am porting the same project to iOS. SO, I am trying to use the same C source code and prebuilt C static libraries.
I have placed the files in Linked libraries in Build Phases but not use. I have read about module map, swift package manager, bridging header but not very clear.
Can anyone kindly help me with step by step process of this linking with the swift code?
Thank you

How to package module.modulemap into CocoaTouch Swift Framework?

I am trying to create a CocoaTouch Swift Framework which I can then distribute to 3rd parties for them to use, and I can build it and use it ok on my machine.
The issues arise when I give it to other people.
My framework uses C code, which I make available for use with Swift within my framework via a module.modulemap file as such:
And I am able to use such module in a Swift file, within the framework, ok, as such:
However, when I build the framework and give it to other people to use, their compiler complains that the Minzip module is missing with the message Missing required module 'Minizip'.
Having investigated, it seems like I'd have to make the users of my framework modify their Swift Compiler - Search Paths -> Import Paths the same way I have to do it to have my compiler find the module.modulemap.
Is there a way that I can build the framework so that I don't have to do this?

Distributing Swift Framework with dependencies; Multiple versions of dependent library

I have a set of swift code which I need to package into a framework and distribute to third parties, so they can bundle it into their iOS applications.
My code depends on RxSwift.
If one of the third party applications also depends on RxSwift, and their version is not the same as my version, what happens here?
A) How do I create a swift framework that depends on another swift framework
B) What happens if there's another copy of said swift framework bundled in the app with a different version.
C) Are there any other options I have? I'm quite happy to compile the RxSwift source code into my framework if that helps

Can I make iOS all-in-one framework? or include private static library into my framework?

I'm a novice on XCode and I'm making an iOS Framework with Swift2, including 3rd party libraries(*.a) and frameworks.
I want to provide it as API to others, but I also want to hide the 3rd party libs and frameworks files from my framework distribution files because they are private.
Therefore I just want to open API interfaces and classes I defined.
Is it possible? How to configure my build options?
You can do that but there are some things you need to consider:
You cannot embed one framework into another one. That means if you do not have the sources to a particular framework you have to ship it alongside your own framework. If you have the sources you may consider compiling them into your framework directly.
Depending on the sources that you use in the framework you might have to do some post processing of the framework to obfuscate private headers etc. For example, if you use Objective-C or C code alongside Swift you definitely need to do some post processing of your *.framework file to hide any API that you want to keep private.
If you use Swift code in your framework please be aware that your framework can only be used by someone with the same Swift compiler version due to the absence of an ABI. That means binaries produced by one compiler version have a high likelihood of being incompatible to a newer version of the compiler.
Static linked libraries can be linked and therefore "merged" into your framework binary directly. You just need to make sure that you have a compatible binary for the architecture you want to target, e.g., you cannot use a static linked library that was build for simulator and link it against your framework that you want to build for the actual iOS device.
If you use Swift in your framework, the users of your framework need to include the Swift dylib libraries in their app bundle - either by using Swift in the app or by enabling the Embedded Content Contains Swift Code build setting.

Make static library for iOS with existing C code in Xcode

Short version of the question:
So basically what I'm looking to do is to take an existing library written in C (https://github.com/lsalzman/enet) and turn it into a static library for iOS.
I am just looking for an easy to understand step by step of how to accomplish this in Xcode.
Long version:
I've gone over some tutorials for making a simple static library that's written in Objective-C (http://www.raywenderlich.com/41377/creating-a-static-library-in-ios-tutorial), and I generally understand what is happening there, but I'm failing to understand how to do this with existing code written in C.
I think I'm getting close, but I'm not so sure.
I start out by making a "Cocoa Touch Static Library" project in xcode.
I add all of the enet .h and .c files
make sure the enet stuff is in my "User Header Search Paths" in build settings.
hit build - it compiles!
The generated .a file is 517kb, so I'm pretty sure it's building the enet stuff in at this point.
My problem right now though is that the header file for the library is basically empty:
#import <Foundation/Foundation.h>
#interface enet_ios : NSObject
#end
I'm thinking I either need to write a wrapper in Objective-C that talks to the enet library, or I need to reconfigure my xcode project somehow so that enet.h is the 'entry point' into this library and not xcode's pre-generated .h/.m files. I'm not really sure how to do that, though. Ideally I'd just like to skip any sort of wrapper and use what the enet library is already providing me.
Thanks for taking a look!
Question, are you trying to call the functions using objective c syntax / object orient notation? Then you do need a wrapper object, no way around that.
But if you are fine calling C functions directly, which is completely acceptable in IOS/Objective C, then it is a matter of making sure your header files from the enet library (the ones in the include directory I see in the github link you shared) are also distributed with the static library. This is a limitation of the static library. You can copy them with the *.a, but they must be copied with the static library. This does differ from a Framework, which has included .H and assets, which developers are not easily able to create with Apple's tools for IOS.
I find that library management with Objective C to be painful on its own and static libraries a challenge for this and many other reasons. One more suggestion, definitely more elegant and portable but slightly overkill for personal use, would be building the project as a cocoapod. You can do this by forking the project and converting it to cocopods. There are lots of examples of how the project structure should look on cocopods and other OSS like AFNetworking. This seems to be the defacto standard way people are creating IOS libraries. See http://cocoapods.org/ for more details. This will include the source code as the pod and compiled against the target application.
This is the only way i deal with my own libraries and third party libraries. It has gotten to the point that if the library doesn't use cocoapods, i don't use the library or fork it and do make it a pod myself....

Resources