Qt / QMake iOS Set Target, Device, other XCode settings - ios

Qt for iOS creates an XCode project when you execute a build.
How does one dictate the XCode project settings from Qt to set a "target" (minimum iOS version) and "device" (Universal/iPhone/iPad), as found on the "General" tab in XCode when this project is opened?

I could not find this documented anywhere, but I figured it out.
In your qmake (pro or pri file) add these lines:
# Set "Target"
QMAKE_IOS_DEPLOYMENT_TARGET = 5.0
# Set "Devices" (2=iPad Only)
QMAKE_IOS_TARGETED_DEVICE_FAMILY = 2
Note for devices: 1=iPhone, 2=iPad, 1,2=Universal.
If you need to change other XCode project settings here's how you can:
After a build in Qt for iOS look at the "Compile Output" tab.
You will find a list of "export VARIBALE=some_value" entries.
To change one of these XCode build settings, simply use QMAKE_IOS_VARIABLE_NAME = my_value in your qmake.
For more info on these environmental varibles, check this out: Xcode Build Setting Reference
-- UPDATE --
I was wrong about the last part. You can't set all the XCode variables quite like that. If you output QMAKESPEC, however, you will get the path where you can find a qmake.conf file which will display some of these undocumented variables. Do so like this in your pro / pri:
message( $$QMAKESPEC )
That path will appear in the Qt console "General" tab when you build the project.
Here's an extended version I'm now using, with some logic for setting the build architectures:
greaterThan( QT_MAJOR_VERSION, 5 ){
DEFINES += QT_VER_5_4_OR_NEWER
}
else:equals( QT_MAJOR_VERSION, 5 ) &&
greaterThan( QT_MINOR_VERSION, 3 ){
DEFINES += QT_VER_5_4_OR_NEWER
}
contains(DEFINES, QT_VER_5_4_OR_NEWER){
DEFINES += SUPPORT_64_BIT_IOS
message( "SUPPORT_64_BIT_IOS" )
}
contains(DEFINES, SUPPORT_64_BIT_IOS) {
iosArchitectures="armv7 arm64"
iosTarget=5.1.1
}
else{
iosArchitectures=armv7
iosTarget=5.0
}
# Set "Architectures"
QMAKE_IOS_DEVICE_ARCHS = $$iosArchitectures
# Set "Target"
QMAKE_IOS_DEPLOYMENT_TARGET = $$iosTarget
# Set "Devices" (1=iPhone, 2=iPad, 1,2=Universal)
QMAKE_IOS_TARGETED_DEVICE_FAMILY = 2

Related

Xcode archive build failing. Signing requires a development team

