Limit or change Scheme Destinations in Xcode 4? - xcode

Overview & Motivation
I would like to set up some Schemes that build for iOS Device only.
For example, I never want to build an Ad Hoc build with a Simulator destination. The ability to choose Simulator destinations for an Ad Hoc build is just noise.
Desired Behavior
Actual Behavior
What I tried
I removed the "iphonesimulator" value in "Support Platforms" in the configurations that are meant to be device-only, like so:
In the Ad Hoc scheme settings, I disabled the run and profile steps. I left the archive step
For all Build steps (including the disabled ones) I set the Build Configuration to "Ad Hoc", which was previously set to iphoneos only.
Results so far
I can still select Simulator as a destination in the scheme dropdown:
However, if I run the scheme with a Simulator destination, I get an expected, appropriate error:
It would be much nicer for myself and my team is would could just hide these invalid destinations.
Is there a better way to manage what destinations are available for a given scheme?

Updated Answer
Hmmm. This works for me with ONE target. I removed the platforms from the Supported Platforms in the configuration and they disappeared from the Scheme.
I then tried adding another configuration that allows the simulator and it's still just the device destination visible. Then I duplicated the target and added in iphonesimulator ... and the simulator shows up in the scheme for both targets.
Unfortunately, I think the available destinations are an aggregated list of those available to all targets. File a bug report: http://bugreporter.apple.com
Another Update
AH! It looks like an Xcode bug with updating the Scheme selector! I configured each target's settings - one to omit the simulator and the other to keep it - then closed and re-opened the project. Magically, the first target had only the iOS Device destination while the other target had the device + simulator destinations.
So, the answer may well be to duplicate your desired targets and set them to allow only the device, then make sure your scheme is properly named so you know which target is being built. Close and re-open the project and the list should show up just as you'd expect.

Related

Xcode 11.2.1 confused about the minimum deployment target

I have a library and an app in the same workspace. One is dependent on the other. When I compile I get an error saying that the library is build for iOS 11 but the apps deployment target is iOS 10.
I change the minimum deployment target for the library. Same error.
I change the minimum deployment target for the app. Same error.
I clean the build folder, delete the derived data, reboot the computer. Same error.
The minimum deployment target can be changed in two places in the project settings, either in the info tab or the build settings tab. They both seem to be in sync.
Is there anywhere else it is stored?
Here is how I fixed it. Right click on your project file (something.xcodeproj), select 'Show Package Contents'. Open project.pbxproj with a text editor and search for IPHONEOS_DEPLOYMENT_TARGET. There will be 4 hits, 2 for Release mode and 2 for Debug mode. One of the Release mode values and one of the Debug mode values will be wrong. Hand edit them to the correct values. After this I checked my other projects. Every single one has inconsistent values for the minimum deployment target. I have a feeling that this is a problem with xcode 11.2.1 as this is the first time I have had this problem, but I am not sure. Has anyone else had this problem?

ResearchKit.framework error: Image not found

