Creating groups using a custom template xcode 8 - xcode

I have successfully created an Xcode 8 template that will respond to these actions:
You already have a working project
You want to add your custom swift file to this project
Step by step, how to achieve that:
I have created under:
/Users/*YOUR_USER_NAME*/Library/Developer/Xcode/Templates/File Templates
The folder name Custom/Interactor.xctemplate
Files inside that folder:
___FILEBASENAME___Interactor
TemplateInfo.plist
TemplateIcon.png
TemplateIcon#2x.png
So when I right click and create new file, I will choose the custom file:
The above example works and creates my custom file:
What I am trying to achieve:
I am trying to create a group that will contain the new custom file. No need for an actual folder or complicated tasks, simply a group that contains the actual file.
So the end result will be:
Since there is no documentation explaining how to create a custom template I have used many references: ref1, ref2, ref3, ref4.
Here is the TemplateInfo.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>DefaultCompletionName</key>
<string>MyCustomInteractor</string>
<key>Description</key>
<string>Custom interactor</string>
<key>Kind</key>
<string>Xcode.IDEKit.TextSubstitutionFileTemplateKind</string>
<key>Options</key>
<array>
<dict>
<key>Description</key>
<string>Custom interactor</string>
<key>Identifier</key>
<string>fileName</string>
<key>Name</key>
<string>Custom name</string>
<key>NotPersisted</key>
<true/>
<key>Required</key>
<true/>
<key>Type</key>
<string>text</string>
</dict>
<dict>
<key>Default</key>
<string>___VARIABLE_fileName:identifier___</string>
<key>Identifier</key>
<string>productName</string>
<key>Type</key>
<string>static</string>
</dict>
<dict>
<key>Default</key>
<string>___VARIABLE_fileName:identifier___Interactor</string>
<key>Description</key>
<string>The interactor name</string>
<key>Identifier</key>
<string>interactorName</string>
<key>Name</key>
<string>Interactor Name:</string>
<key>Required</key>
<true/>
<key>Type</key>
<string>static</string>
</dict>
</array>
<key>Platforms</key>
<array>
<string>com.apple.platform.iphoneos</string>
</array>
<key>SortOrder</key>
<string>99</string>
</dict>
</plist>
What I have tried:
I have tried to insert this answer into my TemplateInfo.plist but nothing happens. In my opinion it could be related to a scope issue - perhaps I am not inserting the Definitions or the Nodes keys in the right place. The xml Definitions and Nodes code snip I have been struggling with:
<key>Definitions</key>
<dict>
<key>___FILEBASENAME___Interactor.swift</key>
<dict>
<key>Group</key>
<string>Custom Interactor</string>
<key>Path</key>
<string>___FILEBASENAME___Interactor.swift</string>
</dict>
</dict>
<key>Nodes</key>
<array>
<string>___FILEBASENAME___Interactor.swift</string>
</array>
So where should I insert those keys or what am I doing wrong ?
Any help would be much appreciated.
Thanks.

you can create group as well as folder in project directory using this
<key>Swift</key>
<dict>
<key>Nodes</key>
<array>
<string>ViewController.swift:comments</string>
<string>ViewController.swift:imports:importCocoa</string>
<string>ViewController.swift:implementation(___FILEBASENAME___: UIViewController)</string>
<string>ViewController.swift:implementation:methods:viewDidLoad(override func viewDidLoad(\))</string>
<string>ViewController.swift:implementation:methods:viewDidLoad:super</string>
<string>ViewController.swift:implementation:methods:didReceiveMemoryWarning(override func didReceiveMemoryWarning(\))</string>
<string>ViewController.swift:implementation:methods:didReceiveMemoryWarning:super</string>
<string>Constant/CommonExtension.swift</string>
</array>
</dict>
and Definition just like this
<key>Definitions</key>
<dict>
<key>Base.lproj/Main.storyboard</key>
<dict>
<key>Path</key>
<string>Main.storyboard</string>
<key>SortOrder</key>
<integer>99</integer>
</dict>
<key>Group</key>
<array>
<string>Singletone</string>
</array>
<key>Constant/CommonExtension.swift</key>
<dict>
<key>Path</key>
<string>Constant/CommonExtension.swift</string>
<key>Group</key>
<array>
<string>Constant</string>
</array>
</dict>
</dict>

