Templates and other services to create XCode projects

Introduced classes

class LaunchScreenStoryboardTemplate

nitc :: LaunchScreenStoryboardTemplate

Template for the loading screen to generate LaunchScreen.storyboard
class PbxFile

nitc :: PbxFile

Reference to a file for the PBX format of a project file
class PbxUUIDGenerator

nitc :: PbxUUIDGenerator

Generator of PBX UUIDs
class PbxprojectTemplate

nitc :: PbxprojectTemplate

Template for a PBX project file, usually a project.pbcproj
class PlistTemplate

nitc :: PlistTemplate

Template for a property list used by XCode for iOS projects

Redefined classes

redef class Sys

nitc :: xcode_templates $ Sys

The main class of the program.

All class definitions

class LaunchScreenStoryboardTemplate

nitc $ LaunchScreenStoryboardTemplate

Template for the loading screen to generate LaunchScreen.storyboard
class PbxFile

nitc $ PbxFile

Reference to a file for the PBX format of a project file
class PbxUUIDGenerator

nitc $ PbxUUIDGenerator

Generator of PBX UUIDs
class PbxprojectTemplate

nitc $ PbxprojectTemplate

Template for a PBX project file, usually a project.pbcproj
class PlistTemplate

nitc $ PlistTemplate

Template for a property list used by XCode for iOS projects
redef class Sys

nitc :: xcode_templates $ Sys

The main class of the program.
package_diagram nitc::xcode_templates xcode_templates nitc::abstract_compiler abstract_compiler nitc::xcode_templates->nitc::abstract_compiler nitc\>platform\> platform nitc::abstract_compiler->nitc\>platform\> nitc::mixin mixin nitc::abstract_compiler->nitc::mixin counter counter nitc::abstract_compiler->counter nitc::pkgconfig pkgconfig nitc::abstract_compiler->nitc::pkgconfig ...nitc\>platform\> ... ...nitc\>platform\>->nitc\>platform\> ...nitc::mixin ... ...nitc::mixin->nitc::mixin ...counter ... ...counter->counter ...nitc::pkgconfig ... ...nitc::pkgconfig->nitc::pkgconfig nitc::ios ios nitc::ios->nitc::xcode_templates nitc::compiler compiler nitc::compiler->nitc::ios nitc::compiler... ... nitc::compiler...->nitc::compiler

Ancestors

module abstract_collection

core :: abstract_collection

Abstract collection classes and services.
module abstract_text

core :: abstract_text

Abstract class for manipulation of sequences of characters
module annotation

nitc :: annotation

Management and utilities on annotations
module array

core :: array

This module introduces the standard array structure.
module auto_super_init

nitc :: auto_super_init

Computing of super-constructors that must be implicitly called at the begin of constructors.
module bitset

core :: bitset

Services to handle BitSet
module bytes

core :: bytes

Services for byte streams and arrays
module c

nitc :: c

Support for nesting C code within a Nit program using its FFI
module c_tools

nitc :: c_tools

provides tools to write C .c and .h files
module caching

serialization :: caching

Services for caching serialization engines
module circular_array

core :: circular_array

Efficient data structure to access both end of the sequence.
module codec_base

core :: codec_base

Base for codecs to use with streams
module codecs

core :: codecs

Group module for all codec-related manipulations
module collection

core :: collection

This module define several collection classes.
module console

console :: console

Defines some ANSI Terminal Control Escape Sequences.
module core

core :: core

Standard classes and methods used by default by Nit programs and libraries.
module counter

counter :: counter

Simple numerical statistical analysis and presentation
module csv

csv :: csv

CSV document handling.
module digraph

graph :: digraph

Implementation of directed graphs, also called digraphs.
module engine_tools

serialization :: engine_tools

Advanced services for serialization engines
module environ

core :: environ

Access to the environment variables of the process
module error

core :: error

Standard error-management infrastructure.
module exec

core :: exec

Invocation and management of operating system sub-processes.
module explain_assert_api

nitc :: explain_assert_api

