Xcode Create a swift framework that itself uses cocoapods - ios

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.

Related

Framework using cocoapods inside other framework using cocoapods inside app project

I have a app which historically has grown a lot and to be a bit cleaner and to have the option to give out code to third party developers in the future, I was thinking about splitting my project into multiple projects which I then could export as a framework.
Currently everything is in one big project. I have:
4 App targets
Shared view controllers
Shared web services
Shared model classes
Shared utility classes
Shared extensions
Shared protocols
The thing is that not every web service is used in every app. Not every protocoll is used in every app. Not every extension is used in every app and so on.
Now correct me if I'm wrong but can't I put, for example, the web services in their own framework and then use the framework in the project where I have my app targets?
Can I do the same for a "core" which contains all utilities, extension, protocolls and models?
Can I then use the "core" in the webs service framework as well as in the app targets?
What would such a structure look like? I already tried creating two framework projects and then use one framework inside the other but I cant build it. Is it because I would need to use Cocoapods inside each of the framework projects? Is that possible?
The web services for example would need "RxSwift" and "Moya" but the "Core" would also need "RxSwift".
Do I have a wrong thinking here? Shall I only use one Core framework and put everything in there which is shared? I'm confused and probably lack the deeper understanding of how the frameworks work.
I'm using CocoaPods and have separate from main app web service and core frameworks. This way it looks in the project:
Lets start with core because even web service depends on it. I call it Common instead of core and it is available on GitHub. It contains multiple subfolders which represent frameworks they extend. And there are two podspecs.
CommonExtended contains functions that are not available in app extensions (for example in Today Extension) and depends on Common. So, splitting core into two separate frameworks provide a way to use it in both main app and app extensions. Although Common is available on GitHub, I download and use it locally (but it can be downloaded from remote whenever you update your pods, you just need to specify remote address)
web service is a local folder which is called Api and its podspec looks this way:
As you can see, it has such dependencies as RxSwift, Moya and Common (the desired behavior from your question - framework contains framework).
So, whenever I need to use any of the frameworks in an app or its extensions - I just specify what kind of framework is required as dependency:
Then just import your frameworks and use them:
import Api
import Common
import CommonExtended
P.S. This is just an experiment, I'm not a CocoaPods professional. But it works for me.
Edit. Local pods are easy to update. You just make changes and see them in your project (as I remember Cmd+B on main project makes the changes to be visible). But this only works with files in local pod which already exist. If you need to add new file to a local pod - run pod install to make this file visible.
All the local pods are 100% local and they live in the same repository as main project. But Common is a remote repository which is downloaded locally. Why? Because it is used in different projects. So, on each machine you have to write its own path to Common in podfile. This link provides a way to define a path to Common on each machine and never change podfile again. Don't forget to commit Common changes to the remote. Other local pods will be committed with the project automatically.

Debugging (owned) Framework when using Carthage

