How to add iOS framework in iOS project effectively - ios

Recently started work on an iOS project, written in swift and objective-c. As of now, we have a monolithic repo. Now we are focusing on creating few frameworks so that we can reuse same framework across multiple apps. I would like to know your opinion on below points.
If I add framework.xcodeproj in my client app project, I'm able to access the framework's public entities after writing the import statement. My concern is every time I build by client app project, this framework.xcodeproj is also compiling though its has not changed since last build nor it is dependent on any other framework.
If I add framework by adding it as framework.framework and make its entry into embed framework, I can access the public entities of the framework. What's alarming in this case is that whenever I change the code of framework I need to update the framework in the client app project too.
Is there any way to include framework in client app project where I can access the public entities and it does not get build every time I build client app project ?
It's absolutely fine if framework get's build when its code is updated.
I have used Visual studio in past which let me build my client project without building dependent projects if there is not code change in dependent projects.

If the framework is build every time you build your app, depends on the type of the framework:
There are Cocoa Touch Static Libraries and Cocoa Touch Frameworks.
Cocoa Touch Frameworks
They are always open-source and will be built just like your app. (So Xcode will sometimes compile it, when you run your app and always after you cleaned the project.) Frameworks only support iOS 8 and newer, but you can use Swift and Objective-C in the framework.
Cocoa Touch Static Libraries
As the name says, they are static. So they are already compiled, when you import them to your project. You can share them with others without showing them your code. Note that Static Libraries currently don't support Swift. You will have to use Objective-C within the library. The app itself can still be written in Swift.
Conclusion
If you don't mind using Objective-C, Static Libraries seem to fit your requirement, that the framework should only be built once.
But since I love Swift, I would personally recommend you to use frameworks (if you don't mind that others that use the framework can see your code). My experience showed, that it's not a big problem, that the framework is built sometimes.
AddThis wrote a good blog post about deciding whether to use Static Libraries or Frameworks.
Cocoa Touch Static Library vs. Cocoa Touch Framework

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.

Creating framework that requires (depends on) another framework

I'd like to create a framework using Cocoa Touch Framework Project in Swift. However, I'm building this framework on top of another framework called RNCryptor, which is Objective-C based. I've seen various tutorials on how to create a framework in Xcode but none has covered a framework with its own dependency.
I tried to create a framework project and then using CocoaPods to manage its dependencies. However, there are errors appeared: 'Check Dependencies' Unable to run command...'
So the question is: is it possible to create a framework on top of another framework in Xcode. And if so, how?
Frameworks should never embed other frameworks directly. This leads to collisions if the importing project or any other framework also includes that framework. Instead, you need to tell your consumer that they also need to include your dependency. CocoaPods will do this for you automatically, so you should let it. (If you're having trouble with CocoaPods dependencies, you should ask a question about that and get it cleared up. The whole point of CocoaPods is to manage these kinds of things.)
Note that I will be releasing the Swift version of RNCryptor into beta today (or tomorrow, but I really hope today). This version bridges to ObjC and will be the preferred version going forward. (The ObjC version will continue to be available of course for projects that cannot or don't want to include Swift.)

Third-Party Static Frameworks within a XCode Framework Project

I have created a iOS Framework using the iOS-Universal-Framework:
https://github.com/kstenerud/iOS-Universal-Framework
When I use a static library, let's say libGoogleAnalytics.a I can build my framework let's say MyObjectiveCLib.framework and put everything into the main app. The static libraries will be properly linked into the app.
As soon as I try to add another Third-Party static framework, let's say WindowsAzureMessaging.framework to the framework project, I cannot build the app if I don't link this framework against the app too.
So I'm going to have the WindowsAzureMessaging.framework twice within the iOS app and within the app's core framework MyObjectiveCLib.framework
A solution that I have found is to build every imported framework as a static library (of course we are talking about static libraries in all cases, since it's all about static libs in iOS, hence in this case we are talking about a static framework).
Anyway I cannot do this for every framework when I do not have the source libraries for them.
So since iOS8 release I was able to compile and run the Embedded Frameworks:
Look at my post XCode 6 and Embedded Frameworks only supported in iOS8

Static Library added as sub-project vs static library added as target

First of all I'd like to say that I'm pretty new to this topic so I'm a bit confused on some general aspects of how it works.
Basically I'm working on an iOS project which has two targets, one is the app itself which I'm developing and it is a front-end iOS client, one is a static library which the former developer used to define classes belonging to a back-end framework.
Both the files of the app itself (the client I'm working on) and the static library (the back-end framework) are in the same xcode project bundle.
Even If I've never done the "setup procedure" of the static library anything seems to be working just fine on compilation.
Now the question is: I'm setting up unit tests because I'd like to start developing new features adopting a Test Driven Development approach, so one of the things I was struggling on was if I had to generate or not two separate test targets, one for the iOS app and one for the static library (since they're two separate targets), ore use one single test target for both the static library and the iOS App.
So, reading on the internet to find a solution I discovered that, as even Apple suggests here , a common approach is to add the static library as a "sub-project" of the app project.
I'm just asking myself why and what is the difference with my current situation (one project, to targets, one of it is the static library). Are there any drawbacks? Should I reorganize the whole project?
My experience agrees with Apple and the common approach. I'd suggest making the framework a subproject. (I've had some issues finding headers, but that's my lack of mastery over Xcode, not a flaw in the process.)
Set up unit tests on each project, independently. This way, your tests are true to your objective with a framework: You've successfully decoupled the framework from the parent project entirely.
If you write the all of the unit tests in the parent project, what happens when the framework is needed in another project? You've got two choices. You can not test the framework, or string along the original parent. Do the right thing and split up your tests.
I've got an open source framework that I built, called SpiffyKit, that has a parent project called SpiffyTester. (I admittedly didn't unit test much, because it's all UI and no logic.) It may serve as a good example of a starting point.
Depending on your needs you can use Pods, static or adding it to the project. If you add a library as a "subproject" is useful when you are working on the 2 projects at once. For example if you add something new to the library you just compile the library and voila you have access to the new library in your project. However if you just link the static library you will have to open the project for the library then build then replace it in the library and add the new headers witch is a lot of setup work.

Custom dynamic framework on iOS

There is a number of questions (some of them with answers) about creating custom dynamic frameworks for iOS. My practical experiance shows that on iPad2 and iPad3 one can use custom dynamic frameworks and it works. On iPad1 it doesn't work. So my question is. Did it become possible to use dynamic frameworks on new versions of iOS?
Apple doesn't allow you to create your own dynamic frameworks for the iOS platform. There is however a way to package up your static library and using in a similar way as a framework.
Did you see this post?
I particular check out this GitHub repo, this is what I used to get up and running, very simple explanations: https://github.com/jverkoey/iOS-Framework
Basically you will create a static library and create multiple targets for each platform - simulator and device and one last target which I usually call "build and merge", this target has a script that takes the resulting libraries for device and simulator, and packages them up in a folder called xxxxxx.framework, inside is the standard structure and it contains your static libs, when you use this in other projects you import the framework to that project and include the header files like you would any other real dylib framework.

Resources