I have defined 3 configurations for my project: development, release and testing. I want to exclude one library from release builds (only used for testing purposes).
Is there any simple option how to do that from Xcode?
I want to achieve same like Exclude specific library from one build variant in android but for iOS specific configurations/scheme.
Is that even possible in Xcode? Or I have to do it in different location/tool (PodFile)?
Related
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.
We are at 400+ targets in xcode. It still works fine but there has to be a better way to set this up by keeping the same code base but not having all those targets which could slow down xcode.
Android Studio lets you update the appname, which loads that folder from disk so only that project is loaded to run and program against. In XCode that is not the case, all targets are available.
It's been years but is there a better way now, with hundreds of targets that doesnt involve Git or Branching? The questions in regards to this are old and only for a few projects, we are talking hundreds here.
Your question lacks enough context to make a specific recommendation but in general...
Use Frameworks
If you can, combine sensible things into a single (or multiple) framework target. Frameworks can be more than fancy wrappers around a dynamic library, they can contain helper tools and such as well.
Use Workspaces
If there is a logical grouping to your existing targets you can separate them out into their own Xcode projects. Once you have them in their own projects you can create a workspace that references those individual projects. Even if the combined workspace loads in everything upfront (I don't think it does tho) you can still open and use the separate projects for a fast and fluid experience when working on the components.
Use static libraries
If you have a ton of targets such that one requires A, B, and C, but another needs B, C, D then you can actually put A, B, C, and D together in a static library and rely on the linker to strip out unused code from each individual target. This obviously does not reduce the number of targets you have, but you can make the static library its own project and include it in a common workspace. This will also speed up compilation as the files only need be compiled once.
Parameterize Targets or Use Schemes
If your targets are simply wrapping some external build tool/script with hardcoded parameters (I've actually seen this) you can actually pass a ton of existing variables from xcode to these external tools and eliminate "duplicate" targets. Similarly you can add new schemes if some of your targets are simply permutations of each other. A good example I've seen of this are people that have a separate target for "sanitized" (address sanitizer, etc) builds you can instead create a sanitization scheme instead of a target.
Use "Script" Build Phases
If some of your targets are doing something such as linting then you can instead employ a script build phase to call the linter instead of having a separate target to do it.
Offload Targets to an External build System
Xcode can have targets that simply call out to an external tool/script using the Script build phase (and using variable parameters as mentioned above). This can make sense to do if you already use another build system (make, cmake, etc) for another platform. Use Xcode only for the Mac/iOS specific targets and offload everything else to a cross platform build system.
If the build system outputs errors in a format Xcode understands it will even show file and line errors the same as native Xcode targets. I've seen people write thin wrappers around external tools to catch parse and reprint errors into such a format.
I have an iOS project and I want to have several apps in the store with the same code base, but slight changes in assets and some features enabled in an app and other features in another.
I read in some blogs I can do it using some deferent targets...
How Can I Do It?
You can use targets to set user defined properties, set different assets to each target and enable features in a target and disable them on another. I created a blog here with the details of this process. how to use targets to launch multiple
I have several apps that using the same core framework, Since each app have some small differences i'm searching for the best way to build the framework with relevant code and parameters.
The best solution (that is not so good) that i found is:
For different code compilation - using targets that include different classes
For different configuration using different Swift flags for each configuration (e.g. debug, release...)
The problems are:
I'm using several targets and each target duplicate the project configuration and i need to maintain all. this approach can lead to some bugs if i change configuration in one target but forget to change it on other target.
For debug/release & stagingA/stagingB/production I'm creating specific configurations instead combining them (This solution is problematic since for each staging i need to duplicate it for release and debug):
release production
debug production
release stagingA
debug stagingA
release stagingB
debug stagingB
Apps struct is:
App A include CoreFramework with code adjustments for A
App B include CoreFramework with code adjustments for B
Each app have debug, release, production... configuration. This configurations affect the framework (these configuration run also on the framework)
==> I'm looking for other/better way to configure my apps project's
Don't make "code adjustments" in the framework based on which client is calling it.
Construct your framework as if it were something provided as a binary release by an external supplier. Any behaviour that may be variable can then only be controlled by run-time configuration through a public API.
There is a number of questions (some of them with answers) about creating custom dynamic frameworks for iOS. My practical experiance shows that on iPad2 and iPad3 one can use custom dynamic frameworks and it works. On iPad1 it doesn't work. So my question is. Did it become possible to use dynamic frameworks on new versions of iOS?
Apple doesn't allow you to create your own dynamic frameworks for the iOS platform. There is however a way to package up your static library and using in a similar way as a framework.
Did you see this post?
I particular check out this GitHub repo, this is what I used to get up and running, very simple explanations: https://github.com/jverkoey/iOS-Framework
Basically you will create a static library and create multiple targets for each platform - simulator and device and one last target which I usually call "build and merge", this target has a script that takes the resulting libraries for device and simulator, and packages them up in a folder called xxxxxx.framework, inside is the standard structure and it contains your static libs, when you use this in other projects you import the framework to that project and include the header files like you would any other real dylib framework.