Hello I'm trying to troubleshoot my failing .ipa build. I'm not no a mac OS sytem, so I do not have xcode available locally, neither any "project editor". My build is handled on bitrise cloudbuild server. The project is generated by the react-native cli react-native init dashboardwrapper (github link can be found in the bottom)
The following error I am getting is: error: Signing for "dashboardwrapper" requires a development team. Select a development team in the project editor. (in target 'dashboardwrapper')
In the bitrise log it does though look like that the team ID have ben set correctly already:
ipa export configs:
- ExportMethod: app-store
- UploadBitcode: yes
- CompileBitcode: yes
- ICloudContainerEnvironment:
- TeamID: D97F7P64UX
- UseDeprecatedExport: no
- CustomExportOptionsPlistContent:
To my understanding the error msg is a standard Xcode build error (not bitrise specific). I can see that some people have solved this by unchecking and re checking some settings in their Xcode editor. Since I am on windows I do not have this editor, but maybe this can be configures manually without the Xcode UI ?
I do have a file called: project.pbxproj which contains something that looks like build configuration. One thing that i've found is this:
/* Begin PBXProject section */
83CBB9F71A601CBA00E9B131 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 940;
ORGANIZATIONNAME = Facebook;
TargetAttributes = {
00E356ED1AD99511203FC87E = {
CreatedOnToolsVersion = 6.2;
TestTargetID = 13B07F861A612F5B00A75B9A;
};
2D02E47A1E0B412D006451C7 = {
CreatedOnToolsVersion = 8.2.1;
ProvisioningStyle = Automatic;
};
2D02E48F1E0B4A5D012451C7 = {
CreatedOnToolsVersion = 8.2.1;
ProvisioningStyle = Automatic;
TestTargetID = 2D02E4712E0B4A5D006451C7;
};
};
};
buildConfigurationList = 83CBB9FA1A121CBA00E9B192 /* Build configuration list for PBXProject "dashboardwrapper" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 83CBB9F61A601CBA00E9B112;
productRefGroup = 83CBBA001A601CBA00E9B122 /* Products */;
projectDirPath = "";
projectReferences = (
{
ProductGroup = 146834001AC3E56700842450 /* Products */;
ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */;
}, ... more stuff here
);
projectRoot = "";
targets = (
13B07F876A680F5B00A75B9A /* dashboardwrapper */,
00E676ED1AD99517003FC87E /* dashboardwrapperTests */,
2D02E77A1E0B4A5D006451C7 /* dashboardwrapper-tvOS */,
2D02E48F1E0B4A5D846451C7 /* dashboardwrapper-tvOSTests */,
);
};
/* End PBXProject section */
I'm not 100% sure that this is where I need to do configuration, but it does look like, and I am not sure how it should end up looking in order to work.
Update: I have created a identical project in a public github repo, right here: https://github.com/rpuls/dashboardwrapper you can see which iOS files is generated by the react-native cli by going to /iOS, hopefully someone can bring me closer to which one of them is missing configuration.
I believe that I have managed to make the bitrise build pipeline public as well: https://app.bitrise.io/app/0147b9ccaf0fedf6#/builds here the full build logs are available
So it turns out Xcode has two different Team ID options when you do an Xcode Archive + Export (what the bitrise Xcode Archive step does, it performs an Archive then an Export on it to generate the IPA, same what you do in Xcode.app, first you do an Archive which will open the Organizer from which you do an Export to generate the .ipa).
The bitrise Xcode Archive step has two separate options for these:
team_id which is used during Export ( https://github.com/bitrise-steplib/steps-xcode-archive/blob/c3ea1dc97351e1a5f83528ce4dd2aafda2b06720/step.yml#L77 )
and force_team_id which is used during Archive ( https://github.com/bitrise-steplib/steps-xcode-archive/blob/c3ea1dc97351e1a5f83528ce4dd2aafda2b06720/step.yml#L115 )
Based on your build log ( https://app.bitrise.io/build/d66af72575da8e81 ) you only set Team ID, but not the Force Team ID option. If you set both that should work.
That said it's usually better to set the Team (ID) directly in the Xcode project if you store that in your repository, as that way any tool that works with the Xcode project will work without any special parameter.
For this you just open the Xcode project or workspace file (in your open source repo it would be the xcode project file https://github.com/rpuls/dashboardwrapper/tree/master/ios/dashboardwrapper.xcodeproj ), and in Xcode.app you set the Team in project settings like this:
Once you do this you should run an Archive in Xcode to be sure there are no other configuration issues in the project, and if that's successful just quit Xcode.app and commit+push the project file changes into the repo.
With this setup all the tools should work out of the box, e.g. https://github.com/bitrise-io/codesigndoc which is prompted on the bitrise.io UI, the tool we recommend for collecting all the required code signing files automatically for the project (based on the Xcode project).

How to write different script for Debug and Release Builds Xcode IOS

I am integrating crashlytics for android and ios apps for android using build flavor we can give separate organization key but in ios debug and release scheme i need to run different script because i need to provide different keys to that project.
script
"${PROJECT_DIR}/Fabric.framework/run" 834343231341432432432432432408497cdbfa13ceb728b296e1c595557bb8c389a33693f150f
There's many options for build confg in iOS as well depending on your project.
You could use configuration files :
xcconfig
1 : Create a new xcconfig file ( base.xcconfig) with the following :
KEY = YOUR_DEBUG_KEY
2 : Create a release config file ( release.xcconfig) :
KEY = YOUR_LIVE_KEY
3 : Set the newly created files in project settings :
4 : In the Build Phase :
"${PROJECT_DIR}/Fabric.framework/run" ${KEY}
Another simple way to do it ( if something needs to be changed in the code itself) :
#ifdef DEBUG
// debug config
#else
// release config
#endif
You can edit your sheme to add a script for each configuration.
EDIT: You click on your scheme -> Edit Scheme... -> Click on Build Arrow -> Pre/Post actions -> + -> New Run Script Action

Xcode 8 Beta - Convert to Current Swift Syntax Failed: Could not find test host

I am receiving an error message when I try to use Xcode 8's Convert Wizard.
After trying rebooting, downloading fresh code, and deleting my DerivedData files I cannot escape this error:
Convert to Current Swift Syntax Failed: Could not find test host
I have tried both options which are: Swift 2.3 and Swift 3. After I select a version I instantly get that error.
Here is a screenshot of the error:
This worked for me:
Select the Xcode project in the lefthand browser.
Click on your test target in the Project's General tab.
Disclose "Testing". In my project the "Host Application" pulldown button was blank. Select your appropriate host application.
Try building your test target now. If that succeeds then converting syntax should as well.
I had this problem after installing the Xcode 8 beta so I assume this is related.
Picture Credit to #karthikkck
It cost me a bit of time to find the "Host Application" pulldown mentioned in the otherwise very helpful answer by iluvcapra.
So this is what he meant:
This is where you find the pulldown menu. Select your main target.
I find easy fix for this, just edit your Scheme and disable tests.
And run conversion again.
+1 iluvcapra
Alternatively, use text editor to remove the following two items from your MyAppSwift.xcodeproj/project.pbxproj file, search for TEST_HOST
Now, re-open your project and run the convert wizard again.
4EFFFAE51B53D5D8003CD25A /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
FRAMEWORK_SEARCH_PATHS = (
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
);
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
INFOPLIST_FILE = "AF SwiftTests/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) #executable_path/Frameworks #loader_path/Frameworks";
PRODUCT_NAME = "FA SwiftTests";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/AF Swift.app/AF Swift";
};
name = Debug;
};
4EFFFAE61B53D5D8003CD25A /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
FRAMEWORK_SEARCH_PATHS = (
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
);
INFOPLIST_FILE = "AF SwiftTests/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) #executable_path/Frameworks #loader_path/Frameworks";
PRODUCT_NAME = "FA SwiftTests";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/AF Swift.app/AF Swift";
};
name = Release;
};
Please try these Steps:
Select your project on the left side of Xcode.
Go to Targets and select your Project Tests.
Select the General Tab and select Host Application drop down and choose your Host Application.
Convert or Run your project.
Trying these steps worked for me.
In my case I deleted my tests target, then re-added it using the + below targets and selecting "iOs Unit Testing Bundle"
For some reason this got a compile error, so I changed the "Per-configuration Intermediate Build Files Path: for my test target to $(PROJECT_TEMP_DIR)/$(CONFIGURATION) for both debug and release. This allowed the compile to work.
Fix this in 3 steps:
First delete your test target
The select Edit -> Convert -> To current Swift syntax... and perform the conversion
Then add a new test target

