Building and reusing Framework with Pods - ios

I spoke with my Product Owner recently and we decided we would like to build a framework with a collection of classes that we'll reuse amongst apps that are part of the same product. At the moment we have completed Consumer Version of an app and will be building a Merchant Version of the same app soon - We realized that we will be reusing a lot of code so thought it an opportune time to build a common framework. I understand how to build Cocoa Touch Library to achieve this, but my question is how do I bring cocoa pods into the mix?
The thing is we will have cocoa pod libraries that are unique to each project, but then also a lot of libraries that the 2 apps will have in common. The code that is reused is importing and using the common cocoa pods, so I would like to know if it is possible to let the framework we want to write be a workspace housing all the common cocoa pods and contain classes using those libraries, then adding that framework to both apps?
Will this approach even work? And how do I add the new common library project to the individual apps, like do I add the workspace or just the project? Will the Cocoa Pods Libraries be included in such a way that when the individual apps are built they include the common library that in turn contain the necessary pods?

Related

Distribute an iOS framework with 3rd party libraries

I'm currently developing a custom framework that makes use of different dependencies such as Moya, RxSwift, ObjectMapper etc. The only issue is that whilst developing the framework I set the search path to the Carthage folder so it knows where the files are when I'm developing the framework.
So the issue is when it comes to distribution because there are so many 3rd parties getting the user to download frameworks and/or link them themselves seems like a long task and I'm unable to distribute the framework via Carthage or CocoaPods.
So I'm currently looking for advice/guidance on how to distribute my own framework and embed these third parties within it whilst still being able to prevent duplicate symbols if the user includes the library within their project i.e. My framework uses RxMoya and the user adds RxMoya as a dependency within the project via Carthage, CocoaPods or manually.

How to create a cocoa touch framework with its own pods

I have not seen this question asked, and answered for several years. We are now on much newer versions of Xcode and Pods so I think it is worth re-visiting.
If I want to create a cocoa touch framework that itself wants to be dependent on specific pods how does one go about this?
I want to add a few pods, like alamofire, to a cocoa touch framework I use in several other workspaces that also use their own pods.
I was about to add the pods to the frameworks and then realized all the issues that may come up and thought I would ask here first because I saw no real relevant information that was related to the latest Xcode and pod versions.
This is for iOS swift projects using Xcode 10.
Any inside from those who already do this is appreciated!
Thanks,
B
Firstly, adding a another library in your on cocoa touch framework results into a umbrella framework which is not recommended by Apple. You can check below:
Why are umbrella frameworks discouraged?
Answer to your question:
Create your cocoa touch framework (Say it as MyLib) which depends on other library (Say it ThirdPartyLib). In this scenario you have to explicitly mention to developers who will use MyLib they have to add ThirdPartyLib as well in their project.
If you upload your library on cocoapods there use can mention in podspec file with property:
s.ios.dependency 'ThirdPartyLib'
Doing above dependent library will install with your framework, when any developer try to install you MyLib pod.

How to add iOS framework in iOS project effectively

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 am able to access the framework 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 it's code is 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 it's entry into embed framework, i can access the public entities of the framework. What's alarming in this case is "whenever i change the code of framework do i need to update the framework in the client app project".
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 it's 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

Embedding frameworks inside closed-source Swift framework

