Xcode - How to auto select resource based on build config? - ios

So just like the question's title, does Xcode have this feature so that we can select which resource to compile based on build config?
For example I have 2 build config: A and B
can I do something like this in my project structure:
- A
-- ui1.xib
-- ui1.swift
- B
-- ui1.xib
-- ui1.swift
- uiCommon.xib
- uiCommon.swift
so when I select build config A, the file in A folder that will be compiled automatically.
We can achieve this in Android by using Flavor right?
Can we achieve this in xcode?
In Xcode we can just put anyname.~iphone.xib and anyname.~ipad.xib for different layout based on device types. Can we do something like this for build config?

Click on the resource file at the left sidepanel in Xcode, then select document properties tab (sheet of paper icon) at the right sidepanel and change "Target Membership" option for needed resource.
To use the same resource name for different targets - place the resources in separate folders like TargetAResources, TargetBResources.

Related

Swashbuckle custom asset not found

I added to SwaggerConfig.cs this string
c.CustomAsset("index", thisAssembly, "Table.Web.CustomContent.index.html");
...than I run the application, go to swagger docs and get error:
An error has occurred.
Embedded resource not found - Table.Web.CustomContent.index.html
Swashbuckle.SwaggerUi.AssetNotFound
The build action property of the index.html was set to embedded resource
What should I do to fix it?
I struggled with this for a while today in a ASP.NET C# project and finally resolved it by cobbling together a few different resources.
First (as noted in the Swagger comments), the item must be marked as an Embedded Resource by right-clicking the item in the solution explorer and going to Properties, and selecting Embedded Resource from the Build Action dropdown.
Second, the logical name can be tricky to identify. In my case, a dash in a directory name was being converted to an underscore once embedded, leading to lots of hair-pulling (hair_pulling?). The easiest way to get the true logical path is to get it from the Build Output window.
Go to Tools => Options
Expand the Projects and Solutions sidebar item and click Build and Run
Set the MSBuild Output to Detailed.
Clean the solution and rebuild, opening the Output window if necessary.
The output log should unambiguously state the true logical name of the file with a line like...
Resource file 'swagger-ui\SwaggerUiStyle.css' gets manifest resource name 'MySolutionName.swagger_ui.SwaggerUiStyle.css'
(credit to #bkwdesign for his excellent explanation on this part)

Custom Schema Types

I'm working through the "Building Graph-Based Web Applications With Structr 1.0" video and I've hit a bump when I get to adding a custom schema type.
First - it lists the new type "extends" a bunch of types - so far I haven't found what that means, so I've left it as an AbstractNode.
Next - when I add the type and then go to the "Data" tab, the new type isn't in the tab list - if I click on "Schema Node" the new types are listed there like so:
I checked the .config file to see if the schema service is setup to start, and it's in the list:
configured.services = NodeService AgentService CronService SchemaService LogService HttpService FtpService CloudService
There's no "Show Custom types" option on my "Data" tab - it looks like this:
How do I proceed from here?
Running 2.0 Build 5403 gave me the updated tabs in the Data area.

Different app-name depending on configuration when app-name is localized in InfoPlist.strings

We use a setup with different plists for each configuration. Like this:
Target-Info-Dev.plist, Target-Info-Beta.plist...
This way our configurations could have their own CFBundleDisplayName, and we can differentiate builds by app-name on device. Like this: "DEV Appname", "BETA Appname"...
However, now we are required to localize the app-name. We have done this by creating a localized InfoPlist.strings for each target:
"CFBundleDisplayName" = "<localized-appname>";
"CFBundleName" = "<localized-appname>";
But since the CFBundleDisplayName is no longer derived from Target-Info-[Configuration].plist, we cannot differentiate the app-name for different configurations.
It should be noted that we have several Targets as well, for different brands of the same app, but we already got that working by haveing a separate InfoPlist.strings for each target.
Anybody have an idea of how to accomplish both localized and configuration-based app-name?
Better Solution
Edit Info.plist, set CFBundleDisplayName's value to a variable named something like $(MY_DISPLAY_NAME)
Open 'Build Settings' tab of the project or target, add a key named MY_DISPLAY_NAME under User-Defined section(you need scroll to the bottom to find this section), then just expand the newly-added key, and set any name for each configuration as you wish.
When building your project, every variable in the Info.plist will be replaced to its value.
The solution is much simpler than the original one.
Original Solution
I had the same requirement in my project, and then I found your question, and at last I solved it.
Edit your projects' scheme, add pre-action and post-action script to execute your change. Like this,
Step 1. change app name in Build's Pre-actions
str=""
if [ "${CONFIGURATION}" == "Debug" ];then
str="dev"
elif [ "${CONFIGURATION}" == "AdhocDevelopment" ];then
str="dev"
elif [ "${CONFIGURATION}" == "AdhocDistribution" ];then
str="adhoc"
elif [ "${CONFIGURATION}" == "DailyBuild" ];then
str="rdm"
fi
perl -pi -e "s/appName[^<]*/appName${str}/g" ${PROJECT_DIR}/smd/Info.plist
Step 2. Restore app name in Build's Post-actions
perl -pi -e "s/appName[^<]*/appName/g" ${PROJECT_DIR}/smd/Info.plist
echo ${PROJECT_DIR}/${INFOPLIST_FILE} > ~/tmp.txt; rm -f ~/tmp.txt
Something to explain: Debug/AdhocDevelopment/AdhocDistribution/DailyBuild are your projects' configuration names; ${CONFIGURATION} is predefined by Xcode; perl is preferable to awk and sed, which are all pre-installed on every mac OS X.
By the way, what I have done is changing appName in Info.plist, you can change your infoPlist.strings. In this way, you just need a single Info.plist file.
Since the file InfoPlist.strings is not just 1 single file, but is spread across multiple folders and files like so: en.lproj/InfoPlist.strings, de.lproj/InfoPlist.strings. It is a bit trickier to use it for different schemes.
Here is how I localized the name of the Today Widget shared by 2 flavors / schemes of the same target. For demonstration purposes, I used 2 "flavors": TA and EC. I will refer to them in this answer.
Step 1:
Create folders for each "flavor" or scheme in the target directory. Name each folder exactly as they are named in your user-defined scheme. Copy there the InfoPlist.strings file.
This step might be tricky. What I did: I created a new folder in XCode and named it TA. I dragged & dropped there my InfoPlist.strings file, then browsed to that folder in Finder, duplicated that folder, and renamed it to EC. Then, I drag & dropped it into XCode. Don't add it to any target. It is not needed.
Step 2:
Remove the InfoPlist.strings from the target's Copy Bundle Resources build phase:
Click on your project name -> Select the widget's target (ex. Today Widget) -> go to Build Phases -> open the Copy Bundle Resources -> find the file InfoPlist.strings, select it and press Delete button
Step 3:
Add a new Run Script to copy the correct InfoPlist.strings file
Here is the script I came up with which will copy the correct file, based on the current flavor/scheme your app is running now:
for lng in en de es fr it nl pt-PT tr
do
INFO_PLIST_FILE="${PROJECT_DIR}/TodayMatchesWidget/${APP_FLAVOR}/${lng}.lproj/InfoPlist.strings"
BUILD_APP_DIR="${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}"
FILE_LOCATION="${BUILD_APP_DIR}/${lng}.lproj/InfoPlist.strings"
cp "${INFO_PLIST_FILE}" "${FILE_LOCATION}"
done
This is a for loop, which iterates through all my localization
languages. You need to put there only the languages that you support.
Each language abbreviation should be separated by a space, nothing
else.
The only variable which you need to take care of is APP_FLAVOR,
which in my case is a user-defined setting inside the project's Build Settings, and in my case will be either TA or EC.
Here is the final folder structure in Today Widget's folder:
P.S:
I assume you already have a InfoPlist.strings file in the target's directory. If not, just add a new Strings File and call it InfoPlist.strings and add this value inside:
CFBundleDisplayName = "My Localized Widget";
I hope it helps anyone out there!
Here's how you can have different InfoPlist.strings for different build configurations in the same target, using only Build Settings and a few duplicate Info.plist files.
In your Build Settings:
Specify a different Info.plist File (INFOPLIST_FILE) for each configuration.
Set Adjust Strings File Names for Info.plist (STRINGS_FILE_INFOPLIST_RENAME) to Yes. On Xcode 14, it was set to Yes by default.
Create .strings files with the base name of your Info.plist filename + Plist.strings.
For example, if your Info.plist filename is Beta-Info.plist, your strings file should have the name Beta-InfoPlist.strings. Make sure you include all of these strings file to your build.
Do not include an InfoPlist.strings file in your target.
The key to making this work is Adjust Strings File Names for Info.plist in the Build Settings Reference.
Adjust Strings File Names for Info.plist.
Setting name: STRINGS_FILE_INFOPLIST_RENAME
If enabled, renames .strings files whose basename matches that of the target’s Info.plist file, to InfoPlist.strings in the built product.
Example
Here's an example in my app which has 3 different variants (AdSupported, AdSupported-Dev, Pro) that require different app names.
Build settings.
Strings files. They are all included in my target.
Info plist files. As usual, they are specified in the Build Settings and NOT included in my target.

how to add file extension in adobe-brackets editor ?

I am using files with .html.eco extension in my web project and I am trying to edit in Adobe Brackets but I can't specify that it should treat this as HTML file, to provide the typical features of editing html file (like color support, grammar, etc.).
In fact I noticed that this is possible when changing languages.json file, however I am using the binary version and I didn't build from source.
https://github.com/adobe/brackets/blob/master/src/language/languages.json
Any help ?
Update: this is now much easier to do:
Open the .html.eco file
In the status bar (lower-right), click the dropdown that says "Text"
Select the "HTML" option
Open the dropdown again and select the "Set as Default" option at the top
Original answer:
There's a backlog item for making this easily configurable (please upvote!), but in the meantime you can do it by writing a very simple Brackets extension:
define(function (require, exports, module) {
var LanguageManager = brackets.getModule("language/LanguageManager");
var language = LanguageManager.getLanguage("html");
language.addFileExtension("html.eco");
});
Put this code in a file named main.js
In Brackets, go to Help > Show Extensions Folder
Create a new folder under user, and place the main.js file inside it
Restart Brackets
Here's more info on writing Brackets extensions, if you're curious.
The approach referenced using the status bar menu does not persist across sessions. An option to persist settings across all projects and all sessions is easily accomplished by editing the preferences file (accessible through the Debug menu) and associating the file extension to the desired language.
Debug -> Open Preferences File
{
"language.fileExtensions": {
"html.eco": "html"
}
}

iOS changing target name

In iOS project, I changed the target name.
But for building, on the top left (beside stop button), its still showing old target name only... What should I change so that old project name will completely disappear from XCode?
Select your target from TARGETS(in left navigation bar) and double click, then rename it.
Just Click on your target Name beside stop button > Manage Schemes > Select and change name
If you want to change Project Name, Target name, -Info.plist name & -Prefix.pch name then,
- Select Project in Xcode (.xcodeproj file)
- Selecte file inspector
- In identity section change project name which u want to update & press enter
- After scanning whole project it will ask to change the file names i.e target, plist & pch file
- Select check boxes as per your need
Target name(TARGET_NAME)
To change a Target name(TARGET_NAME) you can:
Rename a target via Project Settings(Double click or press Return)
Also after changing Target Name you can:
Rename a schema via Manage Schemas... -> Select -> Press Return
Rename a root Group via Navigator. In this case you should resolve errors that can be caused by out-to-date path. For example:
Info.plist(INFOPLIST_FILE) or
Build input file cannot be found: '<some_path>/Info.plist'
Bridging Header(SWIFT_OBJC_BRIDGING_HEADER) or
error opening input file '<some_path>/<module_name>-Bridging-Header.h' (No such file or directory)
Move umbrella header from private to public scope or
Umbrella header '<name>.h' not found
[Xcode components]
To make the change of target name effective you can go to manage schemes and there, remove all old targets. Then click on "Autocreate Schemes Now"

Resources