{"id":1181,"date":"2014-12-29T20:01:17","date_gmt":"2014-12-30T02:01:17","guid":{"rendered":"http:\/\/dev.iachieved.it\/iachievedit\/?p=1181"},"modified":"2014-12-29T20:01:17","modified_gmt":"2014-12-30T02:01:17","slug":"build-configuration-management-with-swift","status":"publish","type":"post","link":"https:\/\/dev.iachieved.it\/iachievedit\/build-configuration-management-with-swift\/","title":{"rendered":"Build Configuration Management with Swift"},"content":{"rendered":"<p>You&#8217;ve undoubtedly read that Swift doesn&#8217;t have a preprocessor and may have concluded from that you can no longer use code techniques such as:<\/p>\n<pre>\r\n#ifdef RELEASE_VERSION\r\n#define SERVER_URL \"https:\/\/production-server\/\"\r\n#else\r\n#define SERVER_URL \"https:\/\/staging-server\/\"\r\n#endif\r\n<\/pre>\n<p>You wouldn&#8217;t necessarily be faulted in thinking this, in that <code>#define<\/code> is gone, as well as one my particular favorites <code>#if 0<\/code> (see our post <a href=\"http:\/\/dev.iachieved.it\/iachievedit\/if-0-in-swift\/\">here<\/a> on how to use <code>\/* *\/<\/code> in Swift to comment out large blocks of code, even if they are <i>nested<\/i>).  Nor are there macros in the C preprocessor sense.  There <i>is<\/i> however support for the <code>#if <i>FLAG<\/i><\/code> &#8220;preprocessor&#8221; statement and it can still be used as above with a slight modification.  Let&#8217;s take a look:<\/p>\n<pre>\r\n#if RELEASE_VERSION\r\nlet SERVER_URL = \"https:\/\/production-server\/\"\r\n#else\r\nlet SERVER_URL = \"https:\/\/staging-server\/\"\r\n#endif\r\n<\/pre>\n<p>Notice we just replaced our inner preprocessor <code>#define<\/code> statements with the constant declaration syntax of Swift (i.e., <code>let<\/code>).<\/p>\n<p>To set the <code>RELEASE_VERSION<\/code> flag go to your target&#8217;s <b>Build Settings<\/b> page and search for <b>swift flags<\/b>.  You should see the following filtered out:<\/p>\n<p><a href=\"http:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2014\/12\/tut_swift_build_flags.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2014\/12\/tut_swift_build_flags.png\" alt=\"tut_swift_build_flags\" width=\"897\" height=\"223\" class=\"alignnone size-full wp-image-1187\" \/><\/a><\/p>\n<p>Click on the <b>Other Swift Flags<\/b> line to show the disclosure triangle, and then click on the disclosure triangle to bring down the options for setting flags for either the <b>Debug<\/b> or <b>Release<\/b> build (I&#8217;m assuming here these are your two build configurations, if you&#8217;re an advanced user and managing many different build configurations then you&#8217;ll select the one you want to set flags for).<\/p>\n<p>Click on the build configuration you are interested in and bring up the dialog box for entering individual flags and add each flag one by one using the syntax <code>-D<i>FLAG_NAME<\/i><\/code> with no spaces between any of the characters.  Using underscores is fine, and to be honest I haven&#8217;t tried using &#8220;special characters&#8221; or created emojified (is that a word?) flags.<\/p>\n<p><a href=\"http:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2014\/12\/tut_swift_build_config.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2014\/12\/tut_swift_build_config.png\" alt=\"tut_swift_build_config\" width=\"899\" height=\"463\" class=\"alignnone size-full wp-image-1185\" \/><\/a><\/p>\n<p>Again, this is <i>not<\/i> the same as the C preprocessor, so you can&#8217;t do things like this:  <code>-DRELEASE_VERSION=1<\/code>.  Keep it simple and treat the flags as present or not.  Our above code was combined with a simple <code>println(\"Launching with SERVER_URL as \\(SERVER_URL)\")<\/code> in the <code>didFinishLaunchingWithOptions<\/code> function, and as expected the console printed <code>Launching with SERVER_URL as https:\/\/production-server\/<\/code> when building with the <b>Release<\/b> configuration.<\/p>\n<p><b>Note:<\/b> You&#8217;ll notice that we used the <i>target<\/i> Build Settings page.  You can if you have multiple targets (say, for Apple Watch support), use the <i>project&#8217;s<\/i> Build Settings to apply to all of the targets saving those you explicitly override.<\/p>\n<h3>Summary<\/h3>\n<p>No, there is not a preprocessor Swift, and along with it no support for macros and the like, but basic build configuration flags are supported and one can compile in one set of constants or another using this technique.  I frequently have 4 or 5 different build configurations I work with:<\/p>\n<ul>\n<li>Production Debug (use the production server with debug logs enabled)\n<li>Staging Debug (use the staging server with debug logs enabled)\n<li>Production Release (use the production server with optimization on and debug logs off)\n<li>Staging Release (use the staging server with optimization on and debug logs off)\n<li>No iAd (if I&#8217;m taking screenshots for the AppStore and don&#8217;t want the iAd banner in the way)\n<\/ul>\n<p>All of this can be accomplished by using <code>#if<\/code> and Swift build flags alongside the familiar build configurations and schemas.  <\/p>\n","protected":false},"excerpt":{"rendered":"<p>You&#8217;ve undoubtedly read that Swift doesn&#8217;t have a preprocessor and may have concluded from that you can no longer use code techniques such as: #ifdef RELEASE_VERSION #define SERVER_URL &#8220;https:\/\/production-server\/&#8221; #else #define SERVER_URL &#8220;https:\/\/staging-server\/&#8221; #endif You wouldn&#8217;t necessarily be faulted in thinking this, in that #define is gone, as well as one my particular favorites #if [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,2],"tags":[],"class_list":["post-1181","post","type-post","status-publish","format-standard","hentry","category-swift","category-xcodetips"],"_links":{"self":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/1181"}],"collection":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/comments?post=1181"}],"version-history":[{"count":13,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/1181\/revisions"}],"predecessor-version":[{"id":3240,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/1181\/revisions\/3240"}],"wp:attachment":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/media?parent=1181"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/categories?post=1181"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/tags?post=1181"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}