Our company wants to distribute a closed-source SDK for iOS to our clients. I've been using Cocoapods to build the framework and built an example app making use of it. Previously the app worked fine on the simulator as well as when deployed on the device. However, I was also embedding the Pods.framework file in the app itself. One other piece of information that may be of interest is that the framework is written in Swift, the included cocoapods dependencies are both Swift and Objective-C.
I wanted to make the pods requirements easier to manage so the user doesn't need to be concerned with them and tried to embed the Pods.framework file inside of the SDK we're building - so I removed the steps to Embed Pods Frameworks and Copy Pods Resources from the example app, leaving them only in the framework, I also removed Pods.framework as a dependency of the example app, leaving it only in the SDK. This seemed to work in the simulator, but the app now crashes on mobile device with dyld: Library not loaded error.
Upon researching it, I stumbled into a few related discussions:
https://github.com/CocoaPods/CocoaPods/issues/344 https://objectpartners.com/2014/06/25/developing-private-in-house-libraries-with-cocoapods/
However, the suggested solution of using private pods does not look like it would work for us, it's my understanding that the source code in the private pod would still be open, and we can't share it with our clients.
Could someone advise on a solution that would work in this case?
OK, I finally have a more durable solution. It's a modified, cleaner version of my old one now that I understand how Xcode links in my Swift sub-frameworks better
Problem that makes distribution/compilation a bit ugly:
Since Swift standard libraries aren't bundled on the device like Obj-C, nor are they guaranteed to be stable between versions yet (stable binary interface promised in Swift 3: https://github.com/apple/swift-evolution#development-major-version--swift-30) we have to make sure the entire project is compiled against the same version of Swift. That means the guy using your closed-source framework has to be using the same version of Swift in their Xcode for their project as you did for compiling the library, even if he's not using Swift in his code because ultimately it's his version of Swift that gets bundled into the app and your SDK runs against. This is only an issue for closed-source frameworks because open-source ones will always be compiled against the same version as final project. Possible workaround is to restrict clients to same version you use or distribute multiple compilations (i.e. Swift 2.1 and Swift 2.0). To remedy this, you could provide users with copies of binaries compiled against multiple versions of Swift.
Aside from that, here is what I had to do during compilation/distribution to make a binary framework that works in Swift:
When building the framework:
In project target, make sure to add Pods.framework to Linked Frameworks and Libraries (make sure this is a pre-compiled RED version of Pods.framework, I had a black compiled Pods.framework in the same directory which built fine but then resulted in a framework that would cause the project to complain about missing armv7 architecture during linker phase in later project)
In Build Settings, under User-Defined section, add a field called BITCODE_GENERATION_MODE and set it to bitcode
DO NOT #import any frameworks in your bridging header, all instructions telling you to do that are leftover from Swift 1.0-1.2 days, you don't need it anymore and it does more harm than good (the later project will complain that it can't find these headers that aren't even exposed to it)
Change build target to Generic iOS Device, Archive and Export the framework
When building the project using the framework:
Drag and drop the framework into the project, in General tab add it to Embedded Binaries and Linked Frameworks and Libraries (you only need to add the framework itself, not the sub-frameworks or the pods file)
In Build Settings tab, add a new path to Framework Search Paths: $(PROJECT_DIR)/MyFramework.framework/Frameworks
Build the project

Are private frameworks supported on iOS?

Recently I started to modularize my applications much more aggresively than I used to, separating pieces of code into frameworks or libraries.
I like the concept of “private frameworks” in desktop Cocoa, ie. the frameworks included in the application bundle. From my small experience the frameworks are better suited for code reuse than simple libraries, as the frameworks can include their own headers with them. This makes adding a new framework to an existing project a whole lot easier.
The problem is that these “private” frameworks are not supported on iOS. You have to do with static libraries there, and the header management is a pain. Is there a good technical reason for Apple to not support frameworks on iOS?
(Just to make sure: Apple unfortunately uses the term “private framework” for two things. The first is “custom” frameworks that ship with an application, the second is undocumented and prohibited frameworks that people are not supposed to use on iOS. I’m asking about the former.)
PS. Did this change in iOS 8? There’s a “Cocoa Touch Framework” template in Xcode 6.
It appears that custom frameworks are now supported by Xcode 6:
iOS developers can now create dynamic frameworks. Frameworks are a
collection of code and resources to encapsulate functionality that is
valuable across multiple projects. Frameworks work perfectly with
extensions, sharing logic that can be used by both the main
application, and the bundled extensions.

Resources