Sharing a Cocoa Framework between apps (iOS) - ios

I have created a dynamic framework for one of my apps as I was using a lot of the same code for the main app and the extensions. This works well and has reduced the amount of duplicate code in the project.
I am now looking at creating a second app and it would save me a huge amount of time if I could use the framework from the first app.
How would I go about doing this?
My initial thought is to break the framework out into it's own project and include that project in the app projects by using a workspace.
Another thought was to have both apps in the same project, but as different targets.
I also use git, so it would be beneficial to have the framework separate from the apps.

Related

Can I refactor my xcode swift app into a lib?

I have an Xcode swift app that uses "import CoreBluetooth" to access a wearable.
Now, my teammate wants to use my functionality, and thus wants a lib (.a) that he can incorporate into his xcode GUI app.
Can I refactor my app into a lib for him to add to his GUI app?
Or, is the only way to create a new xcode lib project?
Short answer is yes, you can use the same project. You need to separate 2 things:
Project is a design-time / code organization entity. One project can contain framework, app, tests, etc - all at the same time
What actually dictates what is going to be built are Targets. Some targets will build an app, some will build the library etc. Each target may contain any subset of files from your project (as long as they compile).
So that's one way to go about it: create a second target for Framework, add relevant files to Build Phases > Compile Sources and voila.
The advantage is simplicity. The disadvantages are many: how do you know you didn't break compatibility with wearable? how do you know which file belongs to app, and which belongs to app and framework (sure, you can see when you click on file, or folder structure can help, but it's not going to stop the mistake from happening)? or what if compatibility your iOS app needs is different with what wearable app needs? how do you maintain versions of such framework? etc etc
So a much better cleaner way is to create a separate repo for your framework, and maintain it as an internal product you are sharing between various components. That way you can maintain clear versioning, compatibility, and address bugs without the fear of breaking either app or wearable. And you can include that framework in both projects using (like suggested above) Swift Package Manager, or CocoaPods, or even manually.

Xcode Create a swift framework that itself uses cocoapods

I'm still relatively a beginner. I'm trying to create a uber type app that uses firebase database (installed via cocoa pods). I'm creating an app for drivers and another for riders. I'm also trying to start out right by structuring my app as best i can to begin with.
In the riders app, I created a database handler singleton to control access to the database including functionality to add the rider to the database. A common firebase database is shared by both apps. Rather than have both apps have separate database handlers (and various other independent handlers), I've created an independent swift framework to hold the handlers.
I've added my swift framework to the top level of my workspace in both the rider app workspace and in the driver app workspace (by dragging in the framework xcodeproj file) and gone through all the processes I've read about to build the framework to a generic device and copy the framework to the actual app embedded binaries etc. Independently both app workspaces are working properly .... however ... i have 2 problems at this stage
if i try to open both workspaces at the same time (ie work on the rider app at the same time as working on the driver app), Xcode gives me a workspace integrity error basically giving error "couldn't load xcode project (ie the framework project) because it is already opened from another project". the app still runs ok but the error (red error) remains. how can I fix this?.
I want to use FirebaseDatabase within the database handler framework itself but even though I have FirebaseDatabase installed in the main app, the framework can't see it ie import FirebaseDatabase line is showing "no such module". I also tried installing FirebaseDatabase via cocoa pods separately in the framework project and am still getting the same "no such module" error. How can i get the framework code to see the required cocoa pod frameworks
Having a shared framework project outside of two app projects, but included in their workspaces can cause problems. Editing the framework in one workspace may break the app in the other workspace if the change is a major one.
I think you have two options. One is that you keep the framework app in a central repository and check it out into the app projects. This lets each app project use the version of the framework they are comfortable with and if one changes, the other doesn't see those changes until you tell it to update.
Another option is to switch to a single workspace with both apps and the framework in it. Effectively saying that you will always be working on both at the same time and they will always be in sync.
I can't say what the issue is with not finding the framework as I don't use CocoaPods, but I'd be checking all the framework search paths in each project settings to see if they are searching the right directories for the compiled frameworks. You should not be copying any dependency frameworks in the framework target, but all of them will need to be copied in the app targets.

xCode - how to link dynamic framework from workspace

What is the proper way to link a dynamic framework which lives in the same workspace like the app?
I have a problem when adding the framework from the products folder to the App's "Embedded Binaries" section - because the added framework may be built for simulator and the app builds against iphoneos. I can not add both, can I?
I want to achieve that when my app builds, the framework is built too and I can work the changes immediately instead of doing some cumbersome update via Carthage or something link that.
EDIT: http://netsplit.com/xcode-two-apps-with-a-shared-private-framework-in-a-workspace This blog post describes exactly what i want to do - but this does not work since i want to develop on simulator and iphone (it would require a fat framework). Or did I miss something.
Although is possible to develop main app and framework and doing integration test in the same time from many workspaces, at same point becomes a slow-ish and not scalable development process.
So I suggest you to make a sample app in the workspace of your framework and develop and test your features directly from there. Once your framework is quite stable you release it and you integrate it with your main app.

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'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

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.

Resources