Explain failed assert to the console (service declaration only)
module ffi_base

nitc :: ffi_base

Tools and utilities for implement FFI with different languages
module file

core :: file

File manipulations (create, read, write, etc.)
module fixed_ints

core :: fixed_ints

Basic integers of fixed-precision
module fixed_ints_text

core :: fixed_ints_text

Text services to complement fixed_ints
module flat

core :: flat

All the array-based text representations
module flow

nitc :: flow

Intraprocedural static flow.
module gc

core :: gc

Access to the Nit internal garbage collection mechanism
module hash_collection

core :: hash_collection

Introduce HashMap and HashSet.
module ini

ini :: ini

Read and write INI configuration files
module inspect

serialization :: inspect

Refine Serializable::inspect to show more useful information
module iso8859_1

core :: iso8859_1

Codec for ISO8859-1 I/O
module kernel

core :: kernel

Most basic classes and methods.
module lexer

nitc :: lexer

Lexer and its tokens.
module lexer_work

nitc :: lexer_work

Internal algorithm and data structures for the Nit lexer
module light_c

nitc :: light_c

Support for nesting C code within a Nit program using its FFI
module light_ffi_base

nitc :: light_ffi_base

Tools and utilities for implement FFI with different languages
module list

core :: list

This module handle double linked lists
module literal

nitc :: literal

Parsing of literal values in the abstract syntax tree.
module loader

nitc :: loader

Loading of Nit source files
module local_var_init

nitc :: local_var_init

Verify that local variables are initialized before their usage
module location

nitc :: location

Nit source-file and locations in source-file
module math

core :: math

Mathematical operations
module mdoc

nitc :: mdoc

Documentation of model entities
module meta

meta :: meta

Simple user-defined meta-level to manipulate types of instances as object.
module mixin

nitc :: mixin

Loading and additional module refinements at link-time.
module mmodule

nitc :: mmodule

modules and module hierarchies in the metamodel
module mmodule_data

nitc :: mmodule_data

Define and retrieve data in modules
module model

nitc :: model

Classes, types and properties
module model_base

nitc :: model_base

The abstract concept of model and related common things
module modelbuilder_base

nitc :: modelbuilder_base

Load nit source files and build the associated model
module modelize

nitc :: modelize

Create a model from nit source files
module modelize_class

nitc :: modelize_class

Analysis and verification of class definitions to instantiate model element
module modelize_property

nitc :: modelize_property

Analysis and verification of property definitions to instantiate model element
module more_collections

more_collections :: more_collections

Highly specific, but useful, collections-related classes.
module mpackage

nitc :: mpackage

Modelisation of a Nit package
module native

core :: native

Native structures for text and bytes
module nitni

nitc :: nitni

Native interface related services (used underneath the FFI)
module nitni_base

nitc :: nitni_base

Native interface related services (used underneath the FFI)
module nitni_callbacks

nitc :: nitni_callbacks

nitni services related to callbacks (used underneath the FFI)
module nitpm_shared

nitc :: nitpm_shared

Services related to the Nit package manager
module numeric

core :: numeric

Advanced services for Numeric types
module opts

opts :: opts

Management of options on the command line
module ordered_tree

ordered_tree :: ordered_tree

Manipulation and presentation of ordered trees.
module parser

nitc :: parser

Parser.
module parser_nodes

nitc :: parser_nodes

AST nodes of the Nit language
module parser_prod

nitc :: parser_prod

Production AST nodes full definition.
module parser_util

nitc :: parser_util

Utils and tools related to parsers and AST
module parser_work

nitc :: parser_work

Internal algorithm and data structures for the Nit parser
module phase

nitc :: phase

Phases of the processing of nit programs
module pkgconfig

nitc :: pkgconfig

Offers the PkgconfigPhase to use the external program "pkg-config" in order
module platform

nitc :: platform

Platform system, used to customize the behavior of the compiler.
module poset

poset :: poset

Pre order sets and partial order set (ie hierarchies)
module protocol

core :: protocol

module queue

core :: queue