I have an Objective-C app I wrote roughly 12 months ago, with the iOS Deployment target set to 12.1 . I added the ResearchKit framework to it, and during the time of development the app was working fine. What I do remember is that it only worked on an actual device and not on the simulator.
A year later Im back to make changes, using Xcode 11, and am now getting a familiar error, solution to which I cannot figure out. This is both on real device and simulator.
I have done all that is required to add the library. See attached images below:
TARGETS -> General Tab
TARGETS -> Build Phases
ERROR
Attempting to run on an iOS 12 device fails too. Is there something I'm missing?
I ended up removing the pre-build Research.framework and adding the full Project instead:
Remove the Pre-built ResearchKit.framework file, select Move to Trash when prompted.
Make sure the ResearchKit project is closed (if it's open it wont be added as a project but as a file)
Drag and drop the ResearchKit.xcodeproj project file, into destination project. After this make sure the ResearchKit project has its files under it.
Go to Main project file of your project (not ResearchKit) and select your Target.
Make sure ResearchKit.framework is listed under Embed Frameworks. If not, then add it by selecting the + button and selecting it from the list. If it is not on that list then build the ResearchKit project to create the .framework file.
Under the same Target, go to Build Phases, and make sure ResearchKit.Framework is added under Link Binary with Libraries, and also under Embed Frameworks. If not then add it where absent.
Build and run.
There may be better ways to resolve the issue, but for now this works for me to run the App. App now runs on simulator. However, an initial build takes up-to a minute because the ResearchKit project it pretty big.
Update: I later figured out that the reason why I was encountering the 'Image not found' error is that I was trying to run on simulator while the ResearchKit framework had been build to target arm64 (real device). You will have the same issue the other way around (attempting to run on device-arm64 while app was build for simulator).
So how do the above steps fix this? That fixes the issue because by having the ResearchKit project files included you get to build everything for the currently selected architecture, whether device, or simulator. Happy coding.

Xcode showing duplicate schemes for same target when using shared scheme

We are trying to include some pre-build script in Xcode. So to make it available to all, we are marking the target Xcode scheme as "Shared" and we are committing shared Xcode scheme to git repository. Now the problem is that when ever some one pulls the code they are seeing both shared scheme as well as the Xcode generated user specific schemes for the same target, resulting in 2 schemes for the same target. So is there any way to disable auto creation of scheme for specific target? We see that there is one "Auto Create schemes" check box. But unchecking this will disable it for all the targets? Any help is appreciated. Thanks in advance.

Xcode 6: No provisioning profiles found for AdHoc distribution build; after healthkit entitlements added

I updated to Xcode 6's final release last week, and all as gone well. I've been able to build my code, generate adhoc distribution builds (for legacy Testflight), etc.
Today I added some healthkit code, and had to enable HealthKit in the AppId to do the full build. After I did this, Xcode is refusing to Distribute the build I've just archived to create the final .ipa file. I get the error below no matter what now.
What I've done to try to fix this, as various tests:
regenerated my apps Distribution provisioning profile for adhoc release.
deleted all previous Xcode provisioning profiles, reinstalled and reimported all the provisioning profiles. The updated profile is present for sure.
changed the Team in the General settings, and changed it back to the correct one; allowed Xcode to try to "Fix" the issue.
Updated "build settings" to have the correct Distribution provisioning profile for Release, which Archives use. Confirmed code signing is correct for the Team
Tried "Automatic" for provisioning profile and code signing, as an alternate.
close and restart Xcode
None of this has helped generate the .ipa again, which worked before adding Healthkit support and invaliding all this.
How am I supposed to fix this to properly generate my ipa builds again?
EDIT
I was able to get an IPA built by installing an XC generated provisioning profile that appears to match my Distribution Adhoc profile entirely, except that it includes ALL the user devices I have in the portal, including ones that have long since been phased out (ex-employees). The only difference is the desired profile excludes about half the devices. I'd prefer not to have to do this.
I'm facing more or less similar problems since i started using XCode6. Before XC6, i could use my ad-hoc distribution provisioning profile that was linked to a limited number of devices to create an ad-hoc distribution.
Since XC6, I get the same error message as above, while at the same time Xcode generates its own XC Ad-hoc provisioning profile. From that moment on, when you try again,this XC generated profile is always used and you don't get the error anymore. But of course, at that moment it is using a profile that links to all my registered devices, which i do not want.
No matter what i have tried, eg removing all profiles, it keeps on generating and using that XC generated profile that links to all registered devices.
It gets worse: as a workaround, i tried to modify the XC generated profile and simply remove the devices i don't want. After refreshing in XCode and creating an adhoc distribution, I get the same error again stating that no profiles can be found. Again Xcode generates its own XC-adhoc profile, which of course already existed, and again all devices are linked back to that XC-adhoc profile...
FYI: i don't use anything like Healthkit or so, just default features.
Strictly speaking, it is not blocking from creating an adhoc distribution, but also in my case I have registered devices which belong to different customers, which means i prefer to limit the number of devices for a particular adhoc distribution.
Did you enable HealthKit in the apple developer portal in the app id and update your provision profile?
You need to activate that, and update your provision profile.

Define schemes in an xcode phonegap project from terminal

I'm writing a script to archive the iOS portion of a phonegap project. The script wipes the directory that the project is in and then repopulates it using the latest code from source control. I then run$ phonegap local build ios in order to build the project. However in order to archive the project I need its schemes to be defined. I have tried building the project from the command line but I get the message ** BUILD FAILED **. As of right now I have the code open the xcode project (the only way that I've found to get the schemes defined) and then sleep for 30 second while I wait for xcode to work its magic. My question is how can I either simulate opening xcode or otherwise define the scheme from the command line.
Thanks in advance for any help.
This is a completely fair question given that Xcode schemes are somewhat less than thoroughly documented and schemes have this feeling of being somewhat magical until you see how they hook into the build process as a whole.
Based on the workarounds you are seeking, it sounds as though you need to promote a scheme to being "Shared" so that automated tools (or other developers) do not have to first open your project and wait for Xcode to auto-generate the default scheme. This is an entirely normal 'ask' from developers trying to make their Xcode projects work with Continuous Integration systems or with other command line tools acting on an Xcode 4 or Xcode 5 project. The great news is that there are Xcode-native ways to configure your project without having to resort to messy or error prone workarounds.
TL;DR Version:
The default Xcode behavior for schemes is to treat them as a developer-specific setting and not share with other developers or tools. We need to promote your project's scheme to being 'Shared' and commit those changes to your version control system:
Start with a clean checkout of your project.
Navigate Xcode's Menus: Product > Scheme > Manage Schemes... menu option
Uncheck 'Autocreate Schemes' in the upper left corner of the scheme sheet,
Check the 'Shared' checkbox next to the scheme that should be made available to all developer users and build systems.
Finally commit all project changes back to your version control system.
This will make a single Scheme shared across all developer using this project, regardless of OS X username and make it such that unattended builds via xcodebuild or the build tool of choice will have a scheme to work with.
...And now, on to the the longer answer for the curious
First a bit of background before we dive into your direct questions:
Target: The app, static library, bundle, or more generally the 'product' constructed from the source code, assets, plists, build settings, and other files contained within the project. This 'product' is generated when a build operation is invoked either via Xcode's "Run" button or via the command line tool xcodebuild
Build Configuration: A named set of build settings that can be identified by a human-readable label. By default, all Xcode projects start with a "Debug" configuration that generates build targets with the greatest amount of transparency aiding developers in debugging their applications and a "Release" configuration that strips the resulting build of this diagnostic information and optimizes the build to reduce its size. Some developers elect to create additional configurations based on their team's needs: "Ad-Hoc" might be created so that the Signing Identity and Provisioning Profile settings can be changed for code signing the app for installation via an Ad-Hoc provisioning profile. "AppStore" or "Distribution" are other common custom Build Configurations one might see in other projects.
Action: A set of related activities supporting different phases involved in the development, diagnosis, and testing of a product. As of the time of writing there are six actions: "Build", "Run", "Test", "Profile", "Analyze", and "Archive". As a developer the two you will most frequently use are "Build" and "Run".
Build Scheme: An Xcode 4 invention for managing project build target dependencies, build parallelization options, for a specified Build Target. Each Scheme allows a developer to select exactly one Build Configuration (ex. "Debug" or "Release") for each Action ("Build", "Run", etc.) of a project's lifecycle as well as define other behaviors or options associated with that specific Action. For example, the "Profile" action in a scheme allows the developer to select which diagnostic instrument will be loaded by default when Profiling code in Instruments.app.
With these definitions in mind, lets get back to your questions:
How can I either simulate opening xcode or otherwise define the scheme from the command line?
Very simply: You don't need to do either, there is an Xcode-native mechanism for making schemes available and we just need to do some minor scheme reconfiguration to get you up and running then commit those changes to version control (I'm going to refer to this as 'SCM' for the rest of this answer).
The behavior you are facing is Xcode's default project behavior when it comes to persisting project settings. By default, many things are considered developer-specific settings and reside in a set of files mapping to the specific username of the account that opened the Xcode project itself (more on this in a moment). The policy governing these settings could be distilled down to the rule that Xcode settings were considered 'developer private until explicitly promoted to shared'. Although this was present in versions of Xcode prior to Xcode 4, it wasn't until the introduction of Schemes as the primary vehicle for invoking builds that this approach caused development teams and their Continuous Integration systems problems.
Schemes came along and consolidated a great number of settings screens from early versions of Xcode into a single editor window where a developer could take a look at the highest-level settings for each of the different Action phases of the app:
When running the "Build" action, one could define which targets need to get constructed, or if Xcode should try and identify build dependencies on its own.
For a "Run" action, select which Build Configuration should be used as well as which Debugger to use.
For a "Test" action, select which Build Configuration should be used as well as which Test Classes and Test Data Bundles should be used to test application behavior.
...etc...There are lots of other high-level settings but I'm going to leave exploring them as an exercise for the reader...or an opportunity to ask another SO question!
In each case, these settings cause something of a cascade effect -- Selecting a "Debug" configuration keeps as much diagnostic data in the app as possible to aid developers in tracing the source of problems, this in turn would invoke the "Debug" specific Build Settings as configured in the Build Target itself that may also run "Debug" specific scripts or enable "Debug" specific settings.
Naturally, these selections needed to live somewhere so that they could be persisted between Development sessions or on the rare occasion that Xcode decides to crash. The behavior of "Developer private until promoted" reigned supreme and these Scheme settings were persisted in the "xcuserdata" folder within the .xcodeproj file itself -- This still holds true for those projects that reside as a part of an .xcworkspace.
You can see this for yourself in your own project. First, ensure you are working with a clean version of your code, then open the Xcode project or workspace to ensure that your personal version of the default scheme is available when we walk through your project file:
Switch from Xcode to Finder, then navigate to your project's checkout directory.
Right-click on the .xcodeproj file for your project and select 'Show Package Contents'. If you use a workspace, still select the .xcodeproj that contains your project files, and not the .xcworkspace itself
Navigate into "xcuserdata".
Depending on the number of developers that have been involved with this project or the number of different machines with different usernames that have committed against this project, it is distinctly possible to have more than one .xcuserdatad folder.
Select the folder that matches your OS X username. For me, my OS X username is 'bmusial' so I would select the 'bmusial.xcuserdatad' folder.
Navigate into 'xcschemes' folder.
Observe that you have two files: "[TARGET NAME].xcscheme" and "xcschemenamagement.plist" that contains information about the order of schemes and if schemes should be auto-generated or not.
Ah ha! Schemes are treated as developer-private data and are auto-generated on the first launch of the project!
This realization starts to get at the core of what we need to do -- migrate this scheme out of the developer-specific xcuserdata folder into something shared among all developers, disable auto-scheme-generation to prevent others from falling into the trap in the future, and commit those changes back to your SCM. Switch back to Xcode, let's reconfigure a few things:
Navigate Xcode's Menus: Product > Scheme > Manage Schemes... menu option
Uncheck 'Autocreate Schemes' in the upper left corner of the scheme sheet,
Check the 'Shared' checkbox next to the scheme that should be made available to all developer users and build systems.
Switch back to your Finder window and go up a two levels to get back to the contents of the .xcodeproj folder (the one that contains a 'xcuserdata' folder). Notice that you now have a 'xcshareddata' folder. This folder contains a 'xcschemes' folder that contains the scheme we just shared and the .xcscheme in our own xcuserdata folder is now gone. We have just promoted your private Scheme as a shared, public scheme that will be available to all developers and tools, even those that have never launched the Xcode project directly.
Commit all of the changes we've made (there will be some new folders and files!) back to your SCM so that everyone receives the same configuration changes when the next time they update their source code!
The next time you run phonegap it will reset your checkout as your indicated but because you have a scheme committed it will have build actions it can work with.
Give this a shot and let us know how things go and if you run into any followup questions or problems along the way.
You may also find the ruby gem xcodeproj useful. It can create schemes without having to open xcode.
You can read more about it here.
For phonegap/cordova, save the share_schemes.rb script in a scripts directory in the cordova project.
#!/usr/bin/env ruby
# share_schemes.rb
require 'xcodeproj'
xcproj = Xcodeproj::Project.open("platforms/ios/MyProject.xcodeproj")
xcproj.recreate_user_schemes
xcproj.save
Then add a hook to run it in your config.xml.
<platform name="ios">
<hook type="after_platform_add" src="scripts/share_schemes.rb" />
</platform>
Now you don't have to open xcode to make changes, or check in any changes in your platforms folder. Every time you add the ios platform, your scheme will be created by this script.

Resources