Incase this helps someone, Xcode 12.4 - project template.
<key>Nodes</key>
<array>
<string>ViewController.swift:comments</string>
<string>ViewController.swift:imports:importCocoa</string>
<string>ViewController.swift:implementation(___FILEBASENAME___: UIViewController)</string>
<string>ViewController.swift:implementation:methods:viewDidLoad(override func viewDidLoad(\))</string>
<string>ViewController.swift:implementation:methods:viewDidLoad:super</string>
<string>Info.plist:UIMainStoryboardFile</string>
<string>Info.plist:UIApplicationSceneManifest:UISceneStoryboardFile</string>
<string>Some/MainCoordinator.swift</string>
<string>Some/Other/TestClass.swift</string>
</array>
<key>Definitions</key>
<dict>
<key>Some/MainCoordinator.swift</key>
<dict>
<key>Group</key>
<array>
<string>Some</string>
</array>
<key>Path</key>
<string>MainCoordinator.swift</string>
</dict>
<key>Some/Other/TestClass.swift</key>
<dict>
<key>Group</key>
<array>
<string>Some</string>
<string>Other</string>
</array>
<key>Path</key>
<string>TestClass.swift</string>
</dict>
</dict>
The group is Some.
There's a file inside it.
There's also a subgroup inside it called Other.
And there's a file inside Other called TestClass.

Related

Xcode template doesn't pick the variable from popup

I'm writing an XCode template. Everything works perfectly fine if I use text value for the variable:
<dict>
<key>Identifier</key>
<string>appName</string>
<key>Required</key>
<string>true</string>
<key>Name</key>
<string>App name</string>
<key>Description</key>
<string>App name desc</string>
<key>Type</key>
<string>text</string>
<key>NotPersisted</key>
<string>true</string>
</dict>
But it doesn't, if I use popup:
<dict>
<key>Identifier</key>
<string>appName</string>
<key>Required</key>
<string>true</string>
<key>Name</key>
<string>App name</string>
<key>Description</key>
<string>App name desc</string>
<key>Type</key>
<string>popup</string>
<key>NotPersisted</key>
<string>true</string>
<key>Values</key>
<array>
<string>AppX</string>
<string>AppY</string>
</array>
</dict>
I'm accessing the variable like that:
class ___VARIABLE_appName:identifier___TestCase {}
Tried with:
___VARIABLE_appName:identifier___
___VARIABLE_appName___
___VARIABLE_appName:value___
and still nothing. I can of course just use text, but popup would be really better.
The solution for me was to create 2 folders (AppX and AppY) and store the duplicated templates inside them. The only thing that differs between these 2 files - is VARIABLE_appName - but by storing templates in different folders I remove the necessity to have it as a variable. So I hardcoded the value instead.
Instead of just Template1.swift I now have:
Folder AppX
-Template1.swift
Folder AppY
-Template2.swift

How to make sub-syntaxes? Seems a syntax "category" is required

