{"id":24488,"date":"2019-03-04T16:28:56","date_gmt":"2019-03-04T21:28:56","guid":{"rendered":"https:\/\/mjtsai.com\/blog\/?p=24488"},"modified":"2019-03-04T16:28:56","modified_gmt":"2019-03-04T21:28:56","slug":"bringing-ios-apps-to-macos-using-marzipanify","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2019\/03\/04\/bringing-ios-apps-to-macos-using-marzipanify\/","title":{"rendered":"Bringing iOS Apps to macOS Using Marzipanify"},"content":{"rendered":"<p><a href=\"https:\/\/www.highcaffeinecontent.com\/blog\/20190301-Bringing-iOS-Apps-to-macOS-Using-Marzipanify\">Steve Troughton-Smith<\/a>:<\/p>\n<blockquote cite=\"https:\/\/www.highcaffeinecontent.com\/blog\/20190301-Bringing-iOS-Apps-to-macOS-Using-Marzipanify\">\n<p>At WWDC 2018 Apple gave us a &lsquo;sneak peek&rsquo; at perhaps one of the most impactful developments on macOS since the transition to Mac OS X: UIKit apps running on the desktop. Today, I&rsquo;m going to detail a special tool I built, called marzipanify, to get started with UIKit on the Mac early, and start the initial bringup of your iOS app on macOS.<\/p>\n<p>[&#8230;]<\/p>\n<p>There&rsquo;s another reason for the iosmac distinction: many of the frameworks underneath, n&eacute;e iOS Simulator, clash horrendously with the built-in macOS frameworks, thanks to a decade of divergence from OS X. Both iOS and macOS today share a UIFoundation framework to help support UIKit and AppKit and provide common code, but UIFoundation makes decisions at runtime based on which platform it&rsquo;s running on that affect everything from Interface Builder to text rendering. At its simplest level, this means that if you link AppKit into your iOSMac app, all manner of things will explode in your app. The <code>iosmac<\/code> linker variant for iOSMac binaries explicitly prevents loading non-iosmac binaries and libraries into your code (unless they&rsquo;re whitelisted).<\/p>\n<p>[&#8230;]<\/p>\n<p>Altogether, it appears running modern UIKit on macOS is so much more complex than the more-obvious tack <a href=\"http:\/\/chameleonproject.org\">Chameleon<\/a> took when it rewrote UIKit for the Mac all those years ago. It&rsquo;s not a virtual machine by any stretch, despite evolving from the iOS Simulator, but it certainly goes to great lengths to distance itself from how Mac apps traditionally work.<\/p>\n<\/blockquote>\n\n<p><a href=\"https:\/\/www.highcaffeinecontent.com\/blog\/20190302-Making-Marzipan-Apps-Sing\">Steve Troughton-Smith<\/a>:<\/p>\n<blockquote cite=\"https:\/\/www.highcaffeinecontent.com\/blog\/20190302-Making-Marzipan-Apps-Sing\">\n<p>If you look at your newly-marzipanified app, and compare it with Apple&rsquo;s built-in UIKit apps on Mojave, you will notice that yours looks a lot more clunky and less-native than what Apple&rsquo;s doing. To really make your app sing, you&rsquo;re going to have to use some new classes and mechanics unique to UIKit on macOS.<\/p>\n<p>[&#8230;]<\/p>\n<p>One thing that is key to remember is that Marzipan scales everything in your window by 0.77 to better suit the desktop. This is mostly transparent to the developer, unless of course you&rsquo;re trying to closely match the metrics used in AppKit apps for e.g. sidebar row height, and you suddenly realize everything is smaller than it should be.<\/p>\n<p>[&#8230;]<\/p>\n<p>You may find all your centered text is no longer centered when run on the Mac. That&rsquo;s because Apple uses different integer values for the <code>NSTextAlignment<\/code> enum, so <code>NSTextAlignmentCentered<\/code> is interpreted as <code>NSTextAlignmentRight<\/code>.<\/p>\n<\/blockquote>\n\n<p><a href=\"https:\/\/twitter.com\/jamesthomson\/status\/1101509379596132352\">James Thomson<\/a>:<\/p>\n<blockquote cite=\"https:\/\/twitter.com\/jamesthomson\/status\/1101509379596132352\">\n<p>Here&rsquo;s iOS PCalc running under Marzipan on Mojave. Mostly working, with a few graphical glitches - some stuff works even better than the current Mac version, like fullscreen \/ live resizing. Looking forward to seeing what we get officially at WWDC in June.<\/p>\n<\/blockquote>\n\n<p>Previously: <a href=\"https:\/\/mjtsai.com\/blog\/2019\/02\/20\/apple-to-target-combining-iphone-ipad-and-mac-apps-by-2021\/\">Apple to Target Combining iPhone, iPad, and Mac Apps by 2021<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>Steve Troughton-Smith: At WWDC 2018 Apple gave us a &lsquo;sneak peek&rsquo; at perhaps one of the most impactful developments on macOS since the transition to Mac OS X: UIKit apps running on the desktop. Today, I&rsquo;m going to detail a special tool I built, called marzipanify, to get started with UIKit on the Mac early, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"2019-03-04T21:28:59Z","apple_news_api_id":"465e7a51-685f-4883-9286-429090c64ed8","apple_news_api_modified_at":"2019-03-04T21:29:00Z","apple_news_api_revision":"AAAAAAAAAAD\/\/\/\/\/\/\/\/\/\/w==","apple_news_api_share_url":"https:\/\/apple.news\/ARl56UWhfSIOShkKQkMZO2A","apple_news_coverimage":0,"apple_news_coverimage_caption":"","apple_news_is_hidden":false,"apple_news_is_paid":false,"apple_news_is_preview":false,"apple_news_is_sponsored":false,"apple_news_maturity_rating":"","apple_news_metadata":"\"\"","apple_news_pullquote":"","apple_news_pullquote_position":"","apple_news_slug":"","apple_news_sections":"\"\"","apple_news_suppress_video_url":false,"apple_news_use_image_component":false,"footnotes":""},"categories":[4],"tags":[1621,69,31,1610,30,1609,442,71],"class_list":["post-24488","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-marzipan","tag-cocoa","tag-ios","tag-ios-12","tag-mac","tag-macos-10-14","tag-pcalc","tag-programming"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/24488","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/comments?post=24488"}],"version-history":[{"count":1,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/24488\/revisions"}],"predecessor-version":[{"id":24489,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/24488\/revisions\/24489"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=24488"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=24488"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=24488"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}