{"id":37,"date":"2013-02-12T23:17:18","date_gmt":"2013-02-13T05:17:18","guid":{"rendered":"http:\/\/dev.iachieved.it\/iachievedit\/?p=37"},"modified":"2019-12-22T11:09:20","modified_gmt":"2019-12-22T17:09:20","slug":"managing-multiple-schemes-and-build-configurations","status":"publish","type":"post","link":"https:\/\/dev.iachieved.it\/iachievedit\/managing-multiple-schemes-and-build-configurations\/","title":{"rendered":"Managing Multiple Schemes and Build Configurations"},"content":{"rendered":"<p>I will confess, getting a mental grip on XCode schemes and build configurations took a bit of time. In the end I came to use schemes as managing the different types of builds I may want to generate at any given time. For example, the iAchieved.it <a href=\"https:\/\/itunes.apple.com\/us\/app\/lewis-and-clark\/id487502715\">Lewis and Clark app<\/a> has five schemes:<\/p>\n<ul>\n<li><span style=\"line-height: 1.714285714; font-size: 1rem;\">adhoc production build<\/span><\/li>\n<li><span style=\"line-height: 1.714285714; font-size: 1rem;\">adhoc development build<\/span><\/li>\n<li><span style=\"line-height: 1.714285714; font-size: 1rem;\">debug production build<\/span><\/li>\n<li><span style=\"line-height: 1.714285714; font-size: 1rem;\">debug development build<\/span><\/li>\n<li><span style=\"line-height: 1.714285714; font-size: 1rem;\">release<\/span><\/li>\n<\/ul>\n<p>Why all these builds? \u00a0Let&#8217;s break it down.<\/p>\n<p>We have two distinct\u00a0<em>operating environments\u00a0<\/em>in &#8220;the cloud&#8221; (everything is in the cloud these days), one labeled as production and one labeled as development. \u00a0The production environment is carrying &#8220;live&#8221; traffic from our user community, and has specific webservice endpoints that are exposed to our iOS app. \u00a0These endpoints are distinctly different from those that are available in the development environment. \u00a0In fact, the development environment is a separate set of servers and applications, and often the development environment is running the latest development code.<\/p>\n<p>Depending on the context we may want to build Lewis and Clark against the production or development environment. \u00a0Bleeding edge feature development typically happens on the (you guessed it) development servers. \u00a0Features or bug fixes that don&#8217;t require server-side changes are often tested against the existing production servers. \u00a0It is handy to be able to compile for different environments simply by flipping a switch (or in this case, scheme).<\/p>\n<p>But wait, there&#8217;s more! \u00a0Any seasoned software developer knows that you should turn off or minimize excessive logging when ready to ship your application, but often times turning off logging can introduce subtle race conditions that you may have not noticed before. \u00a0Thus, even during the test phase it is beneficial to test with logging both on and off. \u00a0Or, perhaps, you are have been doing testing with the production-level app and your logs have sensitive information in them such as API keys. \u00a0You are getting ready to send the application out to your freelance testers and don&#8217;t necessarily want them to be able to access your log data. \u00a0Rather than changing any code, simply create a scheme that doesn&#8217;t include logging (we call it an adhoc scheme).<\/p>\n<p>As the old saying goes, there are a number of ways to skin a cat, and there are countless ways to organize your schemes and build configurations, and you don&#8217;t have to have a one-to-one relationship between scheme and build, but this is what has worked for us. \u00a0We&#8217;re going to create an application that utilizes the same concepts and also casually toss in some techniques for accessing webservice data.<\/p>\n<p>Our app is going to be called darkskyClient and it&#8217;s going to make use of the JSON API for obtaining storm data through <a href=\"https:\/\/developer.darkskyapp.com\/\">DarkSky<\/a>. \u00a0You&#8217;ll need to register for an API key at\u00a0<a href=\"https:\/\/developer.darkskyapp.com\/register\">https:\/\/developer.darkskyapp.com\/register<\/a>, so go do that now. \u00a0Once you have your API key, go ahead and create a single-view iOS application, and also add the Lumberjack logging framework. \u00a0See\u00a0<a href=\"https:\/\/dev.iachieved.it\/iachievedit\/?p=7\">our blog post on Lumberjack<\/a> for step-by-step details on how to add Lumberjack logging to your project.<\/p>\n<p>Here&#8217;s a power tip when working with XCode projects:  if you already have a project open with files you want to add to your new project, simply create a New Group in the file explorer (left-pane) and then select, drag, and drop the files from one project into your new project, placing them in the new group you&#8217;ve created.  The group is just there to make some sort of logical sense of things.  Here we take the files from our initial Lumberjack project:<\/p>\n<p><a href=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2013\/02\/lumberjackExample_png.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2013\/02\/lumberjackExample_png.png\" alt=\"lumberjackExample_png\" width=\"261\" height=\"459\" class=\"alignnone size-full wp-image-52\" \/><\/a><\/p>\n<p>and drag-and-drop them into our new darkskyClient project (note we created a group called Lumberjack to accept the new files into):<\/p>\n<p><a href=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2013\/02\/darkskyProject_png.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2013\/02\/darkskyProject_png.png\" alt=\"darkskyProject_png\" width=\"258\" height=\"219\" class=\"alignnone size-full wp-image-56\" \/><\/a><\/p>\n<p>making sure to <em>Copy items into destinations group&#8217;s folder<\/em> and <em>Add to targets<\/em>!<\/p>\n<p><a href=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2013\/02\/add_lumberjack_to_project_png.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2013\/02\/add_lumberjack_to_project_png.png\" alt=\"add_lumberjack_to_project_png\" width=\"792\" height=\"198\" class=\"alignnone size-full wp-image-53\" \/><\/a><\/p>\n<p>Now, create a new header file called <code>Logging.h<\/code> and add the following contents, or drag-n-drop Logging.h from the lumberjackExample project.<\/p>\n<p>[objc]<br \/>\n#ifndef lumberjackExample_Logging_h<br \/>\n#define lumberjackExample_Logging_h<\/p>\n<p>#import &quot;DDLog.h&quot;<\/p>\n<p>#define ENTRY_LOG      DDLogVerbose(@&quot;%s ENTRY &quot;, __PRETTY_FUNCTION__);<br \/>\n#define EXIT_LOG       DDLogVerbose(@&quot;%s EXIT &quot;, __PRETTY_FUNCTION__);<br \/>\n#define ERROR_EXIT_LOG DDLogError(@&quot;%s ERROR EXIT&quot;, __PRETTY_FUNCTION__);<\/p>\n<p>#endif<br \/>\n[\/objc]<\/p>\n<p>Create a new header file called <code>Constants.h<\/code>, and then add your API key (obviously below you would have an actual key rather than useless dashes).  We&#8217;ll also add a <code>#define<\/code> to the Interesting Storms API provided by <a href=\"https:\/\/developer.darkskyapp.com\/\">DarkSky<\/a>.<\/p>\n<p>[objc]<br \/>\n#ifndef darkskyClient_Constants_h<br \/>\n#define darkskyClient_Constants_h<\/p>\n<p>#define DARKSKY_API_KEY @&quot;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;&quot;<\/p>\n<p>#define DARKSKY_INTERESTING_STORMS @&quot;https:\/\/api.darkskyapp.com\/v1\/interesting&quot;<\/p>\n<p>#endif<br \/>\n[\/objc]<\/p>\n<p>We&#8217;re going to use the Interesting Storms API call to the DarkSky webservice, and just log the resulting JSON.  Additional tutorials will take up where we will leave off, the intent of this tutorial is to highlight schemes and build configurations.<\/p>\n<p>Go to your <code>AppDelegate.m<\/code> and add the following code after importing <code>AppDelegate.h<\/code> but before the <code>@implementation<\/code>:<\/p>\n<p>[objc]<br \/>\n#import &quot;Constants.h&quot;<br \/>\n#import &quot;Logging.h&quot;<br \/>\n#import &quot;DDTTYLogger.h&quot;<\/p>\n<p>#ifdef DEBUG<br \/>\nstatic const int ddLogLevel = LOG_LEVEL_VERBOSE;<br \/>\n#else<br \/>\nstatic const int ddLogLevel = LOG_LEVEL_ERROR;<br \/>\n#endif<br \/>\n[\/objc]<\/p>\n<p>and then put the following as your <code>application:didFinishLaunchingWithOptions:<\/code> body:<\/p>\n<p>[objc]<br \/>\n&#8211; (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {<\/p>\n<p>  [DDLog addLogger:[DDTTYLogger sharedInstance]];<\/p>\n<p>  ENTRY_LOG;<\/p>\n<p>  NSString* interestingStorms = [NSString stringWithFormat:@&quot;%@\/%@&quot;, DARKSKY_INTERESTING_STORMS, DARKSKY_API_KEY];<\/p>\n<p>  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{<br \/>\n    NSError* error;<\/p>\n<p>    NSString* interestingStormData = [NSString stringWithContentsOfURL:[NSURL URLWithString:interestingStorms]<br \/>\n                                                encoding:NSUTF8StringEncoding<br \/>\n                                                   error:&amp;error];<br \/>\n    DDLogVerbose(@&quot;API returned:  %@&quot;, interestingStormData);<br \/>\n  });<\/p>\n<p>  EXIT_LOG;<br \/>\n  return YES;<br \/>\n}<br \/>\n[\/objc]<\/p>\n<p>If you have never worked with blocks before (the <code>^{ }<\/code> business inside the <code>dispatch_async<\/code> call), don&#8217;t worry, this tutorial doesn&#8217;t require you to understand them (though you will need to understand eventually).<\/p>\n<p>If you now run the application you should see something like:<\/p>\n<pre>\n2013-02-11 22:23:52:014 darkskyClient[3035:c07] -[AppDelegate application:didFinishLaunchingWithOptions:] ENTRY \n2013-02-11 22:23:52:014 darkskyClient[3035:c07] -[AppDelegate application:didFinishLaunchingWithOptions:] EXIT \n2013-02-11 22:23:52:469 darkskyClient[3035:1a03] API returned:  {\"storms\":[{\"intensity\":47.94,\"score\":592.58,\"city\":\"Sharon, GA\",\"longitude\":-82.73,\"latitude\":33.52,\"radarStation\":\"ffc\"},{\"intensity\":40.59,\"score\":526.82,\"city\":\"Ladonia, AL\",\"longitude\":-85.06,\"latitude\":32.4,\"radarStation\":\"jgx\"},{\"intensity\":42.35,\"score\":491.3,\"city\":\"Turbeville, SC\",\"longitude\":-80.01,\"latitude\":33.85,\"radarStation\":\"clx\"},{\"intensity\":57.65,\"score\":428.69,\"city\":\"Petal, \n...\n{\"intensity\":26.47,\"score\":0.19,\"city\":\"Naco, AZ\",\"longitude\":-110.03,\"latitude\":31.34,\"radarStation\":\"emx\"}]}\n<\/pre>\n<p>in your output log.<\/p>\n<p>As a brief aside, notice that the <code>ENTRY<\/code> and <code>EXIT<\/code> logs were both displayed well before the API returned call, even the the code shows the <code>DDLogVerbose<\/code> statement in the middle.  The secret here is in the <code>dispatch_async<\/code> function, which if you are itching to read about, visit Apple&#8217;s <a href=\"https:\/\/developer.apple.com\/library\/ios\/#documentation\/Performance\/Reference\/GCD_libdispatch_Ref\/Reference\/reference.html\">Grand Central Dispatch<\/a> reference for now.<\/p>\n<p>Now, we have an application worthy of adding some schemes and build configurations to!  Let&#8217;s say we are developing our Dark Sky client application and we want to build a version that doesn&#8217;t contain any debug logging in it.  How are our logs even currently displayed in the first place?  Recall that at the top of our <code>AppDelegate.m<\/code> we have:<\/p>\n<p>[objc]<br \/>\n#ifdef DEBUG<br \/>\nstatic const int ddLogLevel = LOG_LEVEL_VERBOSE;<br \/>\n#else<br \/>\nstatic const int ddLogLevel = LOG_LEVEL_ERROR;<br \/>\n#endif<br \/>\n[\/objc]<\/p>\n<p>So, somewhere <code>DEBUG<\/code> is being defined, but where?  It could be defined somewhere in a header file, but in this case it comes included as a part of the <b>Debug<\/b> build configuration that XCode generated when you created the project.  Go to your darkskyClient target and under <b>Build Settings<\/b> search for <code>DEBUG<\/code>.  Notice under <b>Apple LLVM compiler 4.2 &#8211; Preprocessing<\/b> there&#8217;s an entry called <b>Debug<\/b> and next to it <code>DEBUG=1<\/code>.<\/p>\n<p><a href=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2013\/02\/debug_flag_png.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2013\/02\/debug_flag_png.png\" alt=\"debug_flag_png\" width=\"881\" height=\"319\" class=\"alignnone size-full wp-image-39\" \/><\/a><\/p>\n<p><em>This<\/em> is how <code>DEBUG<\/code> is being defined.  But how did XCode decide to use the <b>Debug<\/b> build configuration when you ran your client?  <em>That&#8217;s<\/em> determined by the <b>scheme<\/b> you are currently using in XCode.<\/p>\n<p><a href=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2013\/02\/scheme_png.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2013\/02\/scheme_png.png\" alt=\"scheme_png\" width=\"430\" height=\"72\" class=\"alignnone size-full wp-image-40\" \/><\/a><\/p>\n<p>If you click on the <b>darkskyClient<\/b> text in the scheme menu, you&#8217;ll probably find that it is the only scheme available.  But before we add additional schemes, let&#8217;s look at the default scheme.  Click on the scheme menu again (the scheme menu is the left side of the bar above &#8216;Scheme&#8217;, whereas the right side of the bar is used to select which device or simulator you want to run the application on) and select Edit Scheme.  You should see a dialog box like this:<\/p>\n<p><a href=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2013\/02\/darksky_scheme_png.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2013\/02\/darksky_scheme_png.png\" alt=\"darksky_scheme_png\" width=\"702\" height=\"433\" class=\"alignnone size-full wp-image-41\" \/><\/a><\/p>\n<p>Now, it might start to make a little sense!  Notice the list of actions can perform:  Build, Run, Test, Profile, Analyze, Archive.  And notice that under each of these tags is a build configuration:  Debug or Release.  Here&#8217;s what this is saying:  if you are using the <b>darkskyClient<\/b> scheme, and you select the <b>Run<\/b> action, it is going to use the <b>Debug<\/b> build configuration.  Period.  Now, of course you can <em>change<\/em> the build configuration for the <b>Run<\/b> action.  But why would you want to do that when you can manage everything easily through schemes?<\/p>\n<p>What we would like is two initial schemes:  one for building a debug client and one for build a non-debug client.  While one can argue the term for &#8220;non-debug&#8221; should not be simply &#8220;adhoc&#8221; it turns out that we release adhoc builds to our test community with debugging explicitly turned off.  So in this example you are going to see two initial build configurations:<\/p>\n<ul>\n<li>adhoc\n<li>debug\n<\/ul>\n<p>We are also going to name the schemes &#8220;production&#8221; to differentiate from the fact that we may have two additional types of builds:  adhoc development and debug development.<\/p>\n<p>Let&#8217;s change the default scheme first (<b>darskyClient<\/b>) and turn it into a <b>DebugProduction<\/b> scheme.  Go to scheme menu and select Manage Schemes&#8230; and click on the darkskyClient name and it should highlight so you can edit it.  Change it to DebugProduction.<\/p>\n<p><a href=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2013\/02\/name_debugproduction_png.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2013\/02\/name_debugproduction_png.png\" alt=\"name_debugproduction_png\" width=\"710\" height=\"144\" class=\"alignnone size-full wp-image-57\" \/><\/a><\/p>\n<p>Click OK and now notice that your scheme menu has changed:<\/p>\n<p><a href=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2013\/02\/debugproduction_scheme_png.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2013\/02\/debugproduction_scheme_png.png\" alt=\"debugproduction_scheme_png\" width=\"340\" height=\"75\" class=\"alignnone size-full wp-image-48\" \/><\/a><\/p>\n<p>Currently our <b>DebugProduction<\/b> scheme needs no further changes, but now let&#8217;s create our <b>AdhocProduction<\/b> scheme.  Go back to the scheme menu and select Manage Schemes, but this time go down to the gear wheel and select Duplicate Scheme.  Name the new scheme <b>AdhocProduction<\/b> and change the Build Configuration of the <b>Run<\/b> action from <b>Release<\/b> to <b>Debug<\/b>.  Click OK and then OK again, and now notice you have two schemes:  <b>DebugProduction<\/b> and <b>AdhocProduction<\/b>.<\/p>\n<p>Select the <b>AdhocProduction<\/b> scheme and run your application.  You <em>should<\/em> notice that you no get any log output!  This is exactly what should expect from the way we configured our logging:<\/p>\n<p>[objc]<br \/>\n#ifdef DEBUG<br \/>\nstatic const int ddLogLevel = LOG_LEVEL_VERBOSE;<br \/>\n#else<br \/>\nstatic const int ddLogLevel = LOG_LEVEL_ERROR;<br \/>\n#endif<br \/>\n[\/objc]<\/p>\n<p>as well as the way the <b>Release<\/b> build configuration is set, recall that it does not define <code>DEBUG<\/code>.  Of course, let&#8217;s say in the <b>AdhocProduction<\/b> build you wanted to see at least Info logs.  Simply replace the above with:<\/p>\n<p>[objc]<br \/>\n#ifdef DEBUG<br \/>\nstatic const int ddLogLevel = LOG_LEVEL_VERBOSE;<br \/>\n#else<br \/>\nstatic const int ddLogLevel = LOG_LEVEL_INFO;<br \/>\n#endif<br \/>\n[\/objc]<\/p>\n<p>and then rerun your <b>AdhocProduction<\/b> build.  You should still not see the <code>ENTRY<\/code> and <code>EXIT<\/code> logs, but you will see the interesting storm data JSON (assuming there are interesting storms somewhere!)<\/p>\n<p>Before we leave this topic and blog post altogether, let&#8217;s create another scheme called <b>DebugDevelopment<\/b>.  The purpose of the <b>DebugDevelopment<\/b> scheme is to build our client against, say, a development set of resources.  Let&#8217;s say for arguments sake that the DarkSky service include development servers that it allowed webclients to test against.  Rather than hit <code>https:\/\/api.darkskyapp.com\/v1\/interesting<\/code> you should hit <code>https:\/\/dev-api.darkskyapp.com\/v1\/interesting<\/code>.  Let&#8217;s update our <code>Constants.h<\/code> to:<\/p>\n<p>[objc]<br \/>\n#ifdef DEVELOPMENT_ENVIRONMENT<br \/>\n  #define DARKSKY_INTERESTING_STORMS @&quot;https:\/\/dev-api.darkskyapp.com\/v1\/interesting&quot;<br \/>\n#else<br \/>\n  #define DARKSKY_INTERESTING_STORMS @&quot;https:\/\/api.darkskyapp.com\/v1\/interesting&quot;<br \/>\n#endif<br \/>\n[\/objc]<\/p>\n<p>Now, we want to create a <b>DebugDevelopment<\/b> scheme that makes use of the development environment.  In this case, go back to Manage Schemes and duplicate <b>DebugProduction<\/b> and call it <b>DebugDevelopment<\/b>.  Uh-oh.  We have a problem!  There is only a <b>Debug<\/b> build configuration, so how do we distinguish between the two?  Easy.  Create a new build configuration.  This feature is a little bit more hidden then the rest.  Select on your project file, and then in the project viewer, select on the project file.  A picture is worth a thousand words in this case.<\/p>\n<p><a href=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2013\/02\/add_build_config_png.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2013\/02\/add_build_config_png.png\" alt=\"add_build_config_png\" width=\"963\" height=\"214\" class=\"alignnone size-full wp-image-46\" \/><\/a><\/p>\n<p>Once you find the build configurations (there will be one called <b>Debug<\/b> and one called <b>Release<\/b>), select the plus button for configurations and duplicate the <b>Debug<\/b> configuration and name it <b>DebugDevelopment<\/b>.  Now, we need to set our <code>#define<\/code> that we put in <code>Constants.h<\/code>.  Go over to <b>Build Settings<\/b> tab of the project view and scroll down to the <b>Apple LLVM compiler 4.2 &#8211; Preprocessing<\/b> section, edit the <b>DebugDevelopment<\/b> defines and put <code>DEVELOPMENT_ENVIRONMENT=1<\/code>.<\/p>\n<p><a href=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2013\/02\/debugdevelopment_png.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2013\/02\/debugdevelopment_png.png\" alt=\"debugdevelopment_png\" width=\"714\" height=\"111\" class=\"alignnone size-full wp-image-47\" \/><\/a><\/p>\n<p>Now, that we have <b>DebugDevelopment<\/b> build configuration, go back and update your <b>DebugDevelopment<\/b> scheme to use the <b>DebugDevelopment<\/b> build configuration when running.<\/p>\n<p>You might want to add something like:<\/p>\n<p>[objc]<br \/>\n  DDLogVerbose(@&quot;Using DarkSky API Endpoint:  %@&quot;, interestingStorms);<br \/>\n[\/objc]<\/p>\n<p>prior to the <code>dispatch_async<\/code> routine (which will dispatch the routine to call the webservice).  Doing so and building the <b>DebugDevelopment<\/b> scheme you should see the following log output:<\/p>\n<pre>\n2013-02-12 22:32:28:076 darkskyClient[6096:c07] -[AppDelegate application:didFinishLaunchingWithOptions:] ENTRY \n2013-02-12 22:32:28:076 darkskyClient[6096:c07] Using DarkSky API Endpoint:  https:\/\/beta-api.darkskyapp.com\/v1\/interesting\/beef10967e3754490e3429349540505e\n2013-02-12 22:32:28:076 darkskyClient[6096:c07] -[AppDelegate application:didFinishLaunchingWithOptions:] EXIT \n2013-02-12 22:32:28:106 darkskyClient[6096:1b03] API returned:  (null)\n<\/pre>\n<p>Switch over to the <b>DebugProduction<\/b> scheme and you will see:<\/p>\n<pre>\n2013-02-12 22:35:15:450 darkskyClient[6165:c07] -[AppDelegate application:didFinishLaunchingWithOptions:] ENTRY \n2013-02-12 22:35:15:450 darkskyClient[6165:c07] Using DarkSky API Endpoint:  https:\/\/api.darkskyapp.com\/v1\/interesting\/beef10967e3754490e3429349540505e\n2013-02-12 22:35:15:450 darkskyClient[6165:c07] -[AppDelegate application:didFinishLaunchingWithOptions:] EXIT \n2013-02-12 22:35:16:033 darkskyClient[6165:1b03] API returned:  {\"storms\":[{\"intensity\":44.41,\"score\":838.08,\"city\":\"Snow Hill,\n<\/pre>\n<p>And there you have it, a simple and effective technique for managing debug vs. adhoc builds, production vs. development environments.  Note that there are other mechanisms by which one can toggle back and forth between production and development environments, perhaps include a toggle switch in your app, but then, you would want some mechanism available to compile that switch out.  We&#8217;ve found through our development that maintaining separate schemes for the environments served our purposes well.<\/p>\n<p>A complete example project is available in <a href=\"https:\/\/github.com\/iachievedit\/darkskyClient\">Github<\/a>.   Remember to obtain a DarkSky API key or you will be greeted with<\/p>\n<pre>\n2013-02-16 11:33:31:273 darkskyClient[88340:c07] -[AppDelegate application:didFinishLaunchingWithOptions:] ENTRY \n2013-02-16 11:33:31:273 darkskyClient[88340:c07] ERROR:  You haven't defined a valid DarkSky API Key!\n<\/pre>\n<p>when running the project!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I will confess, getting a mental grip on XCode schemes and build configurations took a bit of time. In the end I came to use schemes as managing the different types of builds I may want to generate at any given time. For example, the iAchieved.it Lewis and Clark app has five schemes: adhoc production [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-37","post","type-post","status-publish","format-standard","hentry","category-xcodetips"],"_links":{"self":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/37"}],"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=37"}],"version-history":[{"count":13,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/37\/revisions"}],"predecessor-version":[{"id":3934,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/37\/revisions\/3934"}],"wp:attachment":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/media?parent=37"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/categories?post=37"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/tags?post=37"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}