xcodeproj adds framework but linker can't find it

I'm adding a custom framework to my Xcode project using the xcodeproj Ruby Gem:
top_group = project.groups[0]
framework_ref = top_group.new_file(framework_path)
target = project.targets[0]
target.frameworks_build_phase.add_file_reference(framework_ref)
When I then open Xcode and look at the target, the framework is listed correctly under Linked Frameworks and Libraries, yet the linker complains that the framework cannot be found when building. Dragging the framework in the Linked Frameworks list in Xcode fixes it, and I can build successfully.
Why? Dragging seems to force Xcode to regenerate the project.pbxproj and add a missing reference. What would that be?
you need to set the path where your framework is!
append the path in build settings for "FRAMEWORK_SEARCH_PATHS"
settings = target.build_settings("Debug")
settings["FRAMEWORK_SEARCH_PATHS"] = [settings["FRAMEWORK_SEARCH_PATHS"], your_framework_directory ]
or
settings["FRAMEWORK_SEARCH_PATHS"] = settings["FRAMEWORK_SEARCH_PATHS"] + " " + your_framework_directory ]
Append the path in build setting as follows:
#Add framework search path
settings = target.build_settings("Release")
settings["FRAMEWORK_SEARCH_PATHS"] = Array(settings["FRAMEWORK_SEARCH_PATHS"])<< '$(PROJECT_DIR)/SDK'
settings["LIBRARY_SEARCH_PATHS"] = Array(settings["LIBRARY_SEARCH_PATHS"])<< '$(PROJECT_DIR)/SDK'

