{"id":2994,"date":"2013-11-30T19:15:31","date_gmt":"2013-11-30T18:15:31","guid":{"rendered":"http:\/\/t-machine.org\/?p=2994"},"modified":"2013-12-24T15:42:02","modified_gmt":"2013-12-24T14:42:02","slug":"apples-dirty-secret-xcode-and-libraries","status":"publish","type":"post","link":"http:\/\/new.t-machine.org\/index.php\/2013\/11\/30\/apples-dirty-secret-xcode-and-libraries\/","title":{"rendered":"Apple&#8217;s dirty secret: Xcode and Libraries"},"content":{"rendered":"<p>This is a post for every iPhone\/iPad developer. Every day, we try to use &#8220;best practices&#8221; when writing code, and building apps.<br \/>\n<!--more--><br \/>\nWe make apps that:<\/p>\n<ul>\n<li>&#8230;fail gracefully (instead of crashing)\n<li>&#8230;re-use code (reducing the number of bugs)\n<li>&#8230;re-use code (increasing the speed of development\/new features\/fixes for old bugs)\n<li>&#8230;we test extensively (using the Simulator to rapidly check and fix bugs before users see them)\n<li>&#8230;we test extensively (purchasing one of every iPhone\/iPad etc to guarantee it works for everyone)\n<li>&#8230;etc\n<\/ul>\n<p>There&#8217;s a lot of great stuff in iOS to help with this. The standard-libraries Apple wrote for iOS 2 \/ iOS 3 are exceptional in quality and design.<\/p>\n<p>And yet &#8230; while Apple&#8217;s library team has bent over backwards to help developers, it feels like the Xcode team sneaks up behind developers and stabs them in the back. They do it in low-level tools and changes that most ObjectiveC programmers don&#8217;t understand or care about. These seem far removed from normal coding. But they influence everything we do &#8211; right up to the recent &#8220;Xcode won&#8217;t allow you to submit your App to the App Store&#8221; bug. These are the silent quality-destroyer that slows down development every day.<\/p>\n<p>Developers suck it down &#8211; Apple provides no channel for acknowledging or reporting on this stuff (even their bug system is locked-down and private). It&#8217;s time to shine some light on Apple&#8217;s shamefully bad tools&#8230;<\/p>\n<h2>Dynamic Libraries<\/h2>\n<p>Apple <strong>does not allow developers to re-use or share their code via dynamic libraries<\/strong> &#8211; most of what you see in code-re-use is due to hacks\u00a0using Static libs that developers have built to workaround Apple.<\/p>\n<p>To be clear: Dynamic libraries have been Best Practice for decades; <strong>even Apple has been telling developers for years to use Dynamic libs across the board<\/strong> (read the OS X documentation).<\/p>\n<p>When iOS came out, no apps were allowed to run &#8220;dynamic&#8221; code. This was a well-intentioned (but perhaps short-sighted) decision that Apple was later forced to reverse. But they kept the (now meaningless) ban on developers using the core language features of dynamic linking.<\/p>\n<p>Thanks to Apple, we can <strong>more easily write virus\/trojan code that sidesteps Apple&#8217;s security checks<\/strong> (by running scripted code, which is now &#8220;allowed&#8221;) than we can <strong>write legitimate code that does not<\/strong> (Apple screens it when you upload to the App Store).<\/p>\n<h2>Workaround1: Static linking of static libraries<\/h2>\n<p>Apple has consistently told developers to use &#8220;Frameworks&#8221;, Apple&#8217;s proprietary system for managing libraries that abstracts the Dynamic\/Static difference. <strong>Frameworks are hugely valuable and speed up development while reducing bugs<\/strong>. I love Frameworks. They visibly reduce the stress of your team &#8211; it&#8217;s hard to exaggerate what a positive difference they can make.<\/p>\n<p>But from day one, <strong>Apple blocked iOS developers<\/strong> from using this feature, and have never allowed us to use it. Anecdotally, the reason given was &#8220;frameworks can (optionally) be Dynamic, and dynamic linking isn&#8217;t allowed&#8221;.<\/p>\n<p><strong>This is (cow)(excrement)<\/strong>. The community <a href=\"https:\/\/github.com\/kstenerud\/iOS-Universal-Framework\">has already proved there is no reason for Apple to ban Frameworks from iOS<\/a>. Instead of a trivial change on Apple&#8217;s side, developers have to jump through hoops and hacks to un-break Xcode.<\/p>\n<h3>&#8230;Corollary: Bundles<\/h3>\n<p>Continuing in this vein, <strong>Apple won&#8217;t allow iOS developers to use Bundles &#8211; which are nothing more than ZIPped folders of ordinary files!<\/strong>. Frameworks made Bundles &#8220;optional&#8221;; without Frameworks, Bundles are <strong>&#8220;required&#8221;<\/strong>, but for the last 3 years, Apple has actively prevented iOS developers from using them.<\/p>\n<p>Again, if you doubt this, you can <a href=\"http:\/\/t-machine.org\/index.php\/2013\/11\/25\/how-to-load-images-from-allany-bundles-in-xcode5\/\">use the commmunity-authored workarounds that work (after you jump through all the hoops)<\/a>. Apple won&#8217;t explain their actions, but again: this appears to show there&#8217;s no reason for Apple to block developers from this feature.<\/p>\n<h2>Workaround2: Dynamic linking of Static Libraries<\/h2>\n<p>25 years ago (this is how behind the curve Apple is!), before dynamic libraries were viable, there was a solution with Static Libraries. The toolchain is supposed to be &#8220;intelligent&#8221; (all of them except Apple&#8217;s) and only link static libs where necessary.<\/p>\n<p>Apple is different; Xcode <strong>cannot detect that 1==1, even when its own tools tell it this is the case<\/strong>. Xcode then <strong>blocks your code from building, for no reason at all<\/strong>, pushing developers through more obscure hoops &#8211; or to just give up, stop re-using code, and instead copy\/paste duplicate it. Causing many, many bugs in the process.<\/p>\n<p><a href=\"http:\/\/binaryfinery.wordpress.com\/2010\/06\/11\/universal-static-library-problem-in-iphone-sdk\/\">Here&#8217;s a post from 2010 where someone figured out the problem and some code Apple could use to fix it<\/a>. This <strong>still has not been fixed<\/strong>. As one commenter put it:<\/p>\n<blockquote><p>\n&#8220;&#8230;I\u2019ve been doing this kind of thing for 29 years, and yet in 2011 Apple cant get linking libraries right? Its a waste of our time.&#8221;\n<\/p><\/blockquote>\n<p>Apple has real problems with this, it&#8217;s no joke &#8211; when the iPhone4s came out, it <strong>broke Apple&#8217;s compilation everywhere for all apps, in the live version of their tools<\/strong>, because of this same bug (combined with another bug, and Apple apparently forgetting to test their own tools). Apple fixed the &#8220;other&#8221; bug, but ignored this one. So we&#8217;re still suffering it, in 2013\/2014&#8230;<\/p>\n<h2>Corollary3: Static combining of static libraries<\/h2>\n<p>Three years ago, Apple <strong>removed the feature of Universal libraries<\/strong>. There was a footnote at the time saying they&#8217;d done this, but offering no explanation.<\/p>\n<p>Since then, Apple seems to have made no effort to bring this back. Even though it&#8217;s needed by every non-trivial project (Of the last 20 projects I&#8217;ve worked on, &#8230; 20 of them have needed this feature). A bunch of iOS developers <a href=\"http:\/\/stackoverflow.com\/questions\/3520977\/build-fat-static-library-device-simulator-using-xcode-and-sdk-4\">wrote scripts you can add to Xcode that re-add this feature<\/a>. This script is used in many apps. It&#8217;s a pain to maintain &#8211; Apple keeps breaking it &#8211; but if we&#8217;re able to make this perfectly-working &#8220;hack&#8221;, why can&#8217;t Apple re-enable the feature? What possible reason is there to hurt developers like this?<\/p>\n<p>My best guess is that the root problems behind the previous bug above (whereby Apple&#8217;s linker is so stupid it can&#8217;t handle multiple architectures, even though it&#8217;s built on a linker that can) are the reason Apple removed this too.<\/p>\n<p>However, <strong>Since the launch of the iPhone4, Apple has been creating Universal libraries on all iOS builds<\/strong>. And it doesn&#8217;t always work &#8211; as noted above, Apple&#8217;s crappy tools keep causing problems here. First on iPhone 4, then 4S\/5. It&#8217;s like they spend 2 years building new hardware, but forget to let the Xcode team test it. WTF?<\/p>\n<p>Of course, if they just fixed Xcode itself, these problems would go away&#8230;<\/p>\n<h2>Conclusion<\/h2>\n<p>This post is a rant. Unashamed, frustrated, (hopefully) coherent. I know Apple won&#8217;t do anything to fix this &#8211; if they cared, they&#8217;ve had <strong>more than 3 years<\/strong> to fix most of the above problems. But it makes ongoing iOS development on medium-to-large projects a never-ending nightmare of shitty, broken tools that repeatedly stab you in the back.<\/p>\n<p>As one friend put it recently:<\/p>\n<blockquote><p>\n&#8220;I had no idea iOS development was so primitive. Apple owns the code, the tools, the hardware, and the OS. I thought it would all work together! But it doesn&#8217;t. Right now, it looks to me like it would be cheaper and faster to use Unity for everything. .Net is a robust and widely-used platform&#8221;\n<\/p><\/blockquote>\n<p>Tragically, he&#8217;s got a good point. It&#8217;s amazing that Apple&#8217;s investment in tools is so dire that a multi-billion-dollar company &#8211; that <strong>has total control of the environment<\/strong> &#8211; can&#8217;t keep up with a tiny, 7-year-old startup that has to <strong>work with every platform, and has no control over anything<\/strong>.<\/p>\n<p>Now, if the Unity guys can just get that forever-promised, never-delivered UnityGUI system delivered &#8230; I may walk away from iOS forever. Except to hit the &#8220;publish for App Store&#8221; button in Unity. That&#8217;s a road that Apple should be terrified of: developers leaving the ecosystem and going cross-platform. Because <strong>once you take that first step out of the walled garden, every step that follows is easier<\/strong>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is a post for every iPhone\/iPad developer. Every day, we try to use &#8220;best practices&#8221; when writing code, and building apps.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[51],"tags":[],"_links":{"self":[{"href":"http:\/\/new.t-machine.org\/index.php\/wp-json\/wp\/v2\/posts\/2994"}],"collection":[{"href":"http:\/\/new.t-machine.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/new.t-machine.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/new.t-machine.org\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/new.t-machine.org\/index.php\/wp-json\/wp\/v2\/comments?post=2994"}],"version-history":[{"count":9,"href":"http:\/\/new.t-machine.org\/index.php\/wp-json\/wp\/v2\/posts\/2994\/revisions"}],"predecessor-version":[{"id":3057,"href":"http:\/\/new.t-machine.org\/index.php\/wp-json\/wp\/v2\/posts\/2994\/revisions\/3057"}],"wp:attachment":[{"href":"http:\/\/new.t-machine.org\/index.php\/wp-json\/wp\/v2\/media?parent=2994"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/new.t-machine.org\/index.php\/wp-json\/wp\/v2\/categories?post=2994"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/new.t-machine.org\/index.php\/wp-json\/wp\/v2\/tags?post=2994"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}