Queuing data structures and wrappers
module range

core :: range

Module for range of discrete objects.
module rapid_type_analysis

nitc :: rapid_type_analysis

Rapid type analysis on the AST
module re

core :: re

Regular expression support for all services based on Pattern
module ropes

core :: ropes

Tree-based representation of a String.
module scope

nitc :: scope

Identification and scoping of local variables and labels.
module semantize

nitc :: semantize

Process bodies of methods in regard with the model.
module serialization

serialization :: serialization

General serialization services
module serialization_core

serialization :: serialization_core

Abstract services to serialize Nit objects to different formats
module sorter

core :: sorter

This module contains classes used to compare things and sorts arrays.
module stream

core :: stream

Input and output streams of characters
module tables

nitc :: tables

Module that interfaces the parsing tables.
module template

template :: template

Basic template system
module text

core :: text

All the classes and methods related to the manipulation of text entities
module time

core :: time

Management of time and dates
module toolcontext

nitc :: toolcontext

Common command-line tool infrastructure than handle options and error messages
module typing

nitc :: typing

Intraprocedural resolution of static types and OO-services
module union_find

core :: union_find

union–find algorithm using an efficient disjoint-set data structure
module utf8

core :: utf8

Codec for UTF-8 I/O
module version

nitc :: version

This file was generated by git-gen-version.sh

Parents

module abstract_compiler

nitc :: abstract_compiler

Abstract compiler

Children

module ios

nitc :: ios

Compile programs for the iOS platform

Descendants

module a_star-m

a_star-m

module compiler

nitc :: compiler

Compilation to C
module nitc

nitc :: nitc

A Nit compiler
# Templates and other services to create XCode projects
module xcode_templates

import template

import platform
import compiler::abstract_compiler

redef class Sys
	# Map to identify the PBX file type for a given file extension
	private var pbx_file_types: Map[String, String] is lazy do
		var map = new HashMap[String, String]

		# Source code
		map["m"] =			"sourcecode.c.objc"
		map["c"] =			"sourcecode.c.c"
		map["h"] =			"sourcecode.c.h"
		map["cpp"] =		"sourcecode.cpp.cpp"
		map["hpp"] =		"sourcecode.cpp.h"
		map["vsh"] =		"sourcecode.glsl"
		map["fsh"] =		"sourcecode.glsl"

		# Images
		map["png"] =		"image.png"
		map["gif"] =		"image.gif"
		map["jpg"] =		"image.jpeg"
		map["jpeg"] =		"image.jpeg"
		map["pdf"] =		"image.pdf"
		map["ico"] =		"image.ico"

		# Others
		map["app"] =		"wrapper.application"
		map["plist"] =		"text.plist.xml"
		map["storyboard"] =	"file.storyboard"
		map["xib"] =		"file.xib"
		map["xcassets"] =	"folder.assetcatalog"
		map["xctest"] =		"wrapper.cfbundle"

		return map
	end

	# Generator of PBX UUIDs quique to an execution of the compiler
	private var pbx_uuid_generator = new PbxUUIDGenerator is lazy
end

# Generator of PBX UUIDs
#
# PBX UUID are composed of 24 hex characters.
# They only need to be unique within the same project.
#
# This implementation simply counts upward from 0.
class PbxUUIDGenerator
	private var seed = 0

	# Generate a new UUID
	fun next_uuid: String
	do
		seed += 1

		var hex_val = seed.to_hex.to_upper
		return "0"*(24-hex_val.length) + hex_val
	end
end