Localize iOS App name in Unity

I'm'developing a Unity3D game that shows a different (localized) app name in the iPhone's home screen according to the user local language. Note that:
I already know how to localize the iOS app name by editing the Xcode project (create a InfoPlist.string file, localize it, add the CFBundleDisplayName key to it, etc.)
I also know how automatically localize an Android app name within the Unity editor (add a values-XX.xml file with the app_name property onto Assets/Plugins/Android/res/ folder, etc.)
The question is: how can I automatically localize my iOS app name within the Unity Editor so that I don't need to perform the error-prone task 1. every time I build the project?
I think that PostprocessBuildPlayer should be the way to go, however I haven't found any documentation on how to parse it and/or modify the Xcode project file correctly to achieve this.
Long time ago I ran into trouble when I tried to modify info.plist via the Build Player Pipeline especially when doing it in Append mode. It works only once and then subsequent builds fail with "The data couldn’t be read because it isn’t in the correct format." (s. Unity forum posts like this one and my blog posting about this problem) So I decided to take the alternative way combining a customised build with an Xcode Build Pre-action.
Three steps are required:
(1) Xcode setup:
In Xcode go to Edit Scheme / Build / Pre-actions. Then click the + sign to add a New Run Script Action.
In Provide build settings select Unity-iPhone.
Paste . ${PROJECT_DIR}/modify_info_plist.sh (note the dot and blank at the beginning, is ensures that the script is executed in the caller's shell)
So it should look like this:
(2) Script modify_info_plist.sh:
Within your script you have access to all environmet variables from Xcode (s. Xcode Build Setting Reference) and you can manipulate Info.plist using the defaults command (man page). Here is a sample I used to add gyroscope to the UIRequiredDeviceCapabilities:
# Code snippet used in Unity-iPhone scheme as "Build Pre-Action"
my_domain=${PROJECT_DIR}/Info.plist
status_bar_key=UIViewControllerBasedStatusBarAppearance
logger "Start adding keys to info.plist"
defaults write $my_domain $status_bar_key -boolean NO
if [ `defaults read $my_domain UIRequiredDeviceCapabilities | grep "gyroscope" | wc -l` = "0" ]; then
defaults write $my_domain UIRequiredDeviceCapabilities -array-add "gyroscope"
fi
logger "Keys added to info.plist successfully"
(3) Build Pipeline:
Put the following code in a static editor class to create a new menu item Tools / My iOS Build with shortcut cmd+alt+b:
static string IOSBuildDir= "Develop";
[MenuItem("Tools/My iOS Build %&b")]
public static void IOSBuild () {
string[] levels = { "Assets/Scenes/Boot.unity",
"Assets/Scenes/Level-1.unity",
// ...
"Assets/Scenes/Menu.unity"
};
string path = Directory.GetCurrentDirectory ();
path += "/" + IOSBuildDir + "/Info.plist";
if (File.Exists (path)) {
Debug.Log ("Removing file " + path);
File.Delete (path);
}
BuildPipeline.BuildPlayer (levels, "Develop", BuildTarget.iPhone,
BuildOptions.AcceptExternalModificationsToPlayer);
}
I know this is no perfect solution but it's the only one I found to work stable. Two drawbacks:
Step (1) has to be repeated after major Xcode format changes
New scenes have to be appended in the editor class code in step (3)

Resources