Separate Xcode Project - ios

We have 3 apps that we maintain, that all use the same menu controller and Core Data model. In addition, one of the apps uses several views and controllers from one of the apps. It's getting to the point that we need to find some way to separate into different projects to prevent painful Xcode project merges. Right now all the code is mixed in together and each app has its own target in one Xcode project.
Is there any way we can separate the project easily into different projects that have AppA, AppB, and AppC where AppB and AppC depend on AppA?

Depending on how each app is different, you can create different targets in your Xcode.
Here's a docs on how you create Xcode targets.
If that does not suit your need, you can create multiple projects and reference files from other projects. I really can't tell what you'd need without more information.

Maybe use cocoapods.
You can make your own (private) pods for the various files that your projects rely on and then keep them updated in their own repository, and then the projects can include the pod and update it when needed. You can also point specific projects to specific branches of the pod repo etc.
(Not sure whether Core Data is supported in pods yet though, might be)

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.

Keep WatchKit Extension code (git repo) separated from the existing iPhone code (repo)

I wanted to add a WatchKit Extension (with SwiftUI supported on iOS13+) to my existing app (target iOS12) while keeping both codebase separated (two repos).
How can I separate the WatchKit Extension code from the Mobile One?
Will my Watch App with SwiftUI only work for users with WatchOS 6 and iOS13 without affecting the existing users with iOS12?
How about the app binary size increase?
Thanks for reading!
I am not sure if there is a simpler solution, but this one should work:
Separation of both apps:
If you open in Xcode the Source Control navigator, you see that Branches, Tags and Remotes belong to a main entry in the Project navigator, i.e. to a Xcode project. So in order to have separate repos, you need separate Xcode projects to which you can assign separate repos.
You can however have multiple projects in one workspace, so that all files are available in this workspace.
To have one standalone app, and one app with a watch extension, just setup a workspace with your standalone app, and add another new project. This new project needs all files of the original app plus the watch extension.
Since you need files from one project also in the other, you could drag them from one project to the new one, but then they will be copied (a green + badge is shown during dragging). Usually this is not what you want, since you usually don’t want to maintain two copies separately. Instead, you can show such a file in the finder, and then drag it from the finder to the new project. In this case, you have the option only to copy the reference.
Independence of both apps:
Since you have two separate projects, you can set the deployment target in the target’s build settings as required.
Size:
Each project will get separate products, the standalone app only an xxx.app, and the new project xxx.app, Watch.app, and Watch Extension.appex. So there should be no overhead.
EDIT (due to the comment of Ouadie in his question):
I am not sure if I understand your problem:
With the procedure above, you get a single workspace with two separate projects that share part of the files.
The „mobile project“ is the same as you use right now. It has only a single target (despite of test targets) that is built exclusively with the sources required. It has thus the same size as now.
The „watch project“ is new. It has 3 targets, the „mobile“ target, the Watch target, and the Watch Extension target (despite of test targets). It is built with the shared sources, and the additional watch extension sources. Its size is thus larger, but the increase depends of course on your sources.
Since you have 2 repos, the projects are decoupled, but both repos share some files. If you want to decouple them completely, you could copy the files from your current project to your new project (instead of copying only references), but then you had to maintain 2 copies.
I hope this helps!

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.

Sharing a File Among Xcode / iOS Projects

I have several iOS apps that rely on a common class (i.e. MyClass.swift). Rather than copy MyClass.swift into each project subdirectory, I would like to configure Xcode to understand that the file resides on my desktop but should be considered an essential part of each project for developing, building, running on simulator, running on device, archiving, and uploading to the App store.
Is it possible to achieve this without using a Library, Framework, or third-party dependency manager?
i usually create a separate repository for the common class. when adding the common class to other projects i make sure to deselect "Copy items if needed".
now each project points to the same file and any changes made by a project to the common class immediately changes the code for all projects. changes made to the common class should be committed to its own repo.
this approach has some downsides (repositories for the separate projects would require you to manually pull down the common class's repo), but these could be mitigated by using submodules

Is it possible to duplicate an iOS application without duplicating all the code?

I have 3 applications that share a lot of functionality. It is only the content and styling changes between them.
Instead of simply duplicating the project for each app, is there a way to make a "base" application and then have the 3 applications extend this?
Simply duplicating the project would be horrible to maintain, whereas extending a "base" would allow them to all update simultaneously.
I know you could create the project and then copy all files from the old project into the new. This would keep the files up-to-date, however if any files were added or removed, you would have to manually do that.
Have one base project that uses multiple targets. Each target can include a subset of the files in your main project, and/or add their own independent files. Each target can also have its own set of preprocessor defines set up in the build configuration.
You can add more targets to your project in Xcode.
Create a project that builds a static library for the reusable components. You can use an Aggregate target to package any associated resources, such as nib files, storyboards, images, etc.
Your app projects can all then consume the static library and resources. Any changes to the static library will be available to all the dependent projects.

Resources