# Reference to a file for the PBX format of a project file
#
# TODO create subclasses for different file types, this is currently for
# compilable source files only.
class PbxFile

	# Path to `self`
	var path: String

	# Compiler flags for this source file
	var cflags: String = "" is writable

	# UUID for build elements
	private var build_uuid: String = sys.pbx_uuid_generator.next_uuid is lazy

	# File reference UUID
	private var ref_uuid: String = sys.pbx_uuid_generator.next_uuid is lazy

	# Documentation to add besides this file in the template
	private fun doc: String do return path

	# PBX file type for `self`
	fun file_type: String
	do
		var map = sys.pbx_file_types
		var ext = path.file_extension
		if ext != null and map.keys.has(ext) then return map[ext]
		return "unknown"
	end

	# PBX description of this file
	private fun description: Writable
	do
		var extra = ""
		var cflags = cflags
		if not cflags.is_empty then extra = "\nsettings = \{COMPILER_FLAGS = \"{cflags}\"; \};"

		return """
		{{{ref_uuid}}} /* {{{doc}}} */ = {
			isa = PBXFileReference;
			fileEncoding = 4;
			lastKnownFileType = {{{file_type}}};
			path = '{{{path}}}';
			sourceTree = "<group>";{{{extra}}}
			};
"""
	end

	private fun add_to_project(project: PbxprojectTemplate)
	do
		project.source_files.add self
		project.files.add self
	end
end