My goal is to extend the text.html syntax with a text.html.django syntax, so (for example) Django-only autocompletes don't show up when I'm working on a non-Django html file. Same thing with source.python and source.python.django.
The Djaniero package does just this, and using PackageResourceViewer, I've copied both syntax files and saved them into my User directory (both are below).
It's not working, and I'm wondering if it's because, when Djaniero in installed, these syntaxes are listed in a category:
But when I uninstall Djaniero, my syntaxes are not showing up in that same list. I am not finding anything obvious in the Djaniero resource files on how to make this category.
How do I create this syntax category? Or if that's not the issue, what am I missing?
Thanks.
C:\Users\jeffy\AppData\Roaming\Sublime Text 3\Packages\User\syntax_definitions\Python Django.tmLanguage
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>fileTypes</key>
<array>
<string>py</string>
</array>
<key>foldingStartMarker</key>
<string>^\s*(def|class)\s+([.a-zA-Z0-9_ b]+)\s*(\((.*)\))?\s*:|\{\s*$|\(\s*$|\[\s*$</string>
<key>foldingStopMarker</key>
<string>^\s*$|^\s*\}|^\s*\]|^\s*\)</string>
<key>keyEquivalent</key>
<string>^~P</string>
<key>name</key>
<string>Python Django</string>
<key>patterns</key>
<array>
<dict>
<key>match</key>
<string>(meta|models)\.(Admin|AutoField|BigIntegerField|BooleanField|CharField|CommaSeparatedIntegerField|DateField|DateTimeField|DecimalField|EmailField|FileField|FilePathField|FloatField|ForeignKey|ImageField|IntegerField|IPAddressField|ManyToManyField|NullBooleanField|OneToOneField|PhoneNumberField|PositiveIntegerField|PositiveSmallIntegerField|SlugField|SmallIntegerField|TextField|TimeField|URLField|USStateField|XMLField)\b</string>
<key>name</key>
<string>support.type.django.model</string>
</dict>
<dict>
<key>match</key>
<string>django(\.[a-z]+){1,} </string>
<key>name</key>
<string>support.other.django.module</string>
</dict>
<dict>
<key>match</key>
<string>(ABSOLUTE_URL_OVERRIDES|ADMIN_FOR|ADMIN_MEDIA_PREFIX|ADMINS|ALLOWED_HOSTS|ALLOWED_INCLUDE_ROOTS|APPEND_SLASH|AUTHENTICATION_BACKENDS|AUTH_USER_MODEL|AUTH_PROFILE_MODULE|CACHE_BACKEND|CACHE_MIDDLEWARE_ALIAS|CACHE_MIDDLEWARE_ANONYMOUS_ONLY|CACHE_MIDDLEWARE_KEY_PREFIX|CACHE_MIDDLEWARE_SECONDS|CSRF_COOKIE_DOMAIN|CSRF_COOKIE_NAME|CSRF_COOKIE_PATH|CSRF_COOKIE_SECURE|CSRF_FAILURE_VIEW|DATABASES|DATABASE_ENGINE|DATABASE_HOST|DATABASE_NAME|DATABASE_OPTIONS|DATABASE_PASSWORD|DATABASE_PORT|DATABASE_USER|DATABASE_ROUTERS|DATE_FORMAT|DATE_INPUT_FORMATS|DATETIME_FORMAT|DATETIME_INPUT_FORMATS|DEBUG|DEBUG_PROPAGATE_EXCEPTIONS|DECIMAL_SEPARATOR|DEFAULT_CHARSET|DEFAULT_CONTENT_TYPE|DEFAULT_EXCEPTION_REPORTER_FILTER|DEFAULT_FILE_STORAGE|DEFAULT_FROM_EMAIL|DEFAULT_TABLESPACE|DEFAULT_INDEX_TABLESPACE|DISALLOWED_USER_AGENTS|EMAIL_BACKEND|EMAIL_FILE_PATH|EMAIL_HOST_PASSWORD|EMAIL_HOST_USER|EMAIL_HOST|EMAIL_PORT|EMAIL_SUBJECT_PREFIX|EMAIL_USE_TLS|FILE_CHARSET|FILE_UPLOAD_HANDLERS|FILE_UPLOAD_MAX_MEMORY_SIZE|FILE_UPLOAD_PERMISSIONS|FILE_UPLOAD_TEMP_DIR|FIRST_DAY_OF_WEEK|FIXTURE_DIRS|FORCE_SCRIPT_NAME|FORMAT_MODULE_PATH|IGNORABLE_404_ENDS|IGNORABLE_404_STARTS|IGNORABLE_404_URLS|INSTALLED_APPS|INTERNAL_IPS|JING_PATH|LANGUAGE_CODE|LANGUAGE_COOKIE_NAME|LANGUAGES|LOCALE_PATHS|LOGGING|LOGGING_CONFIG|LOGIN_REDIRECT_URL|LOGIN_URL|LOGOUT_URL|MANAGERS|MEDIA_ROOT|MEDIA_URL|MESSAGE_LEVEL|MESSAGE_STORAGE|MESSAGE_TAGS|MIDDLEWARE_CLASSES|MONTH_DAY_FORMAT|NUMBER_GROUPING|PASSWORD_HASHERS|PASSWORD_RESET_TIMEOUT_DAYS|PREPEND_WWW|PROFANITIES_LIST|RESTRUCTUREDTEXT_FILTER_SETTINGS|ROOT_URLCONF|SECRET_KEY|SECURE_PROXY_SSL_HEADER|SEND_BROKEN_LINK_EMAILS|SERIALIZATION_MODULES|SERVER_EMAIL|SESSION_ENGINE|SESSION_CACHE_ALIAS|SESSION_COOKIE_AGE|SESSION_COOKIE_DOMAIN|SESSION_COOKIE_HTTPONLY|SESSION_COOKIE_NAME|SESSION_COOKIE_PATH|SESSION_COOKIE_SECURE|SESSION_ENGINE|SESSION_EXPIRE_AT_BROWSER_CLOSE|SESSION_FILE_PATH|SESSION_SAVE_EVERY_REQUEST|SHORT_DATE_FORMAT|SHORT_DATETIME_FORMAT|SIGNING_BACKEND|SITE_ID|STATIC_ROOT|STATIC_URL|STATICFILES_DIRS|STATICFILES_FINDERS|STATICFILES_STORAGE|TEMPLATE_CONTEXT_PROCESSORS|TEMPLATE_DEBUG|TEMPLATE_DIRS|TEMPLATE_LOADERS|TEMPLATE_STRING_IF_INVALID|TEST_DATABASE_CHARSET|TEST_DATABASE_COLLATION|TEST_DATABASE_NAME|TEST_RUNNER|THOUSAND_SEPARATOR|TIME_FORMAT|TIME_INPUT_FORMATS|TIME_ZONE|TRANSACTIONS_MANAGED|URL_VALIDATOR_USER_AGENT|USE_ETAGS|USE_I18N|USE_L10N|USE_THOUSAND_SEPARATOR|USE_TZ|USE_X_FORWARDED_HOST|WSGI_APPLICATION|YEAR_MONTH_FORMAT|X_FRAME_OPTIONS)\b</string>
<key>name</key>
<string>variable.other.django.settings</string>
</dict>
<dict>
<key>match</key>
<string>(get_list_or_404|get_object_or_404|load_and_render|loader|render_to_response|render)\b</string>
<key>name</key>
<string>support.function.django.view</string>
</dict>
<dict>
<key>match</key>
<string>[a-z_]+\.get_(object|list|iterator|count|values|values_iterator|in_bulk)\b</string>
<key>name</key>
<string>support.function.django.model</string>
</dict>
<dict>
<key>include</key>
<string>source.python</string>
</dict>
</array>
<key>scopeName</key>
<string>source.python.django</string>
<key>uuid</key>
<string>5326D56C-6F76-4758-8DB7-D818527919AC</string>
</dict>
</plist>
C:\Users\jeffy\AppData\Roaming\Sublime Text 3\Packages\User\syntax_definitions\HTML (Django).tmLanguage
This file is enormous. Here it is as a dpaste.
It turns out a "User" category was automatically created. I just didn't notice it.