I am in the process of developing my own Swift framework to be used privately between two of my applications. I am using Carthage to manage that and other dependencies.
I finally got through developing the framework and hooking it up to one of my apps and, not surprisingly, the app crashes in the new framework code.
I would like to debug the framework code. I've looked at some articles that talk about:
Copying the dsym files and
Compiling with debugging information.
Unfortunately, the articles leave out a lot of details (and I'm not a seasoned enough iOS developer or Carthage user to implicitly know them).
Can someone provide a recipe on how to configure the app such that the private framework code is not optimized and I can step into the framework code from the hosting application?
Thanks
Peter...
Here are two options.
1. Debug framework within main project
Follow step 4 of the Carthage guide and then you should be able to step through and debug your private framework.
With the debug information copied into the built products directory, Xcode will be able to symbolicate the stack trace whenever you stop at a breakpoint. This will also enable you to step through third-party code in the debugger.
2. Modify framework within main project
Clone the private framework source locally.
Drag the framework's .xcodeproj into your main project. (Do not have both projects open in Xcode).
remove crthage entry form carthageInput.xcfilelist & carthageOutput.xcfilelist
remove the framework from project -> target -> general -> frameworks libraries and embedded content then add it using the + sign from the dragged project. then you will see beside the framework name Embed & sign
Now you can develop on your private framework and test them all within your main project. Once done
Remove reference to framework .xcodeproj from main project.
Create a new release of your framework.
Update main project to use newer version using standard carthage update

Xcode build process for linking & embedding framework to app in workspace

I've separated some functionality in an app I'm working on into a self-contained framework. Both the framework and the app are included in a workspace. How do I include this framework in my build in a machine-agnostic manner?
What I've been doing is adding the framework to the embedded binaries of my client app, as suggested on a number of posts here on SO. This works nicely until you start work on another machine, at which point the randomly generated 'DerivedData' directory the framework resides in can't be found, and you have to re-create the link. This will become a really tiresome process.
I was considering using CocoaPods for this purpose, but unless I'm reading it wrong, you can't just reference local projects with a podspec; the project needs to reside on a known source / repo.
So basically I'd like to know how people here have forged a multi-project build process that isn't linked to the directory structure of a particular development machine.
So I've found a solution that works. The issue was that my client app project referred to the framework file relative to the project itself.
The minimal steps I took to refer to (and embed) my framework were significantly fewer than some of the solutions I've seen.
In my client app's target (on the General tab), add the framework to the 'Embedded Libraries' section. This will also add a reference to the framework to the Project navigator.
Select the reference added to the Project navigator in step 1, and change it's location to be 'Relative to Built Products'. Optionally move the framework to the 'Frameworks' folder of the client app's project, where the rest of the frameworks live.
This second step ensures the build looks for the framework relative to the build products, rather than relative to something else, whose location may vary between machines / copies of the source.
Actually, you can indeed have private Pods. Most tutorials on how to do this usually keep these private Pods within private repos on GitHub, but you can also host them on another Git (non-GitHub) server.
As for the DerivedData directory issue, it sounds like you are including the framework via a build setting (i.e. something like "-framework ~/Library/Developer/Xcode/DerivedData/MyFramework-$$##$###$#/MyFramework.framework").
You should be able to simply click on the "Build Phases" section of your app's target settings and then the "add" (or "+") button and you'll see your (built via the same workspace) framework or library in that list that you can add. More information can be seen in this Apple documentation.

Xcode 7 is using my framework after I deleted it

I'm in the process of developing a framework. My problem is that the changes I make to my framework are not being reflected in my app. My app seems to be linked to the original framework I created and isn't updating when I update the framework. Even when I delete the framework from my project, xcode still seems to think it's there.
Setup
I created a separate xcode project intending to make an app that uses the framework. I copied the root folder of my framework project into my app project root folder and I drag and dropped the .xcodeproj into my App's xcode project. I added the framework from my nested xcode project in each of the following steps:
Build Phases>Link Binary With Libraries
Build phases>Target Dependencies
General>Embedded Binaries
I tried removing the framework from each of these locations.
I tried cleaning the framework project and App project.
I tried deleting the derived data in my app project and framework project in Window>Projects
I tried using a previous version of my app project that doesn't contain the framework in any way (not in the xcode project or root folder)
The ghost of my framework continues to haunt my project! Any help?
I suppose you must have tried deleting it from build phases as well... just in case though:
Go to Build phases -> Link Binary with libraries
Select the one you want to remove, press minus button down there.
Do it for all modules: as in Debug, Release.
You can also try deleting the older framework and emptying trash to be on the safer side.
I just made a mistake.
I was using the classes I built my framework out of rather than the framework itself. I thought deleting these classes and selecting 'Remove Reference' would stop Xcode from using them. I deleted these classes completely and Xcode told me they couldn't find the class I was looking for-- indicating it was using those files rather than the framework.
Also, in my AppDelegate I used
import "ExternalClass.h"
Which I believe is for classes that are in the project. I changed this to
import <ExternalClass/ExternalClass.h>
to import the header file from the framework instead.

iOS 8 custom framework linking issues

I'm having issues linking to my custom iOS framework which make me realize I don't fully understand the concepts behind this process.
Basically I have a framework project created using the new Cocoa Touch Framework template, and a client project that uses the framework. If I add the framework xcodeproj file to the client project everything works fine. But if I have the 2 projects side-by-side in a workspace I can't get the client project to recognize the framework. I've tried adding it as a link binary but it displays in red, and I've tried adding the header #import statement (which produces the error "unable to build module").
I'm unclear what files the framework should produce as output and where it should put them (I can't find any), and what is needed for the client project to recognize them. Does the OS (or simulator) take care of locating them or does the client have to reference a specific location? Why (and how) does it work when the xcodeproj file is included in the client?
Thanks

Resources