# Template for a PBX project file, usually a `project.pbcproj`
#
# This file list all information required to build an XCode project.
# It would usually be written and read by XCode.
# From the command line, xcodebuild can read this file but not write it.
#
# Information in the file (simplified list):
#
# * Compilable source files
# * Asset files
# * Build configurations (Release and debug modes, cflags, etc.)
# * List of files composing the project
class PbxprojectTemplate
	super Template

	# Name of the project
	var name: String

	# OTHER_CFLAGS
	var cflags = "" is writable

	# All body/implementation source files to be compiled
	private var source_files = new Array[PbxFile]

	# All asset files added to the app package
	private var asset_files = new Array[PbxFile]

	# All files used by this project
	private var files = new Array[PbxFile]

	# Add `file` to this project
	fun add_file(file: PbxFile) do file.add_to_project(self)

	redef fun rendering
	do
		add """
// !$*UTF8*$!
{
	archiveVersion = 1;
	classes = {
	};
	objectVersion = 46;
	objects = {

/* Begin PBXBuildFile section */
"""

		# List build files (compilable sources and assets) with their reference UUID
		for array in [source_files, asset_files] do for file in array do add """
		{{{file.build_uuid}}} /* {{{file.doc}}} */ = {
			isa = PBXBuildFile;
			fileRef = {{{file.ref_uuid}}} /* {{{file.doc}}} */;
			};
"""

		add """
		0F4688411FDF8748004F34D4 /* assets in Resources */ = {isa = PBXBuildFile; fileRef = 0F4688401FDF8748004F34D4 /* assets */; };
		0FDD07A21C6F8E0E006FF70E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0FDD07A11C6F8E0E006FF70E /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
	/* Static generated files */
		AF9F83CC1A5F0D21004B62C0 /* {{{name}}}.app */ = {
			isa = PBXFileReference;
			explicitFileType = wrapper.application;
			includeInIndex = 0;
			path = {{{name}}}.app;
			sourceTree = BUILT_PRODUCTS_DIR;
			};
		AF9F83D01A5F0D21004B62C0 /* Info.plist */ = {
			isa = PBXFileReference;
			lastKnownFileType = text.plist.xml;
			path = Info.plist;
			sourceTree = "<group>";
			};
		AF9F83DE1A5F0D21004B62C0 /* Base */ = {
			isa = PBXFileReference;
			lastKnownFileType = file.storyboard;
			name = Base;
			path = Base.lproj/Main.storyboard;
			sourceTree = "<group>";
			};
		AF9F83E01A5F0D21004B62C0 /* Images.xcassets */ = {
			isa = PBXFileReference;
			lastKnownFileType = folder.assetcatalog;
			path = Images.xcassets;
			sourceTree = "<group>";
			};
		AF9F83E31A5F0D21004B62C0 /* Base */ = {
			isa = PBXFileReference;
			lastKnownFileType = file.xib;
			name = Base;
			path = Base.lproj/LaunchScreen.xib;
			sourceTree = "<group>";
			};

	/* Changing generated files */
"""
		# Describe all known files
		for file in files do add file.description

		add """
		0F4688401FDF8748004F34D4 /* assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = assets; path = {{{name}}}/assets; sourceTree = SOURCE_ROOT; };
		0FDD07A11C6F8E0E006FF70E /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
		AF9F83C91A5F0D21004B62C0 /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
		AF9F83C31A5F0D21004B62C0 = {
			isa = PBXGroup;
			children = (
				AF9F83CE1A5F0D21004B62C0 /* {{{name}}} */,
				AF9F83CD1A5F0D21004B62C0 /* Products */,
				0FDD07A11C6F8E0E006FF70E /* LaunchScreen.storyboard */,
			);
			sourceTree = "<group>";
		};
		AF9F83CD1A5F0D21004B62C0 /* Products */ = {
			isa = PBXGroup;
			children = (
				AF9F83CC1A5F0D21004B62C0 /* {{{name}}}.app */,
			);
			name = Products;
			sourceTree = "<group>";
		};
		AF9F83CE1A5F0D21004B62C0 /* {{{name}}} */ = {
			isa = PBXGroup;
			children = (
				0F4688401FDF8748004F34D4 /* assets */,
"""
			# Reference all known files
			for file in files do add """
				{{{file.ref_uuid}}} /* {{{file.doc}}} */,
"""

		add """
			);
			path = {{{name}}};
			sourceTree = "<group>";
		};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
		AF9F83CB1A5F0D21004B62C0 /* {{{name}}} */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = AF9F83F31A5F0D21004B62C0 /* Build configuration list for PBXNativeTarget "{{{name}}}" */;
			buildPhases = (
				AF9F83C81A5F0D21004B62C0 /* Sources */,
				AF9F83C91A5F0D21004B62C0 /* Frameworks */,
				AF9F83CA1A5F0D21004B62C0 /* Resources */,
			);
			buildRules = (
			);
			dependencies = (
			);
			name = {{{name}}};
			productName = {{{name}}};
			productReference = AF9F83CC1A5F0D21004B62C0 /* {{{name}}}.app */;
			productType = "com.apple.product-type.application";
		};
/* End PBXNativeTarget section */

/* Begin PBXProject section */
		AF9F83C41A5F0D21004B62C0 /* Project object */ = {
			isa = PBXProject;
			attributes = {
				LastUpgradeCheck = 0610;
				TargetAttributes = {
					AF9F83CB1A5F0D21004B62C0 = {
						CreatedOnToolsVersion = 6.1.1;
					};
				};
			};
			buildConfigurationList = AF9F83C71A5F0D21004B62C0 /* Build configuration list for PBXProject "{{{name}}}" */;
			compatibilityVersion = "Xcode 3.2";
			developmentRegion = English;
			hasScannedForEncodings = 0;
			knownRegions = (
				en,
				Base,
			);
			mainGroup = AF9F83C31A5F0D21004B62C0;
			productRefGroup = AF9F83CD1A5F0D21004B62C0 /* Products */;
			projectDirPath = "";
			projectRoot = "";
			targets = (
				AF9F83CB1A5F0D21004B62C0 /* {{{name}}} */,
			);
		};
/* End PBXProject section */

/* Begin PBXResourcesBuildPhase section */
		AF9F83CA1A5F0D21004B62C0 /* Resources */ = {
			isa = PBXResourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
"""
		# Reference all asset files by their build UUID
		for file in asset_files do add """
				{{{file.build_uuid}}} /* {{{file.doc}}} */,
"""

		add """
				0FDD07A21C6F8E0E006FF70E /* LaunchScreen.storyboard in Resources */,
				0F4688411FDF8748004F34D4 /* assets in Resources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXResourcesBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
		AF9F83C81A5F0D21004B62C0 /* Sources */ = {
			isa = PBXSourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
"""
		# Reference all compilable source files by their build UUID
		for file in source_files do add """
				{{{file.build_uuid}}} /* {{{file.doc}}} */,
"""
		add """
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXSourcesBuildPhase section */

/* Begin XCBuildConfiguration section */
		AF9F83F11A5F0D21004B62C0 /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ALWAYS_SEARCH_USER_PATHS = NO;
				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
				CLANG_CXX_LIBRARY = "libc++";
				CLANG_ENABLE_MODULES = YES;
				CLANG_ENABLE_OBJC_ARC = YES;
				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
				COPY_PHASE_STRIP = NO;
				ENABLE_STRICT_OBJC_MSGSEND = YES;
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_OPTIMIZATION_LEVEL = 0;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"DEBUG=1",
					"$(inherited)",
				);
				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
				GCC_WARN_UNDECLARED_SELECTOR = YES;
				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
				IPHONEOS_DEPLOYMENT_TARGET = 8.1;
				MTL_ENABLE_DEBUG_INFO = YES;
				ONLY_ACTIVE_ARCH = YES;
				SDKROOT = iphoneos;
				TARGETED_DEVICE_FAMILY = "1,2";
			};
			name = Debug;
		};
		AF9F83F21A5F0D21004B62C0 /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ALWAYS_SEARCH_USER_PATHS = NO;
				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
				CLANG_CXX_LIBRARY = "libc++";
				CLANG_ENABLE_MODULES = YES;
				CLANG_ENABLE_OBJC_ARC = YES;
				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
				COPY_PHASE_STRIP = YES;
				ENABLE_NS_ASSERTIONS = NO;
				ENABLE_STRICT_OBJC_MSGSEND = YES;
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
				GCC_WARN_UNDECLARED_SELECTOR = YES;
				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
				IPHONEOS_DEPLOYMENT_TARGET = 8.1;
				MTL_ENABLE_DEBUG_INFO = NO;
				SDKROOT = iphoneos;
				TARGETED_DEVICE_FAMILY = "1,2";
				VALIDATE_PRODUCT = YES;
			};
			name = Release;
		};
		AF9F83F41A5F0D21004B62C0 /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
				INFOPLIST_FILE = {{{name}}}/Info.plist;
				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
				OTHER_CFLAGS = "{{{cflags.escape_to_c}}}";
				PRODUCT_NAME = "$(TARGET_NAME)";
			};
			name = Debug;
		};
		AF9F83F51A5F0D21004B62C0 /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
				INFOPLIST_FILE = {{{name}}}/Info.plist;
				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
				OTHER_CFLAGS = "{{{cflags.escape_to_c}}}";
				PRODUCT_NAME = "$(TARGET_NAME)";
			};
			name = Release;
		};
/* End XCBuildConfiguration section */

/* Begin XCConfigurationList section */
		AF9F83C71A5F0D21004B62C0 /* Build configuration list for PBXProject "{{{name}}}" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				AF9F83F11A5F0D21004B62C0 /* Debug */,
				AF9F83F21A5F0D21004B62C0 /* Release */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Release;
		};
		AF9F83F31A5F0D21004B62C0 /* Build configuration list for PBXNativeTarget "{{{name}}}" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				AF9F83F41A5F0D21004B62C0 /* Debug */,
				AF9F83F51A5F0D21004B62C0 /* Release */,
			);
			defaultConfigurationIsVisible = 0;
		};
/* End XCConfigurationList section */
	};
	rootObject = AF9F83C41A5F0D21004B62C0 /* Project object */;
}
"""
	end