Creating sub-groups in XCode 4 Templates

While there is quite a lot of documentation and example for creating templates in XCode 3 converting them to XCode4 Templates is quite a nightmare...
First here is what i've found:
BorealKiss provides a nice tutorial for staters
Cocos2d has some very nice examples to make your templates more "evolved"
But all of them fail to answer this sample question:
How can someone create Folders Insider other Folders ?
For example if you want to have files inside a group you should write:
<key>Definitions</key>
<dict>
<key>File1.h</key>
<dict>
<key>Group</key>
<string>Group1</string>
<key>Path</key>
<string>File1.h</string>
<key>TargetIndices</key>
<array/>
</dict>
<key>File1.m</key>
<dict>
<key>Group</key>
<string>Group1</string>
<key>Path</key>
<string>File1.m</string>
</dict>
</dict>
<key>Nodes</key>
<array>
<string>File1.h</string>
<string>File1.m</string>
</array>
but how would you go for having Group1 inside Group2 for example.
I've tried many many things, playing with ancestors and all but nothing worked.
Any piece of advice or any documentation (I couldn't find any on those XCode templates) would be greatly appreciated.
I've tried many times modify the TemplateInfo.plist and I've also tried to make a sub group and put files in them. Finally I found the solution:
Definition section:
<key>Definitions</key>
<dict>
<key>main.h</key>
<dict>
<key>Path</key>
<string>main.h</string>
<key>Group</key>
<array>
<string>parent</string>
<string>child</string>
</array>
</dict>
</dict>
in the node section:
<key>Nodes</key>
<array>
<string>main.h</string>
</array>
The code above will create groups parent and child. and the main.h is in the child
Project
--parent
---child
----main.h
I've been struggling with this one myself too.
As a workaround I've created and added a folder in my TemplateInfo.plist location (in your case that should be folder named Group1). The folder layout (subfolders and files) are the same as I want them to be in my project source tree ( e.g folder 'Group1' has subfolder 'Group2', folder 'Group2' has files File1.h and File1.m etc).
Then I just add the root folder (Group1) in my TemplateInfo.plist file by defining it in the Definition section and by adding it to the Nodes section like this:
<key>Definitions</key>
<dict>
<key>Group1/</key>
<dict>
<key>Path</key>
<string>Group1/</string>
<key>TargetIndices</key>
<array/>
</dict>
<key>Nodes</key>
<array>
<string>Group1</string>
</array>
For anyone that needs help, this is on Xcode 12.4, this is a project template.
<key>Nodes</key>
<array>
<string>ViewController.swift:comments</string>
<string>ViewController.swift:imports:importCocoa</string>
<string>ViewController.swift:implementation(___FILEBASENAME___: UIViewController)</string>
<string>ViewController.swift:implementation:methods:viewDidLoad(override func viewDidLoad(\))</string>
<string>ViewController.swift:implementation:methods:viewDidLoad:super</string>
<string>Info.plist:UIMainStoryboardFile</string>
<string>Info.plist:UIApplicationSceneManifest:UISceneStoryboardFile</string>
<string>Base.lproj/Main.storyboard</string>
<string>Some/MainCoordinator.swift</string>
<string>Some/Other/TestClass.swift</string>
</array>
<key>Definitions</key>
<dict>
<key>Base.lproj/Main.storyboard</key>
<dict>
<key>Path</key>
<string>Main.storyboard</string>
<key>SortOrder</key>
<integer>98</integer>
</dict>
<key>Info.plist:UIMainStoryboardFile</key>
<string><key>UIMainStoryboardFile</key>
<string>Main</string>
</string>
<key>Some/MainCoordinator.swift</key>
<dict>
<key>Group</key>
<array>
<string>Some</string>
</array>
<key>Path</key>
<string>MainCoordinator.swift</string>
</dict>
<key>Some/Other/TestClass.swift</key>
<dict>
<key>Group</key>
<array>
<string>Some</string>
<string>Other</string>
</array>
<key>Path</key>
<string>TestClass.swift</string>
</dict>
</dict>

OSX Quicklook debugging

I am writing a quicklook plugin for an MPO file.
The plugin isn't that much of a problem, but the problem is trying to debug it. Apples documentation says that to debug you use
qlmanage -r <filename>
And I have. However, none of my breakpoints are matched. I assume this is as it hasn't matched my quicklook plugin with the type. Using mdl (or mdimport) i get a filetype of dyn.ah62d4rv4ge8046dt. Using that I get nothing. I have played around with the info.plist, as I assume that is the problem, and I have looked at other plugins to fix that, but still no breakpoints hit and it is not using my code.
My (important parts of) info.plist currently looks like this:
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>QLGenerator</string>
<key>LSItemContentTypes</key>
<array>
<string>dyn.ah62d4rv4ge8046dt</string>
</array>
</dict>
<dict>
<key>CFBundleTypeRole</key>
<string>QLGenerator</string>
<key>LSItemContentTypes</key>
<array>
<string>public.image.mpo</string>
</array>
</dict>
</array>
...
<key>UTImportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
<string>public.image</string>
</array>
<key>UTTypeDescription</key>
<string>MPO Image file</string>
<key>UTTypeIconFile</key>
<string>MPO</string>
<key>UTTypeIdentifier</key>
<string>public.image.mpo</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>mpo</string>
</array>
</dict>
</dict>
</array>
Is there anything obviously that I am missing here, or any other reason that it is not executing my plugin?
Answering my own question, it will only debug something that is already in the /Library/QuickLook folder.
So now produced and available from here

Problem registering file type through UTIs

I'm using AquaticPrime for license generation in my app, and as the developer guide suggests I'm attempting to register a custom file extension, such that users can simply click on the license and my application will open it and can then verify the license.
To do this, I've added an exported UTI declaration to my Info.plist as follows:
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeDescription</key>
<string>MyApp License File</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.xml</string>
</array>
<key>UTTypeIdentifier</key>
<string>com.mycompany.myapplicense</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>myapplicense</string>
</array>
</dict>
</dict>
</array>
However, when I double-click on a file with that extension it doesn't open in MyApp, and nor does MyApp appear as one of the recommended apps to open the file type with. As well, when viewing the Info panel for the file, the filetype description as specified above doesn't appear.
Can anyone see anything wrong with my UTI declaration, or is there something else that I've missed?
Thanks
You also need a CFBundleDocumentTypes declaration.
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeIconFile</key>
<string>MyAppLicenseIcon</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>NSDocumentClass</key>
<string>MyAppLicenseHandler</string>
<key>LSItemContentTypes</key>
<array>
<string>com.mycompany.myapplicense</string>
</array>
</dict>
</array>
To add to this, in my case I've had to also make sure that I was entering the proper format UTI as such:
<key>UTTypeConformsTo</key>
<array>
<string>public.xml</string>
my file being a simple .plist, it still conforms to xml. You need to make sure you know which UTI format you conform to.

Resources