In Xcode 9, when you create a group it creates a linked folder in the file system, too. So you don't need to create folder for each group manually. A good explanation about the group and folder related changes in Xcode 9, see this.
I have a custom Xcode project template which generates a project and adds loads of Swift boilerplate source files in custom folders. My problem is that I can only create group folders like this: , which represents a Group not associated with a file system directory. It's not good because if you later rename a folder in Xcode, it will have no effect on the corresponding file system directory.
My goal is to write an Xcode project template that adds my custom boilerplate swift files in real reference folders like this: .
You can download my simplified template from here, place it under: ~/Library/Developer/Xcode/Templates
Then Xcode > File > New > Project, and select Custom-Template.
TemplateInfo.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Kind</key>
<string>Xcode.Xcode3.ProjectTemplateUnitKind</string>
<key>Concrete</key>
<true/>
<key>Identifier</key>
<string>custom-swift.xcodeTemplate</string>
<key>Description</key>
<string>Swift starter project for iOS projects</string>
<key>Ancestors</key>
<array>
<string>com.apple.dt.unit.cocoaTouchFramework</string>
</array>
<key>Nodes</key>
<array>
<string>Classes/Interfaces/CustomInterface.swift</string>
</array>
<key>Definitions</key>
<dict>
<key>Classes/Interfaces/CustomInterface.swift</key>
<dict>
<key>Group</key>
<array>
<string>Classes</string>
<string>Interfaces</string>
</array>
<key>Path</key>
<string>Classes/Interfaces/CustomInterface.swift</string>
</dict>
</dict>
</dict>
</plist>
It creates a project like this:
What I'd like to achieve:
Any help is much appreciated! :)
Update 1:
I found a small workaround.. Create your own complex folder hierarchy with the template script then simply delete the root folder - in my case "Classes". Then open the Trash and drag it back to Xcode, select "Copy items if needed" and select "Create groups". It will build the folder structure with real reference folders.
Here is what you need to do.
In the node section specify the group before naming the file.
<key>Nodes</key>
<array>
<string>MyGroup/File.swift:comments</string>
<array>
Next in the definitions provide the group name in the key like so:
<key>Definitions</key>
<dict>
<key>MyGroup/File.swift</key>
<dict>
<key>Path</key>
<string>File.swift</string>
<key>Group</key>
<string>MyGroup</string>
</dict>
Hopefully this will help.
For That purpose one can use Components as used in imessages template
Example of component is
<key>Components</key>
<array>
<dict>
<key>Identifier</key>
<string>com.apple.dt.unit.messagesextensioncomponentios</string>
<key>Name</key>
<string>___PACKAGENAME___ MessagesExtension</string>
<key>ProductBuildPhaseInjections</key>
<array>
<dict>
<key>TargetIdentifier</key>
<string>com.apple.dt.messagesOnlyApp</string>
</dict>
</array>
</dict>
</array>
Related
This question already has answers here:
Info.plist contained no UIScene configuration dictionary (looking for configuration named "(no name)")?
(3 answers)
Closed last month.
I'm trying to store some data, but every time I execute the proper command to do it, I get this message on the console:
GlassyFy[3435:69406] [SceneConfiguration] Info.plist contained no UIScene configuration dictionary (looking for configuration named "(no name)")
I've been looking for solutions about Info.plist (it seems to be the main reason) but I can't find the damn file... or maybe I'm wrong and that's not the reason of this problem.
go into Xcode project build settings and search for INFOPLIST_FILE or simply plist. You should see if there is a folder noted at all, if not write a note into the property field where that Info.plist is or should be, which could in your case look like GlassyFy/Info.plist
you can read also the docu about.
if there is no folder/info.plist than Xcode can also not store your app properties into such file. Search also manually your project folders, maybe even the folder above (..) if your project wrote a info.plist in the wrong place.
and here UIScene definition that usually belongs into info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/> // < --- see should be false when you have just one.
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key> // the name
<array> // the info for that Session
<dict>
<key>UISceneClassName</key>
<string>UIWindowScene</string>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>SceneDelegate</string>
<key>UISceneStoryboardFile</key>
<string>Main</string>
</dict>
</array>
<key>anotherkey</key> //but remember above i wrote false..
<array> // so the property should be <true/> when multiple..
....
</array>
</dict>
</dict>
</plist>
So you see here one definition for UIScene named UIWindowSceneSessionRoleApplication, you can have multiple and so such would appear below with similar structure.
when you change the folder of Info.plist make sure to close and open your project and possibly even Xcode before changing more properties
My app is using a Siri extension with custom Siri intents, which is a new feature for Xcode 10 / iOS 12. I design my custom Siri intents in a .intentdefinition file (included for both app and extension targets).
My custom (not system) Siri intents are declared within the "Do" category.
A Siri intent also requires a AppIntentVocabulary.plist file with example phrases in it https://developer.apple.com/documentation/sirikit/registering_custom_vocabulary_with_sirikit
I've got my AppIntentVocabulary.plist included for the app target only. It looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IntentPhrases</key>
<array>
<dict>
<key>IntentName</key>
<string>MyIntentName1</string>
<key>IntentExamples</key>
<array>
<string>Do stuff with foo</string>
<string>Do stuff with fu</string>
</array>
</dict>
<dict>
<key>IntentName</key>
<string>MyIntentName2</string>
<key>IntentExamples</key>
<array>
<string>Do other stuff</string>
</array>
</dict>
</array>
<key>ParameterVocabularies</key>
<array>
<dict>
<key>ParameterNames</key>
<array>
<string>MyIntentName1.someParam</string>
</array>
<key>ParameterVocabulary</key>
<array>
<dict>
<key>VocabularyItemIdentifier</key>
<string>paramName</string>
<key>VocabularyItemSynonyms</key>
<array>
<dict>
<key>VocabularyItemPhrase</key>
<string>foo</string>
<key>VocabularyItemPronunciation</key>
<string>fu</string>
<key>VocabularyItemExamples</key>
<array>
<string>Do stuff with foo</string>
</array>
</dict>
<dict>
<key>VocabularyItemPhrase</key>
<string>bar</string>
<key>VocabularyItemPronunciation</key>
<string>bur</string>
<key>VocabularyItemExamples</key>
<array>
<string>Do stuff with bar</string>
</array>
</dict>
</array>
</dict>
</array>
</dict>
</array>
</dict>
</plist>
It builds fine and works ok too. But when I'm trying to submit it to App Store, I get:
[Transporter Error Output]: ERROR ITMS-90624: "Invalid Intent
Vocabulary. The AppIntentVocabulary.plist file in the
Payload/AppName.app/en.lproj folder can't contain the intent name
"MyIntentName1"."
And there are subsequent error messages repeating for every .lproj folder.
If it helps, my app is localized for 14 languages, the project is not using base localization.
I had a similar issue when not using Base Localization. As stated from the Apple Docs:
Place your AppIntentVocabulary.plist file in the language-specific
(.lproj) directory of your iOS app that corresponds to your base
development language.
Not using Base localization can create this kind of problems especially with key names, as it needs a neutral name (using the same English wording works as well) to link against all the localized keys.
For the moment, you can only define custom vocabulary on a few specific types of intents: see here under "Register User-Specific Vocabulary" for a list, but it's things like ride sharing, notes, workouts etc. In other words, not your custom intents (that you might want to expose to iOS 12's Siri shortcuts - that's not available... yet).
And the docs say you need to specify one of those intents as the Intent name in the plist. Likewise, the parameter names need to be specific parameters of just those permitted intents. So I'm guessing that's why you're getting errors on uploading to the App Store - it's checking to see if Siri supports custom vocabulary for "MyIntentName1". Not sure why it's working locally for you, or why this isn't a check built into Xcode. 🤷♀️
I have been trying to create the Xcode File Template that contains boiler plate files and code structure for MVVM design pattern.
I created a module successfully with custom template using the plist configuration and file structure as below:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Kind</key>
<string>Xcode.IDEFoundation.TextSubstitutionFileTemplateKind</string>
<key>Description</key>
<string>MVVM Module Template.</string>
<key>Summary</key>
<string>MVVM Module Template</string>
<key>Options</key>
<array>
<dict>
<key>Identifier</key>
<string>productName</string>
<key>Required</key>
<true/>
<key>Name</key>
<string>Module Name:</string>
<key>Description</key>
<string>The module name.</string>
<key>Type</key>
<string>text</string>
<key>Default</key>
<string>Base</string>
</dict>
<dict>
<key>Identifier</key>
<string>View</string>
<key>Name</key>
<string>Also create View file for user interface</string>
<key>Description</key>
<string>Create a view file with the same name</string>
<key>Type</key>
<string>checkbox</string>
<key>NotPersisted</key>
<true/>
</dict>
</array>
</dict>
</plist>
Folder Structure For the Custom Template
The problem was that, when I checked the checkbox, all the files in the View folder was created, but when checkbox is not checked, non of the files are created.
What shall I do to achieve following cases:
Generate source files from the folder 'Source' when checkbox is unchecked.
Generate source files from the folder 'View' when checkbox is checked.
You're doing it right for when the checkbox is checked, but you need to change the "Source" to "default" for when the checkbox is unchecked.
I have my app localized in three languages and this runs as it should. I added a settings.bundle to the app and I can make changes in the settings and that works too. But I have serious problems with the localization. As suggested in other forums I created in Finder the two additional folders de.lproj and fr.lproj. Into them I copied the Root.strings. My Root.plist is a simple version with one group-item for the title and one Multi Value item with three titles/values inside. The titles/values doesn't need to be translated, but the both titles of the items.
My Root.strings have the following content:
"language" = "Sprache";
"selectedlanguage" = "Ihre Sprachwahl";
The "language" and the "selectedlanguage" are the values of the strings in the Root.plist wich shoulod be replaced:
<plist version=1.0">
<dict>
<key>PreferenceSpecifiers</key>
<array>
<dict>
<key>Title</key>
<string>language</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>Type</key>
<string>PSMultiValueSpecifier</string>
<key>Title</key>
<string>selectedlanguage</string>
....
</dict>
</array>
<key>StringsTable</key>
<string>Root</string>
How can I set up the localization to work? Is there a specific way to create the Root.strings or to "implement" them?
Ok, seems to be a simulator problem. On my iPhone it works.
I've been trying to setup settings for my app but I can't seem to get this working even though I've looked over it over and over again and compared it to an example in a book and the example on Craig Dunn's blog.
I understand that the syntax has to be perfect and this file is pretty simple at the moment I am just trying to display one textfield for now. I did get this working briefly on a brand new project however I haven't managed to get it to work since.
Here is the XML of my Root.plist file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Root</key>
<dict>
<key>PreferenceSpecifiers</key>
<array>
<dict>
<key>Title</key>
<string>Group Name</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>AutocapitalizationType</key>
<string>None</string>
<key>AutocorrectionType</key>
<string>No</string>
<key>Key</key>
<string>usernameTextField</string>
<key>Title</key>
<string>Username</string>
<key>Type</key>
<string>PSTextFieldSpecifier</string>
</dict>
</array>
</dict>
</dict>
</plist>
As I said I've looked over it quite a lot of times and I can't see any problems with it. The file build action is set to Content and the Copy to Output Directory is set to Always Copy. The version of MonoTouch that I'm using is 6.0.7.
I'd appreciate any help with this issue. Thanks
Make sure that the Settings.bundle directory is included at the top level of the project. By top-level, I mean that on the file system, the Settings.bundle directory should be in the same directory as your ProjectName.csproj file. In MonoDevelop, it will appear as one of the top-level folders under the project node.
Set the Root.plist Build Action to BundleResource (do not enable "Copy to Output Directory". Hint: if you find yourself setting "Copy to Output Directory", don't do it - it's almost always the wrong thing to do - we've actually discussed removing the option altogether.)
Now, for the plist file format - here's what it should look like:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreferenceSpecifiers</key>
<array>
<dict>
<key>Type</key>
<string>PSGroupSpecifier</string>
<key>Title</key>
<string>Group Name</string>
</dict>
<dict>
<key>Type</key>
<string>PSTextFieldSpecifier</string>
<key>Title</key>
<string>Username</string>
<key>AutocapitalizationType</key>
<string>None</string>
<key>AutocorrectionType</key>
<string>No</string>
<key>KeyboardType</key>
<string>Alphabet</string>
<key>IsSecure</key>
<false/>
<key>Key</key>
<string>usernameTextField</string>
<key>DefaultValue</key>
<string></string>
</dict>
</array>
<key>StringsTable</key>
<string>Root</string>
</dict>
</plist>
Looking at your Root.plist file, it appears that the PreferenceSpecifiers key is not in the top-level dict node (it needs to be). In other words:
get rid of the following lines at the top of the file:
<dict>
<key>Root</key>
...and one of the following lines at the end of your file:
</dict>
That should do it...
Now... all that said, I just recently figured this out myself while trying to add settings to my personal side project and decided that we, at Xamarin, need to make this easier. I've already fixed a few minor issues in the upcoming MonoDevelop 3.1, but I hope to get the time I need to add templates for Settings.bundle to MonoDevelop's "Add New File" wizard. I'd also like to add plist key/value hinting like we do for Info.plist and Entitlements.plist so that MonoDevelop's plist editor can better guide you when editing these plist files.
For starters, you are missing your closing plist </plist> tag. My current one only has one setting in it, but it works. You can compare to yours to see the differences:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreferenceSpecifiers</key>
<array>
<dict>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
<key>Title</key>
<string>Stay Signed-In</string>
<key>Key</key>
<string>staySignedIn</string>
<key>DefaultValue</key>
<true/>
</dict>
</array>
</dict>
</plist>
I hope this helps.