end

# Template for a property list used by XCode for iOS projects
class PlistTemplate
	super Template

	# Value of CFBundleName, pretty name of the application
	var product_name: String

	# Value of CFBundleIdentifier, namespace of the app
	var bundle_identifier: String

	# Value of CFBundleShortVersionString, human readable version
	var short_version: String

	# Value of CFBundleVersion, often a revision number
	var bundle_version: String

	redef fun rendering
	do
		add """
<?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>CFBundleDevelopmentRegion</key>
	<string>en</string>
	<key>CFBundleExecutable</key>
	<string>$(EXECUTABLE_NAME)</string>
	<key>CFBundleIdentifier</key>
	<string>{{{bundle_identifier}}}</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundleName</key>
	<string>{{{product_name}}}</string>
	<key>CFBundlePackageType</key>
	<string>APPL</string>
	<key>CFBundleShortVersionString</key>
	<string>{{{short_version}}}</string>
	<key>CFBundleSignature</key>
	<string>????</string>
	<key>CFBundleVersion</key>
	<string>{{{bundle_version}}}</string>
	<key>LSRequiresIPhoneOS</key>
	<true/>
	<key>UIRequiredDeviceCapabilities</key>
	<array>
		<string>armv7</string>
	</array>
	<key>UISupportedInterfaceOrientations</key>
	<array>
		<string>UIInterfaceOrientationPortrait</string>
		<string>UIInterfaceOrientationLandscapeLeft</string>
		<string>UIInterfaceOrientationLandscapeRight</string>
	</array>
	<key>UISupportedInterfaceOrientations~ipad</key>
	<array>
		<string>UIInterfaceOrientationPortrait</string>
		<string>UIInterfaceOrientationPortraitUpsideDown</string>
		<string>UIInterfaceOrientationLandscapeLeft</string>
		<string>UIInterfaceOrientationLandscapeRight</string>
	</array>

	<key>UILaunchStoryboardName</key>
	<string>LaunchScreen</string>

	<key>NSAppTransportSecurity</key>
	<dict>
		<key>NSAllowsArbitraryLoads</key><true/>
	</dict>
</dict>
</plist>
"""
	end
