I started writing about Xcode templates (for files, projects & core data) in Ulysses.
Ulysses is an amazing app: it works on all Apple devices, it lets me publish directly to Ghost, it has amazing other publishing features, great spell-checker, and many others. But, writing about completely technical concepts and trying to describe their rich relationships felt restrictive in a text editor.
How should I describe inheritance? Should I draw a flow-chart? What about multiple-inheritance and compositions? Should I draw (an utterly complex) spider web?
After a while it felt silly.
If inheritance is what I need, I should express it where it originated from: a programming language. So I’ve switched to Xcode.

I think I’m writing an Xcode template parser, but I’m not sure. I mean it did parse all of the 184 templates (as available in Version 12.2 (12B45b)). It has found:

  • 42 Files templates
  • 126 Project templates
  • 1 Core Data template
  • 15 unknown template kinds

Every template has a mandatory key in it’s root called Kind, and so far I have been familiar with:

  • File template
    – Xcode.IDEFoundation.TextSubstitutionFileTemplateKind
  • Project template
    – Xcode.Xcode3.ProjectTemplateUnitKind
  • Core Data template
    – Xcode.IDECoreDataModeler.ManagedObjectTemplateKind

My 15 unknown templates let me identify six new (to me) template kinds:

  • Refactoring template:
    – Xcode.IDEKit.RefactoringFileTemplateKind.NewSuperclass
  • Test Plan template:
    – Xcode.IDETestPlanEditor.TestPlanTemplateKind
  • SceneKit and SpriteKit templates:
    – Xcode.IDEKit.TextSubstitutionFileTemplateKind
  • SiriKit template:
    – Xcode.IDEIntentBuilderEditor.IntentTemplateKind
  • Playground template:
    – Xcode.IDEFoundation.TextSubstitutionPlaygroundTemplateKind
  • Swift package template:
    – Xcode.IDESwiftPackageSupport.PackageProjectTemplateKind

I have also found one template written using JSON, and not Plist, the SiriKit one:

   {
     "DefaultCompletionName" = Class;
     Description = "An INIntent subclass.";
     Kind = "Xcode.IDEIntentBuilderEditor.IntentTemplateKind";
     AllowedTypes = (
       "public.objective-c-source",
       "public.swift-source",
     );
     Options = ();
     Summary = "An INIntent subclass";
       HiddenFromLibrary = YES;
    }

I’m using Codable to parse the Plist templates, so switching decoders would be easy. I’ll just add JSONDecoder the list. I might first try with PropertyList one first, and if it fails go with the JSON one.

    let templateURLs = getAllTemplateFileURLs()
    for url in templateURLs {
      do {
        let data = try Data(contentsOf: url)
        let template = try PropertyListDecoder().decode(Template.self, from: data)
        
        guard let kind = template.kind?.valueEnum else {
          debugPrint("Error, template has no `kind`, \(template)")
          continue
        }
        
        switch kind {
          case .file:
            let fileTemplate: FileTemplate = try PropertyListDecoder().decode(FileTemplate.self, from: data)
            files.append(fileTemplate)
            result.append(fileTemplate)
          case .project:
            let projectTemplate: ProjectTemplate = try PropertyListDecoder().decode(ProjectTemplate.self, from: data)
            projects.append(projectTemplate)
            result.append(projectTemplate)

The GitHub repo is private for now, for I wanna have something concrete to publish.