Creating a Framework with a Modularized Structure - ios

I've recently been working on a framework to encapsulate the network layer of all the apps at my company, I've got the base structure ready and then I wanted to add the rest of the components into separated modules, to avoid importing everything whenever using the framework. For example, I noticed something like this in the MaterialComponents framework:
pod 'MaterialComponents/TextControls+FilledTextAreas'
The pod name has a directory format and in code, the import looks like this:
import MaterialComponents.MaterialTextControls_FilledTextFields
Any idea how to achieve this structure?
Thanks!

Related

How to include CoreMl model into the cocoa pod framework?

I'm trying to create a framework which will be reused across couple of the apps we're currently developing and this framework will include two things:
CoreMl model
Some amount of code written around this model which will make the work with the model easier
The obstacle I'm currently struggling with is that I can not figure out how to make sure XCode generates the interface class for this model. The thing is, if I'm trying to build the pod itself, I can clearly see that the interface class is being generated. But, if I switch over to the test project I created in order to use this pod, the framework classes start complaining about the use of the unresolved identifier MyModel.
Is there anything I'm missing in my podspec or something like that? I'm new to iOS development (was working on Android solely), so pardon me if I accidentally omitted some important parts of my description.
The solution I ended up with was to disable the code generation and add the Model class along with ModelInput and ModelOutput which were generated before into the project. After that the test project seems to work just fine with the pod framework containing the model.

How to create Swift import submodules

Currently we have modularized our Swift project, using multiple targets. The targets compile to .framework files that are dependencies of the higher targets. We have a Common module target, a few Product module targets, and the original App target. Common will hold very low level code, shared libs, and any specific code that may be shared by multiple product targets.
So the App will do:
import Common
import Product1
import Product2
And Product1 target code might do:
import Common
Generally the flow is Common -> Product* -> App, where Common will never reference the other direction.
Unfortunately Common has grown large, and has a lot of code that may not be needed for every import.
What I'd like to be able to achieve in Swift, is something like this:
import Common.API
import Common.PurchaseCheckout
I've looked into module-maps, which allow for setting up the import submodules, but it is all focused around objective-c headers, and not Swift. Is there a swift variation?
The specific need is that we want to create a light-weight SDK that only uses some of the features, and as soon as we "import Common", it bloats the SDK, and it adds dependencies on quite a few unrelated cocoa-pods also. We can include files in the SDK target file-by-file, but were hoping modularization would make things simpler.
EDIT
It appears I can use such things as:
import class Common.FileDownloadAPI
import class Common.FileUploadAPI
possibly in my code to create the impression of a partial import. However, modulemaps seem to be a way in objective-c to do this for you, creating the submodule. I do not want to have to write 100 class imports to import half of the 200 files that a submodule might do in one import. So still looking for ideas.

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.

How to import package 'Storage' in to Swift project?

I'm currently studying the source code of Firefox-iOS app by creating my own Swift project and typing the code line by line.
In one of the source code files, it imported a packaged named Storage
But I don't think the package Storage is part of the apple API and I don't really know how I can import it.
Edit
Multiple podfiles are present in the project folder
In Swift you dont import other Swift files as they are readily available to use directly.
But you need to import another module. It looks like Storage here is a module inside the firefox-ios app workspace and hence you need to import it before using it.
I looked at the sourcecode at Github and it does contain a package named Storage.
You can read this to understand more about Modules and import statement.

How do I use a local Objective-C file in a pod class file I'm editing?

I have a library that I'm using through Cocoapods, and I'm modifying it slightly. I have a class I've created in my normal project (outside of Cocoapods) that I want to use in the Cocoapod, but when I try to import the file it says that file doesn't exist.
As pods are seemingly achieved through a separate project within the same workspace, I assume that's the reason why I can't access it. How would I access it, however? Do I have to import the file separately into the Pods project and then maintain two separate versions? Or is there a better way?

Resources