end

# Template for the loading screen to generate `LaunchScreen.storyboard`
class LaunchScreenStoryboardTemplate
	super Template

	# Large text to show in the center of the loading screen
	var title = "" is writable

	# Text to show at the bottom of the loading screen
	var subtitle = "" is writable

	# TODO make this more customizable by moving the subviews block as an attribute
	# or by allowing to pass a custom file from the ` res/` folder.

	redef fun rendering
	do
		add """
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9531" systemVersion="15D21" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM">
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/>
        <capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
    </dependencies>
    <scenes>
        <!--View Controller-->
        <scene sceneID="EHf-IW-A2E">
            <objects>
                <viewController id="01J-lp-oVM" sceneMemberID="viewController">
                    <layoutGuides>
                        <viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
                        <viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
                    </layoutGuides>
                    <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
                        <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <subviews>
                            <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="{{{subtitle}}}" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="obG-Y5-kRd">
                                <rect key="frame" x="20" y="559" width="560" height="21"/>
                                <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
                                <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
                                <nil key="highlightedColor"/>
                            </label>
                            <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="{{{title}}}" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="GJd-Yh-RWb">
                                <rect key="frame" x="20" y="176" width="560" height="43"/>
                                <fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
                                <color key="textColor" red="0.0" green="0.5" blue="1" alpha="1" colorSpace="calibratedRGB"/>
                                <nil key="highlightedColor"/>
                            </label>
                        </subviews>
                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
                        <constraints>
                            <constraint firstAttribute="centerX" secondItem="obG-Y5-kRd" secondAttribute="centerX" id="5cz-MP-9tL"/>
                            <constraint firstAttribute="centerX" secondItem="GJd-Yh-RWb" secondAttribute="centerX" id="Q3B-4B-g5h"/>
                            <constraint firstItem="obG-Y5-kRd" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leading" constant="20" symbolic="YES" id="SfN-ll-jLj"/>
                            <constraint firstAttribute="bottom" secondItem="obG-Y5-kRd" secondAttribute="bottom" constant="20" id="Y44-ml-fuU"/>
                            <constraint firstItem="GJd-Yh-RWb" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="bottom" multiplier="1/3" constant="1" id="moa-c2-u7t"/>
                            <constraint firstItem="GJd-Yh-RWb" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leading" constant="20" symbolic="YES" id="x7j-FC-K8j"/>
                        </constraints>
                    </view>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="53" y="375"/>
        </scene>
    </scenes>
</document>"""
	end
end
src/platform/xcode_templates.nit:15,1--619,3