How to package module.modulemap into CocoaTouch Swift Framework? - ios

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?

Related

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.

Is it possible to create a standalone distributed Swift Framework?

I have a scenario where I need to package some common code into a Swift only framework. I have found many tutorials on how to do this but all involve creating a framework within an iOS app. My goal is to:
Create a seperate Framework project
Build and produce a .framework file
Copy that single file(without all the source files) into some iOS app project, add it under "Linked Libraries" and use it.
Question: Is this possible or do I have to include all of the Classes that are part of the framework?
I have added a framework project to an iOS app and had success using it because all the source code was in the Framework project. I tried to copy that .framework file alone to a new project and use it but when trying to access the classes or instantiate the contents of the framework I couldn't even-though whatever needed to be declared as public was.
Appreciate any help...

iOS8 framework library linking WITHOUT Pods

Imagine the following scenario;
I'm developing a cocoa touch framework that requires SomeLibrary (e.g. AFNetworking). My framework is going to be included into someone's project that might require SomeLibrary as well.
How do I accomplish this without running into these nasty duplicate warnings when I include AFNetworking into my framework directly (either via source code or Cocoapods)?
I've tried it with Cocoapods on both projects (my framework, and a test project that includes my framework), but that results in duplicate code warnings as well.
When I don't add AFNetworking into my framework development project, the compiler can't find the required files, which is why I can't build it. I've tried with including AFNetworking's source code directly into the main project, and using the pod, but in both cases the AFNetworking/AFNetworking.h import in the framework project fails.
How can I do this without making a pod out my framework (which isn't really an option)?
I've found this related answer, but I don't know what search path to set for the framework project in order to find a library of the master project;
https://stackoverflow.com/a/23123725/1069487
Any help would be highly appreciated!
You will have to build your framework linked against static library.
You build AFNetworking as a static library (that will give you a .a file as AFNetworking.a)
You build your framework that link against your static library. But be aware that the library won't be embedded in your framework (there is no way to include static library into framework on iOS). Your framework is able to use AFNetworking API because it is linked against it.
any project that use your framework and use AFNetworking methods of your framework need to link with the static library AFNetworking.a that you should provide as a standalone file beside your framework.
See iOS-Framework here for more details : https://github.com/jverkoey/iOS-Framework

iOS Framework build: what is the best practice to link with third-party libraries?

I'm build a Framework for iOS and my framework has AFNetworking as dependency.
So what is the best practice to include AFNetworing? Reading other posts (specially this question here) i came up with three options:
Copy all the .h.m files from AFNetworing in to my project and compile my framework with it. But according to this, it will possible cause a situation where some third part developer using my Framework are already using AFNetworking and will get a compile-time error that some class is declared twice.
Use CocoaPods and link AFNetworking to my Framework. This is causing this error: -lPods is not an object file (not allowed in a library).
Build something like the Aeris SDK where the third part developer using my Framework will be responsibly to add AFNetworking to their project.
I think that option 3 is the best but i don't know how to do that. How can i dev my framework calling AFNetworking classes/methods but do not include on the final framework product?
Thanks!
That's a very bad practice to use third party library in you library.
Ideally you should avoid doing that.
But if you really need it, you can define and add prefixes to class names.
Refer this article Avoiding dependency collisions in iOS static library managed by CocoaPods
Ok. I decided to go with the option 3.
A just added all the header files from any third-party lib to the my framework project (you can also add the .m files but not include them on the static library target).
And a i also documented everything, so developers using my framework will know what are the dependencies and how to include/install them on their own projects (including third-party lib versions, CocoaPods support, etc).
I decided not to go with option 1 because that will cause some situations where a project will have two copies of the same lib compiled on the final app. Even if a change the namespace for the libs on my framework code (to prevent "duplicated symbols" errors) that will still cause some other possible problems like an APP with larger size, possible bugs related to two or more instances of the same lib running together, etc...

How to create & configure a (mix & match) framework as module?

I've read the "Using Swift with Cocoa & Objective-C" a few times, and I've tried every possible combination of project type (framework, static lib & Swift first, Obj-C first, the lot) but I simply can not get modules to work. I've spent more than 2 hours on this, and it shouldn't be that difficult. Chosing a module name and setting Defines Module to 'yes' doesn't do it.
My goal: to create a module that makes the Apple System Logging service available in Swift code. I've got an objective-c wrapper library lying around that I thought I'd make available as a module to import into my Swift framework, but so far the only luck I've had is it exposing only one of the many classes publically in Swift code. The rest simply aren't available. It's also exposed the 'asl.h' C functions, which is cool, but I have no idea how that happened. I tried creating several sparce frameworks/static libs with the sole goal of making 'asl.h' functions available in Swift. If someone knows how to do that (for any C headers that are part of iOS) without the need to create an Objective-C framework as a module to import into Swift, I'd love to hear about it. Or even just as a framework to make any c headers available in Swift that would be awesome.
So! I create a workspace with an app project in it, and then I create a framework project at the same root level in the workspace as the app project. On the framwork target I set the Product Module Name and Defines Module to 'Yes'. I update my My App's Scheme build target to include the framwork above the app target. I ensure the Link Binary With Libraries build phase contains the framework. Build the app target after adding an 'import MyFramework' line in a Swift file and boom. Failure.
Obviously I've tried clean builds, deleting Derived Data for all projects, hopping one leg and trashing everything and starting again. Someone, anyone, had success with modules yet?

Resources