<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Apple &#8211; Xojo Programming Blog</title>
	<atom:link href="https://blog.xojo.com/tag/apple/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.xojo.com</link>
	<description>Blog about the Xojo programming language and IDE</description>
	<lastBuildDate>Tue, 16 Dec 2025 22:46:05 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>Tip: Customize Toolbars on macOS apps</title>
		<link>https://blog.xojo.com/2025/12/17/tip-customize-toolbars-on-macos-apps/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Wed, 17 Dec 2025 17:04:00 +0000</pubDate>
				<category><![CDATA[Desktop]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[2025r3]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[macOS 26]]></category>
		<category><![CDATA[Toolbar]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=15727</guid>

					<description><![CDATA[Starting with Xojo 2025r3, macOS apps are built using macOS SDK 26. One benefit of this is that your apps automatically gain access to newer&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Starting with Xojo 2025r3, macOS apps are built using macOS SDK 26. One benefit of this is that your apps automatically gain access to newer native macOS features with little or no extra work. In some cases, these features are available immediately; in others, they can be enabled with a simple Declare. One such example is allowing users to customize an app’s toolbar.</p>



<p>To demonstrate this, we’ll use the Desktop Toolbar example project that ships with Xojo. You can find it in the Examples section of the New Project window. Open this project using the Xojo 2025r3 IDE.</p>



<p>Once the project is open, locate the MainWindow in the Project Browser. Under MainWindow, select the WindowToolbar item and then choose its Opening event. At the top of the Code Editor for this event, add the following lines of code:</p>



<pre class="wp-block-code"><code>Var hdl As Ptr = Me.Handle
If hdl.Integer &lt;> 0 Then
  Declare Sub AllowCustomization Lib "AppKit" Selector "setAllowsUserCustomization:" (hdl As Ptr, value As Boolean)
  AllowCustomization(hdl, True)
End If</code></pre>



<p>It&#8217;s that simple!</p>



<figure class="wp-block-video"><video controls src="https://blog.xojo.com/wp-content/uploads/2025/12/Grabacion-de-pantalla-2025-12-09-a-las-14.13.05.mp4"></video></figure>



<p>Run the app and open the contextual menu by right-clicking (or Control-clicking) on the window’s toolbar. You’ll see a new Customize Toolbar menu item. Select it to open the standard macOS toolbar customization panel, where you can rearrange or remove items as you like. When you click OK, your changes are immediately applied to the current toolbar.</p>



<p>One important caveat: these customizations are not preserved between app launches. This happens because each toolbar must have a unique identifier that macOS uses to save and restore its configuration. Since the example toolbar does not provide one, the OS has nothing to store or retrieve. But… who knows what the future holds?</p>



<p><em>Javier Menendez is an engineer at Xojo and has been using Xojo since 1998. He lives in Castellón</em>, <em>Spain and hosts regular Xojo hangouts en español. Ask Javier questions on Twitter at <a href="https://twitter.com/xojoes" target="_blank" rel="noreferrer noopener">@XojoES</a> or on the <a href="https://forum.xojo.com/u/javier_menendez/summary" target="_blank" rel="noreferrer noopener">Xojo Forum</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		<enclosure url="https://blog.xojo.com/wp-content/uploads/2025/12/Grabacion-de-pantalla-2025-12-09-a-las-14.13.05.mp4" length="512280" type="video/mp4" />

			</item>
		<item>
		<title>Modern and Evolving: macOS and iOS 26 and WinUI in Xojo</title>
		<link>https://blog.xojo.com/2025/12/09/modern-and-evolving-macos-and-ios-26-and-winui-in-xojo/</link>
		
		<dc:creator><![CDATA[Geoff Perlman]]></dc:creator>
		<pubDate>Tue, 09 Dec 2025 16:30:56 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[2025r3]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[macOS 26]]></category>
		<category><![CDATA[macOS Tahoe]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[WinUI]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=15650</guid>

					<description><![CDATA[As the platforms we develop for continue to evolve, so does Xojo. Each year brings new design directions, updated frameworks and refreshed user experience standards&#8230;]]></description>
										<content:encoded><![CDATA[
<p>As the platforms we develop for continue to evolve, so does Xojo. Each year brings new design directions, updated frameworks and refreshed user experience standards across macOS, iOS and Windows. Staying aligned with these changes is essential, not just to keep apps looking modern, but to ensure they feel right at home on every device. In this post, we’ll take a look at how Xojo is adapting to Apple’s latest updates and our ongoing work to bring a modern Windows experience through WinUI.</p>



<h2 class="wp-block-heading">macOS 26 and iOS 26</h2>



<p>Over time, Apple has brought the user experiences of macOS and iOS closer together. macOS 26 and iOS 26, now aligned in version numbers, also share more similarities than ever in their user experience. These updates represent the most significant user experience changes from Apple since iOS was introduced in 2007 and Aqua for macOS seven years earlier. With such a big update, especially when designing elements to work on both large computers displays as well as small smartphone screens, it’s no surprise there’s some tweaking requiring after release. Clearly, Apple is still refining its platforms.</p>



<p>We continue to update Xojo as Apple defines its preferred user experience, ensuring that you can deliver the best possible experience to your users.</p>



<h2 class="wp-block-heading">WinUI</h2>



<p>We are also hard at work upgrading our Windows framework to WinUI, providing a modern user experience for Windows apps. You can see our progress in each release by enabling the Use WinUI (Experimental) option on the Advanced tab in Windows build settings. The “Experimental” label is a reminder that the feature is still evolving, and it will be removed once WinUI is fully ready. Our goal has always been to keep Xojo on a steady path, prepared for whatever challenges lie ahead.</p>



<h2 class="wp-block-heading">Conclusion</h2>



<p>On behalf of the entire Xojo team, I can say that we love what we do and we appreciate your support in allowing us to do it. We are Xojo users ourselves (after all, we make Xojo with Xojo) and we enjoy seeing what you make with it. With that in mind, feel free to tell us about your creations. Send your screenshots, descriptions and your story to hello@xojo.com.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Xojo 2025r2.1: Publishing macOS Apps Under Tahoe</title>
		<link>https://blog.xojo.com/2025/10/14/xojo-2025r2-1-publishing-macos-apps-under-tahoe/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Tue, 14 Oct 2025 21:20:03 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[macOS Tahoe]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=15445</guid>

					<description><![CDATA[macOS 26 is in the wild, and many Xojo users have likely updated their Macs to the latest version. While Xojo 2025r2.1 is compatible and&#8230;]]></description>
										<content:encoded><![CDATA[
<p><a href="https://blog.xojo.com/2025/09/15/xojo-support-for-macos-26-and-ios-26/" target="_blank" rel="noreferrer noopener">macOS 26 is in the wild</a>, and many Xojo users have likely updated their Macs to the latest version. While Xojo 2025r2.1 is compatible and can build apps that run under the latest macOS, the <a href="https://blog.xojo.com/2025/03/25/how-to-publish-macos-and-ios-apps-to-the-app-store-directly-from-xojo/" target="_blank" rel="noreferrer noopener">Publish feature</a> depends on certain tools provided by Xcode. Unfortunately, one of these tools has undergone a significant change in the latest Xcode release, causing the Publish feature to no longer function correctly.</p>



<span id="more-15445"></span>



<p>There are two possible solutions:</p>



<ul class="wp-block-list">
<li><strong>If your Mac still runs under macOS 15.7 Sequoia</strong> (or an earlier macOS version supported by Xojo&#8217;s Publish feature) with Xcode 26 installed,  you can restore Publish feature compatibility by installing Xcode 16.4.x and making that version the active one in your toolchain (especially if you have multiple Xcode versions installed).</li>



<li><strong>If your Mac is running macOS 26.x Tahoe</strong> with Xcode 26 installed, Xojo&#8217;s Publish feature for macOS apps won&#8217;t work as expected, specifically when it attempts to retrieve the AppID from the App Store Connect. The good news is that by the time this error occurs, your app has already been successfully compiled and the .pkg file created. You can use Apple’s <a href="https://www.google.com/url?sa=t&amp;source=web&amp;rct=j&amp;opi=89978449&amp;url=https://apps.apple.com/us/app/transporter/id1450874784%3Fmt%3D12&amp;ved=2ahUKEwiitNb4mo-QAxWphv0HHc48DjQQFnoECBcQAQ&amp;usg=AOvVaw2lhxdNCd0mHUPXUYrhF8U_" target="_blank" rel="noreferrer noopener">Transporter app</a> to complete the final step of uploading the .pkg file to App Store Connect.</li>
</ul>



<p>This issue has been fixed and the solution will be included in Xojo 2025r3. The update also improves how the App ID is retrieved by relying on the available provider listing. This rare issue could affect users whose Apple ID is associated with multiple publishing services, for example, if the same Apple ID is used for both app development and podcast publishing.</p>



<p>Once Xojo 2025r3 is released, the Publish feature will work as before on macOS Sequoia (and previous supported macOS versions), and it will also function properly with the new Xcode 26 toolchain &#8211; whether installed on Sequoia or on the latest macOS 26. Read more about Xojo Support for macOS 26 and iOS 26 on the <a href="https://blog.xojo.com/2025/09/15/xojo-support-for-macos-26-and-ios-26/" target="_blank" rel="noreferrer noopener">Xojo Blog</a>.</p>



<p><em>Javier Menendez is an engineer at Xojo and has been using Xojo since 1998. He lives in Castellón</em>, <em>Spain and hosts regular Xojo hangouts en español. Ask Javier questions on Twitter at <a href="https://twitter.com/xojoes" target="_blank" rel="noreferrer noopener">@XojoES</a> or on the <a href="https://forum.xojo.com/u/javier_menendez/summary" target="_blank" rel="noreferrer noopener">Xojo Forum</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Xojo Support for macOS 26 and iOS 26</title>
		<link>https://blog.xojo.com/2025/09/15/xojo-support-for-macos-26-and-ios-26/</link>
		
		<dc:creator><![CDATA[Geoff Perlman]]></dc:creator>
		<pubDate>Mon, 15 Sep 2025 17:56:25 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Liquid Glass]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=15358</guid>

					<description><![CDATA[Apple is rolling out some of its biggest design changes in years and we want to update you on where Xojo stands. Apple released macOS&#8230;]]></description>
										<content:encoded><![CDATA[
<p><em>Apple is rolling out some of its biggest design changes in years and we want to update you on where Xojo stands.</em></p>



<p>Apple released <strong>macOS 26 and iOS 26</strong> today, the first versions to ship with Apple’s new&nbsp;Liquid Glass&nbsp;look and feel.</p>



<p>The current release of Xojo (2025r2.1) runs smoothly on macOS 26 and can build apps that run on both macOS 26 and iOS 26. However, because 2025r2.1 uses an older version of Apple&#8217;s SDKs, many controls in both the IDE and the apps you build will still use the previous look and feel when running on these new macOS and iOS versions.</p>



<p>We’ve been working throughout Apple’s beta cycle to bring full support for Liquid Glass to Xojo. As you might imagine, Apple made a lot of changes to the OSs along the way — changes that affected things like our layout editor, control sizing, and behavior. Some of these changes were still happening very late in the process. Now that macOS 26 and iOS 26 are officially shipping, we finally know what the end result looks like and how it behaves.</p>



<p>Supporting Liquid Glass and the underlying system changes is a big undertaking and we still have more work to do. Since we build Xojo with Xojo, this means updating not only the Xojo framework but also parts of the IDE itself so it looks and behaves correctly on macOS 26 with Liquid Glass. Our goal is to let you use Liquid Glass in both built-in Xojo controls and third-party party plugins as soon as possible. That&#8217;s why the next release of Xojo, 2025r3, will be built for macOS 26 and iOS 26, giving your apps the latest look and feel while still allowing them to run on older versions of macOS and iOS. This includes projects still using API 1 windows and controls.</p>



<p>Because of the scope of these changes — along with other big, exciting features in the works — the testing cycle for 2025r3 will be longer than usual. As a result, 2025r3 will likely be our last major release of the year, followed by any needed point releases. The good news is that 2025r3 will pack in everything you’d normally see across two releases, plus more. It’s shaping up to be one of the biggest Xojo releases in recent years, with plenty beyond just Liquid Glass to look forward to. Additionally, the updates for 2025r3 aren’t limited to macOS or iOS — there are improvements and new features coming for all platforms, so every Xojo user benefits.</p>



<p>If you have a current license and would like to get early access, we’d love your help testing 2025r3. Just reach out and we’ll be happy to add you to the beta program. We can’t wait to hear your feedback once testing begins!</p>



<p>If you are a long time Xojo user, you know we have been through a <em>lot</em> of big changes like this. Sometimes we get it all done in a single release and sometimes it takes a few to get to 100%. Regardless, our goal is to make the transition for you a smooth one.</p>



<p><em>Geoff Perlman is the Founder and CEO of Xojo. When he’s not leading the Xojo team he can be found playing drums in Austin, Texas and spending time with his family.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>A Guide to Managing Multiple Apple Developer Accounts in Xojo 2025r2</title>
		<link>https://blog.xojo.com/2025/07/08/a-guide-to-managing-multiple-apple-developer-accounts-in-xojo-2025r1/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Tue, 08 Jul 2025 18:01:00 +0000</pubDate>
				<category><![CDATA[Desktop]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[2025r2]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Apple Developer Account]]></category>
		<category><![CDATA[Mac App Store]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=15064</guid>

					<description><![CDATA[Usually, you only need to manage one Apple Developer Account when publishing your macOS or iOS apps. However, as many Xojo users have pointed out,&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Usually, you only need to manage one Apple Developer Account when publishing your macOS or iOS apps. However, as many Xojo users have pointed out, there are situations where you need to work with multiple Apple Developer Accounts &#8211; perhaps you are publishing macOS apps for different companies (with different Team IDs). So, how do you handle this using the App Specific Password setup introduced in Xojo 2025r1?</p>



<span id="more-15064"></span>



<p>The good news is that starting with Xojo 2025r2, you’ll be able to manage multiple Apple Developer Accounts! By default, everything will work just as it did in Xojo 2025r1. That means Xojo uses a global App Specific Password tied to the Apple Developer Account login (usually an email), the Team ID, and the password generated at <a class="" href="http://appleid.apple.com">appleid.apple.com</a>.</p>



<p>So, if you don’t make any changes, everything will continue to work as before for your existing and new macOS projects published to the Mac App Store. But if you need to publish other macOS projects under a different Apple Developer Account or Team ID, you’ll need to create a new App Specific Password at <a class="" href="http://appleid.apple.com">appleid.apple.com</a> (giving it a unique name), enter the new credentials in Xojo’s App Specific Password setup dialog, and then enable the “Save with Project” checkbox.</p>



<figure class="wp-block-image"><img fetchpriority="high" decoding="async" width="1524" height="940" src="https://blog.xojo.com/wp-content/uploads/2025/06/SpecificPasswordSetup.png" alt="" class="wp-image-15065" srcset="https://blog.xojo.com/wp-content/uploads/2025/06/SpecificPasswordSetup.png 1524w, https://blog.xojo.com/wp-content/uploads/2025/06/SpecificPasswordSetup-300x185.png 300w, https://blog.xojo.com/wp-content/uploads/2025/06/SpecificPasswordSetup-1024x632.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/06/SpecificPasswordSetup-768x474.png 768w" sizes="(max-width: 1524px) 100vw, 1524px" /></figure>



<p>When you do this, the App Specific Password will be saved with the project itself, and its settings will be used whenever you click the Publish button.</p>



<p>If you ever need to switch back to using the Global App Specific Password for that project, select the “Global” option from the popup menu at the top of the same dialog.</p>



<p>And of course, don’t forget: if you’re publishing macOS apps using multiple Apple Developer Accounts, make sure all the necessary certificates for those accounts are installed in your Mac Keychain!</p>



<p>Thank you to everyone who provided feedback and suggestions about this feature!</p>



<p><em>Javier Menendez is an engineer at Xojo and has been using Xojo since 1998. He lives in Castellón</em>, <em>Spain and hosts regular Xojo hangouts en español. Ask Javier questions on Twitter at <a href="https://twitter.com/xojoes" target="_blank" rel="noreferrer noopener">@XojoES</a> or on the <a href="https://forum.xojo.com/u/javier_menendez/summary" target="_blank" rel="noreferrer noopener">Xojo Forum</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Property List Editor, Integrated in the IDE</title>
		<link>https://blog.xojo.com/2025/03/25/property-list-editor-integrated-in-the-ide/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Tue, 25 Mar 2025 15:34:12 +0000</pubDate>
				<category><![CDATA[Desktop]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[2025r1]]></category>
		<category><![CDATA[App Store]]></category>
		<category><![CDATA[App Store Connect]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Mac App Store]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=14554</guid>

					<description><![CDATA[Starting with Xojo 2025r1, a new Property List Editor is available for both Desktop (macOS) and iOS projects under Build Settings &#62; macOS and Build&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Starting with Xojo 2025r1, a new Property List Editor is available for both Desktop (macOS) and iOS projects under Build Settings &gt; macOS and Build Settings &gt; iOS. This editor simplifies the process of adding custom entries that your app may require, beyond those automatically included by Xojo.</p>



<span id="more-14554"></span>



<p>Some projects require additional entries in the generated Info.plist file. Previously, the only way to include these entries was to create the file manually using an external text editor, then drag and drop it into the project’s Navigation area. This allowed its contents to be merged with the entries automatically generated by Xojo in the final Info.plist file within the app bundle.</p>



<p>Now, the Property List Editor in the Xojo IDE provides a simpler way to add these entries. Once added, you can even export the contents to an external file, making it easy to reload them later for other projects that require the same set of entries. This saves time by eliminating the need to manually re-enter them.</p>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" width="1424" height="1082" src="https://blog.xojo.com/wp-content/uploads/2025/02/Screenshot-2025-02-26-at-12.18.28 PM.png" alt="" class="wp-image-14555" srcset="https://blog.xojo.com/wp-content/uploads/2025/02/Screenshot-2025-02-26-at-12.18.28 PM.png 1424w, https://blog.xojo.com/wp-content/uploads/2025/02/Screenshot-2025-02-26-at-12.18.28 PM-300x228.png 300w, https://blog.xojo.com/wp-content/uploads/2025/02/Screenshot-2025-02-26-at-12.18.28 PM-1024x778.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/02/Screenshot-2025-02-26-at-12.18.28 PM-768x584.png 768w" sizes="(max-width: 1424px) 100vw, 1424px" /></figure>
</div>


<p>What about projects that already reference an external Info.plist file? No worries—Xojo will automatically merge its contents with the entries added via the Property List Editor. If the same key exists in both the external file and the Property List Editor, the value from the Property List Editor will take precedence, overriding the one in the external file.</p>



<p>As for the types of data that can be added to the Property List Editor, the expected options are offered:</p>



<p><strong>For collections:</strong></p>



<ul class="wp-block-list">
<li>Dictionary</li>



<li>Array</li>
</ul>



<p><strong>For primitive values:</strong></p>



<ul class="wp-block-list">
<li>Number</li>



<li>String</li>



<li>Boolean</li>
</ul>



<p>For primitive value entries, the Editor allows you to convert them to any of the other two supported primitive types. For example, if you add a Number entry, you can later select it and convert it to a String or Boolean type as needed.</p>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" width="1208" height="862" src="https://blog.xojo.com/wp-content/uploads/2025/02/Screenshot-2025-02-18-at-1.00.05 PM.png" alt="" class="wp-image-14556" srcset="https://blog.xojo.com/wp-content/uploads/2025/02/Screenshot-2025-02-18-at-1.00.05 PM.png 1208w, https://blog.xojo.com/wp-content/uploads/2025/02/Screenshot-2025-02-18-at-1.00.05 PM-300x214.png 300w, https://blog.xojo.com/wp-content/uploads/2025/02/Screenshot-2025-02-18-at-1.00.05 PM-1024x731.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/02/Screenshot-2025-02-18-at-1.00.05 PM-768x548.png 768w" sizes="(max-width: 1208px) 100vw, 1208px" /></figure>
</div>


<p>Of course, the entries added through the Property List Editor are applied and saved to the project file in addition to any changes made using the Property List Editor. The next time you open the project in Xojo, you&#8217;ll find the previously applied Info.plist entries already in place.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>Tip:</strong> If you&#8217;re using the new Publish feature to send your macOS apps to App Store Connect, you can simplify Apple&#8217;s encryption compliance process by adding a new Boolean entry in the Property List Editor with the following values:</p>
</blockquote>



<p><strong>Key:</strong> ITSAppUsesNonExemptEncryption<br><strong>Value:</strong> False</p>



<p>By doing this, you won&#8217;t need to manually go through the &#8220;Manage&#8221; option for Apple&#8217;s encryption compliance on the App Store Connect website—provided your app does not actually use encryption that requires disclosure.</p>



<h2 class="wp-block-heading">In Summary</h2>



<p>Whether you&#8217;re developing macOS or iOS projects, the integration of the Property List Editor in the Xojo IDE streamlines the process of managing additional Info.plist entries. You no longer need to manually create and import external files —now, you can add, edit, and reuse entries directly within the IDE. This not only saves time but also ensures consistency across multiple projects!</p>



<p><em>Javier Menendez is an engineer at Xojo and has been using Xojo since 1998. He lives in Castellón</em>, <em>Spain and hosts regular Xojo hangouts en español. Ask Javier questions on Twitter at <a href="https://twitter.com/xojoes" target="_blank" rel="noreferrer noopener">@XojoES</a> or on the <a href="https://forum.xojo.com/u/javier_menendez/summary" target="_blank" rel="noreferrer noopener">Xojo Forum</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to Publish macOS and iOS Apps to the App Store Directly from Xojo</title>
		<link>https://blog.xojo.com/2025/03/25/how-to-publish-macos-and-ios-apps-to-the-app-store-directly-from-xojo/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Tue, 25 Mar 2025 15:34:03 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[2025r1]]></category>
		<category><![CDATA[App Store]]></category>
		<category><![CDATA[App Store Connect]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Distribution]]></category>
		<category><![CDATA[Mac App Store]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=14558</guid>

					<description><![CDATA[Starting with Xojo 2025r1, you can publish macOS and iOS apps to App Store Connect directly from the Xojo IDE. Keep reading to learn how!&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Starting with Xojo 2025r1, you can publish macOS and iOS apps to App Store Connect directly from the Xojo IDE. Keep reading to learn how!</p>



<p><a href="http://Starting with Xojo 2025r1, you can publish macOS and iOS apps to the App Store Connect website directly from the Xojo IDE. Keep reading to learn how!  App Store Connect is where developers create app records as part of the process to make their apps available on the Mac App Store and/or iOS App Store. All apps must go through Apple’s review process for approval. Once an app record exists in App Store Connect, every new app build uploaded from the Xojo IDE will be available there!">App Store Connect</a> is where developers create app records as part of the process to make their apps available on the Mac App Store and/or iOS App Store. All apps must go through Apple’s review process for approval. Once an app record exists in App Store Connect, every new app build uploaded from the Xojo IDE will be available there!</p>



<h2 class="wp-block-heading">First Things, First</h2>



<p>Before exploring how to use Xojo&#8217;s new Publish feature, let&#8217;s review the requirements and previous processes to better understand how it works.</p>



<p>You may have already met these requirements, but it&#8217;s always a good idea to review them.</p>



<ul class="wp-block-list">
<li>A paid Apple Developer membership (approximately US $99/yr).</li>



<li>Xcode installed on your Mac, preferably the latest version (Xcode 16.2 at the time of writing, which requires macOS Sequoia 15.2). However, Xojo also works with Xcode 13 or later, such as on macOS Ventura.</li>



<li>The following certificates are present in your Mac&#8217;s Keychain:
<ul class="wp-block-list">
<li>Developer ID Application</li>



<li>Apple Distribution</li>



<li>3rd Party Mac Developer Installer</li>
</ul>
</li>



<li>An explicit App ID (Identifier) has been created for your app at developer.apple.com.</li>



<li>A Provisioning Profile has been created at developer.apple.com to ensure the uploaded build is available for testing via TestFlight.</li>



<li>No pending agreements are waiting for your approval at both developer.apple.com and appstoreconnect.apple.com.</li>
</ul>



<h2 class="wp-block-heading">Handling Certificates</h2>



<p>The best way to ensure you have the correct certificates installed in your Mac’s Keychain is to manage them directly from Xcode. Open Xcode, go to Preferences &gt; Accounts, and make sure you are signed in with your developer.apple.com credentials.</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1884" height="1328" src="https://blog.xojo.com/wp-content/uploads/2025/02/1-Certificates-A.png" alt="" class="wp-image-14559" srcset="https://blog.xojo.com/wp-content/uploads/2025/02/1-Certificates-A.png 1884w, https://blog.xojo.com/wp-content/uploads/2025/02/1-Certificates-A-300x211.png 300w, https://blog.xojo.com/wp-content/uploads/2025/02/1-Certificates-A-1024x722.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/02/1-Certificates-A-768x541.png 768w, https://blog.xojo.com/wp-content/uploads/2025/02/1-Certificates-A-1536x1083.png 1536w" sizes="auto, (max-width: 1884px) 100vw, 1884px" /></figure>
</div>


<p>Next, click the &#8220;Manage Certificates…&#8221; button. A new window will appear, displaying the installed certificates—including expired ones or those missing a private key. From here, you can also download any missing certificates.</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1884" height="1328" src="https://blog.xojo.com/wp-content/uploads/2025/02/2-Certificates-B.png" alt="" class="wp-image-14560" srcset="https://blog.xojo.com/wp-content/uploads/2025/02/2-Certificates-B.png 1884w, https://blog.xojo.com/wp-content/uploads/2025/02/2-Certificates-B-300x211.png 300w, https://blog.xojo.com/wp-content/uploads/2025/02/2-Certificates-B-1024x722.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/02/2-Certificates-B-768x541.png 768w, https://blog.xojo.com/wp-content/uploads/2025/02/2-Certificates-B-1536x1083.png 1536w" sizes="auto, (max-width: 1884px) 100vw, 1884px" /></figure>
</div>


<p>Once the required certificates are installed on your Mac, I recommend opening the Keychain app to remove any revoked, expired, or incomplete certificates (those missing a private key) to keep your Keychain clean and organized.</p>



<h2 class="wp-block-heading">Handling App ID</h2>



<p>The App ID, Identifier, or &#8216;Bundle Identifier&#8217; is something you should be familiar with whenever you create a new macOS or iOS app in the Xojo IDE.</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1764" height="1334" src="https://blog.xojo.com/wp-content/uploads/2025/02/3-App-Identifier.png" alt="" class="wp-image-14561" srcset="https://blog.xojo.com/wp-content/uploads/2025/02/3-App-Identifier.png 1764w, https://blog.xojo.com/wp-content/uploads/2025/02/3-App-Identifier-300x227.png 300w, https://blog.xojo.com/wp-content/uploads/2025/02/3-App-Identifier-1024x774.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/02/3-App-Identifier-768x581.png 768w, https://blog.xojo.com/wp-content/uploads/2025/02/3-App-Identifier-1536x1162.png 1536w" sizes="auto, (max-width: 1764px) 100vw, 1764px" /></figure>
</div>


<p>You also need to create the same App ID at developer.apple.com. Log in to the Apple Developer portal using your Apple Developer credentials, then click &#8220;Identifiers&#8221; under the &#8220;Certificates, IDs &amp; Profiles&#8221; section.</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="2100" height="1312" src="https://blog.xojo.com/wp-content/uploads/2025/02/5-Identifiers.png" alt="" class="wp-image-14562" srcset="https://blog.xojo.com/wp-content/uploads/2025/02/5-Identifiers.png 2100w, https://blog.xojo.com/wp-content/uploads/2025/02/5-Identifiers-300x187.png 300w, https://blog.xojo.com/wp-content/uploads/2025/02/5-Identifiers-1024x640.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/02/5-Identifiers-768x480.png 768w, https://blog.xojo.com/wp-content/uploads/2025/02/5-Identifiers-1536x960.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/02/5-Identifiers-2048x1280.png 2048w" sizes="auto, (max-width: 2100px) 100vw, 2100px" /></figure>
</div>


<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>Note:</strong> Keep in mind that you must create a new App ID and follow these steps for each macOS or iOS app you want to distribute through the Mac or iOS App Store.</p>
</blockquote>



<ul class="wp-block-list">
<li>On the page displayed after the previous step, click the <strong>&#8220;+&#8221;</strong> button next to the &#8220;Identifiers&#8221; header to register a new Identifier. </li>



<li>On the next page, ensure that &#8220;App IDs&#8221; is selected, then click &#8220;Continue&#8221;. </li>



<li>On the following page, select &#8220;App&#8221;, then click &#8220;Continue&#8221; again.</li>



<li>Now, you’ll reach the most important step—entering the explicit Bundle ID. Make sure it exactly matches the &#8220;Application Identifier&#8221; used when creating the project in the Xojo IDE. </li>



<li>Also, verify that the App ID Prefix matches the Team ID of the certificates installed in your Mac’s Keychain via Xcode.</li>



<li>Select any Capabilities and/or App Services your app requires. (For this example, none are selected.) </li>



<li>Click &#8220;Continue&#8221; to proceed to the summary page, where you can review all the entered details and selected Capabilities/App Services. </li>



<li>If everything looks correct, click &#8220;Register&#8221; to finalize the process.</li>
</ul>



<p>Once registered, the new Identifier will appear in the list under the &#8220;Identifiers&#8221; section.</p>



<h2 class="wp-block-heading">Handling Provisioning Profiles</h2>



<p>TestFlight is an Apple service that allows developers to gather feedback from users and teammates while an app is still in development, before it becomes publicly available on the Mac or iOS App Store. When a new app build (version) is published from the Xojo IDE, it will also become available through TestFlight.</p>



<p>However, for this to work, the app must have a &#8220;Provisioning Profile&#8221; embedded. This profile needs to be created on the &#8220;developer.apple.com&#8221; website, as we did in the previous &#8220;App ID&#8221; section.</p>



<p>There are two main types of provisioning profiles: &#8220;Development&#8221; and &#8220;Distribution.&#8221; The key difference is:</p>



<ul class="wp-block-list">
<li>&#8220;Development&#8221; profiles specify which devices an app can be installed on. They are primarily used for internal testing on user devices or, in the case of iOS apps, for running tests on a physical device using the &#8220;Run On Device&#8221; option in the Xojo IDE.</li>



<li>&#8220;Distribution&#8221; profiles are used for submitting apps to the App Store or making them available for TestFlight testing.</li>
</ul>



<p>In this example, we will focus on creating a &#8220;Distribution Provisioning Profile&#8221; to ensure that apps published from the Xojo IDE are eligible for TestFlight testing.</p>



<ul class="wp-block-list">
<li>Log in to &#8220;developer.apple.com&#8221; and navigate to the &#8220;Certificates, IDs &amp; Profiles&#8221; section.</li>



<li>Select &#8220;Profiles&#8221; and click the &#8220;+&#8221; button next to the &#8220;Profiles&#8221; header.</li>



<li>On the next page, under the &#8220;Distribution&#8221; section, select &#8220;Mac App Store Connect&#8221; if you are creating a profile for a macOS app. For iOS apps, choose &#8220;App Store Connect&#8221; instead. Click &#8220;Continue.&#8221;</li>



<li>Select the &#8220;App ID&#8221; you previously created. Notice that the App ID is prefixed with the &#8220;Team ID&#8221; from when the App ID was created (e.g., &#8220;BW7PU32485&#8221;).</li>



<li>Under &#8220;Profile Type,&#8221; make sure the &#8220;Mac&#8221; option is selected instead of &#8220;Mac Catalyst.&#8221; Click &#8220;Continue.&#8221;</li>



<li>On the next page, select the same &#8220;Distribution&#8221; certificate that will be used when building the Xojo app (i.e., the &#8220;Apple Distribution&#8221; certificate installed on your Mac). Click &#8220;Continue.&#8221;</li>



<li>Give the Provisioning Profile a meaningful name so you can easily distinguish it later from other profiles. Click &#8220;Generate.&#8221;</li>



<li>After a few seconds, the Provisioning Profile summary page will appear with a &#8220;Download&#8221; button. Click it to download the profile.</li>
</ul>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>NOTE:</strong> Provisioning Profiles for iOS<br>For iOS apps, you need to create both &#8220;Development&#8221; and &#8220;Distribution&#8221; provisioning profiles.</p>



<ul class="wp-block-list">
<li>When creating the &#8220;Development&#8221; provisioning profile, be sure to include all registered devices you want to use for installing and testing the app directly from Xojo (using the &#8220;Run On Device&#8221; option in the IDE).</li>



<li>Once these provisioning profiles are downloaded to your Mac, double-click on them to ensure Xcode installs them in the correct location (as of this writing: &#8220;Library &gt; Developer &gt; Xcode &gt; User Data &gt; Provisioning Profiles&#8221;).</li>
</ul>
</blockquote>



<h2 class="wp-block-heading">Adding the Distribution Provision Profile to your Xojo Project</h2>



<p>Move the downloaded macOS Distribution Provisioning Profile to a more convenient location related to your Xojo project, and rename it to &#8220;embedded.provisionprofile&#8221;.</p>



<p>Next, open your Xojo project and add a new &#8220;Copy Files&#8221; step:</p>



<ul class="wp-block-list">
<li>Right-click (or use the contextual menu) and choose &#8220;Add to &#8216;Build Settings&#8217; &gt; Build Step &gt; Copy Files&#8221;.</li>



<li>Select the &#8220;macOS&#8221; item under &#8220;Build Settings.&#8221;</li>
</ul>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1126" height="434" src="https://blog.xojo.com/wp-content/uploads/2025/02/16-CopyFiles.png" alt="" class="wp-image-14563" srcset="https://blog.xojo.com/wp-content/uploads/2025/02/16-CopyFiles.png 1126w, https://blog.xojo.com/wp-content/uploads/2025/02/16-CopyFiles-300x116.png 300w, https://blog.xojo.com/wp-content/uploads/2025/02/16-CopyFiles-1024x395.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/02/16-CopyFiles-768x296.png 768w" sizes="auto, (max-width: 1126px) 100vw, 1126px" /></figure>
</div>


<p>Next, click the &#8220;Add File&#8221; button in the &#8220;Copy Files&#8221; toolbar and select your &#8220;embedded.provisionprofile&#8221; file.</p>



<p>In the associated &#8220;Inspector&#8221; panel, use the following values:</p>



<ul class="wp-block-list">
<li><strong>Name:</strong> Distribution Profile</li>



<li><strong>Applies To:</strong> Release</li>



<li><strong>Architecture:</strong> Any</li>



<li><strong>Destination:</strong> Contents Folder</li>
</ul>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>NOTE:</strong> For Xojo iOS projects, provisioning profiles are applied automatically when building or publishing the app. This happens based on the profiles installed by Xcode when you double-click them after downloading from developer.apple.com.</p>
</blockquote>



<h2 class="wp-block-heading">App Store Connect: Creating the Record for the App</h2>



<p>You need to create an App Record for every macOS or iOS app that will be distributed through the Mac or iOS App Store. To upload an app from the Xojo IDE, it is not necessary to complete every required field in the various sections right away—you can do that at your own pace. However, you must at least have an App Record created for the app.</p>



<p>To do this, log in to &#8220;appstoreconnect.apple.com&#8221; using your developer credentials. Once logged in, select the &#8220;Apps&#8221; icon. On the next page, click the &#8220;+&#8221; button and choose &#8220;New App&#8221; to create a new App Record. The previous action will open a dialog where you need to enter the essential app information required to create the record.</p>



<ul class="wp-block-list">
<li><strong>Platforms:</strong> Select &#8220;macOS.&#8221;</li>



<li><strong>Name:</strong> Enter the same name used in your Xojo project for the app (Build Settings &gt; macOS &gt; Mac App Name). Apple can be strict about this during the app review process if the names differ, as this will also be the name displayed in the App Store listing.</li>



<li><strong>Bundle ID:</strong> Select the App ID you created for the app by following the steps in the &#8220;Handling App ID&#8221; section.</li>



<li><strong>SKU:</strong> Enter any arbitrary SKU value that makes sense to you for uniquely tracking this app.</li>



<li><strong>User Access:</strong> If you are a solo developer, the choice doesn’t make much difference. However, if you are part of a team, selecting &#8220;Limited Access&#8221; allows more control over which team members can access the app.</li>
</ul>



<p>Once you are confident with the information provided, click the &#8220;Create&#8221; button to generate the new app record.</p>



<p>If you receive an error stating that another app has already been registered with the same name, you will need to choose a different name for your app.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>NOTE:</strong> Values such as the App Name and Bundle ID can be changed later, if needed, from the &#8220;General &gt; App Information&#8221; section on the App Record page.</p>
</blockquote>



<p>Once the App Record has been created, there will be a lot of required information to fill in before the app can go through the App Store Review Process and be publicly listed in the Mac/iOS App Store upon approval. However, as mentioned earlier, you can add this information at your own pace. The most important thing right now is that, once the record is created, you have everything set up to start uploading your app builds (versions) from the Xojo IDE.</p>



<h2 class="wp-block-heading">Publishing Mac Apps From Xojo</h2>



<h4 class="wp-block-heading">&nbsp;</h4>



<h4 class="wp-block-heading">General Information</h4>



<p>Open your Xojo project in the IDE and go to Build Settings &gt; macOS. Then, make sure the correct values are set in the associated Inspector Panel for the following fields:</p>



<ul class="wp-block-list">
<li><strong>Mac App Name:</strong> This should match the name entered for the App Record on appstoreconnect.apple.com.</li>



<li><strong>Bundle Identifier:</strong> This should match the App ID created for the app.</li>



<li><strong>Category:</strong> Select the category that best fits your app from the available options.</li>
</ul>



<h4 class="wp-block-heading">App Store Connect Setup</h4>



<p>To allow the IDE to upload the app to App Store Connect, you need an app-specific password. You can add it by clicking the App Store Connect &gt; Setup button. If you have already created this app-specific password in a previous version of Xojo (under Build Settings &gt; Sign &gt; Notarization &gt; Setup), you don&#8217;t need to do it again. Also, keep in mind that this setup only needs to be done once for all your Desktop (macOS) and iOS projects.</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="556" height="774" src="https://blog.xojo.com/wp-content/uploads/2025/02/AppStoreConnectSetup.png" alt="" class="wp-image-14574" srcset="https://blog.xojo.com/wp-content/uploads/2025/02/AppStoreConnectSetup.png 556w, https://blog.xojo.com/wp-content/uploads/2025/02/AppStoreConnectSetup-216x300.png 216w" sizes="auto, (max-width: 556px) 100vw, 556px" /></figure>
</div>


<h4 class="wp-block-heading">Signing and Sandboxing</h4>



<p>Select Build Settings &gt; macOS &gt; Sign in the project browser in order to access the associated Inspector Panel:</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1004" height="638" src="https://blog.xojo.com/wp-content/uploads/2025/02/21-XojoPublish-B.png" alt="" class="wp-image-14570" srcset="https://blog.xojo.com/wp-content/uploads/2025/02/21-XojoPublish-B.png 1004w, https://blog.xojo.com/wp-content/uploads/2025/02/21-XojoPublish-B-300x191.png 300w, https://blog.xojo.com/wp-content/uploads/2025/02/21-XojoPublish-B-768x488.png 768w" sizes="auto, (max-width: 1004px) 100vw, 1004px" /></figure>
</div>


<ul class="wp-block-list">
<li><strong>Developer ID:</strong> Type (or paste) the full string from the Apple Distribution certificate installed on your Mac. In this example, it is: &#8220;Apple Distribution: Francisco Javier Rodriguez Menendez (BW7PU32485)&#8221;. This certificate should match the one selected when the Distribution Provisioning Profile was created, and the Team ID (the value in parentheses) should match the one used when the App ID (Identifier) was created for the app at developer.apple.com.</li>



<li><strong>Sandboxing:</strong> Apps uploaded to App Store Connect require Sandboxing to be enabled. Turn on this option and click the associated &#8220;Edit&#8221; button to enable the necessary sandboxed features for your app. In our example, we only enabled the ability to read/write the selected user files.</li>
</ul>



<h4 class="wp-block-heading">Shared Settings</h4>



<p>Select Build Settings &gt; Shared in the project browser to access the associated Inspector Panel:</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="550" height="634" src="https://blog.xojo.com/wp-content/uploads/2025/02/23-XojoPublish-D.png" alt="" class="wp-image-14564" srcset="https://blog.xojo.com/wp-content/uploads/2025/02/23-XojoPublish-D.png 550w, https://blog.xojo.com/wp-content/uploads/2025/02/23-XojoPublish-D-260x300.png 260w" sizes="auto, (max-width: 550px) 100vw, 550px" /></figure>
</div>


<p>If you are going to publish the final (release) version of your app after it has been thoroughly tested, you will likely want to set the Stage Code value to &#8220;Final.&#8221; Additionally, make sure to enter the short version string in the Version field and the copyright information for the app in the Copyright field.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>NOTE:</strong> Did you forget something? Every time you click the Publish button (or select the equivalent &#8220;Build and Publish to App Store Connect&#8221; menu item from the Project menu), the IDE will run a &#8220;checklist.&#8221; If something needs to be set in the IDE before uploading the app to App Store Connect, any errors will be shown in the IDE&#8217;s Error Panel, pointing out &#8220;what&#8221; needs to be fixed and &#8220;where&#8221; to make the changes.</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="2110" height="472" src="https://blog.xojo.com/wp-content/uploads/2025/02/macOS-Error-Panel.png" alt="" class="wp-image-14565" srcset="https://blog.xojo.com/wp-content/uploads/2025/02/macOS-Error-Panel.png 2110w, https://blog.xojo.com/wp-content/uploads/2025/02/macOS-Error-Panel-300x67.png 300w, https://blog.xojo.com/wp-content/uploads/2025/02/macOS-Error-Panel-1024x229.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/02/macOS-Error-Panel-768x172.png 768w, https://blog.xojo.com/wp-content/uploads/2025/02/macOS-Error-Panel-1536x344.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/02/macOS-Error-Panel-2048x458.png 2048w" sizes="auto, (max-width: 2110px) 100vw, 2110px" /></figure>
</div></blockquote>



<h4 class="wp-block-heading">App Icon</h4>



<p>Nothing new here, apart from building your macOS app for regular or &#8220;web-based&#8221; distribution. Your app needs an icon in the required sizes. However, when it comes to publishing to the Mac/iOS App Store, this requirement is even more strict. Xojo will catch this before starting the app building process to save you time spent on compilation and uploading. So, make sure you add all the required icon sizes by selecting the App item in the project browser, then clicking the Appearance &gt; Icon option in the associated Inspector Panel.</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1162" height="838" src="https://blog.xojo.com/wp-content/uploads/2025/02/24-XojoPublish-E.png" alt="" class="wp-image-14571" srcset="https://blog.xojo.com/wp-content/uploads/2025/02/24-XojoPublish-E.png 1162w, https://blog.xojo.com/wp-content/uploads/2025/02/24-XojoPublish-E-300x216.png 300w, https://blog.xojo.com/wp-content/uploads/2025/02/24-XojoPublish-E-1024x738.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/02/24-XojoPublish-E-768x554.png 768w" sizes="auto, (max-width: 1162px) 100vw, 1162px" /></figure>
</div>


<p>That action will open the Icon Editor, where you can drag and drop the different icon files for each size or paste them directly from your preferred image editor.</p>



<h2 class="wp-block-heading">Publishing!</h2>



<p>Click the Publish button. Once the &#8220;checklist&#8221; passes without any errors, a confirmation dialog will appear. Click the &#8220;OK&#8221; button to begin the process and upload your app&#8217;s new build to App Store Connect.</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="558" height="140" src="https://blog.xojo.com/wp-content/uploads/2025/02/PublishButton.png" alt="" class="wp-image-14566" srcset="https://blog.xojo.com/wp-content/uploads/2025/02/PublishButton.png 558w, https://blog.xojo.com/wp-content/uploads/2025/02/PublishButton-300x75.png 300w" sizes="auto, (max-width: 558px) 100vw, 558px" /></figure>
</div>


<p>If everything goes smoothly, you will see a &#8220;Success&#8221; dialog at the end of the process. However, if there is an error during any of the steps, an error message dialog will provide more details about the issue, and the process will be interrupted, returning you to the IDE.</p>



<p>In either case—whether your new app build was successfully uploaded to App Store Connect or not—you can find the generated Log file in the same folder as the built app. If there are errors, you can open the Log file to review the information about the issue(s), which will help you resolve them before trying again. For example:</p>



<pre class="wp-block-preformatted">2025-01-23 12:54:35.030 *** Error: [ContentDelivery.Uploader.6000028E01C0] The provided entity includes an attribute with a value that has already been used (-19232) The bundle version must be higher than the previously uploaded version: ‘1.0.6’. (ID: d422b9bf-049f-4263-af43-8357c2fe5f00)</pre>



<p>In this case, the Log file entry indicates that we tried to publish a build with the same version number as an already uploaded build on App Store Connect. If this new build includes changes or new features, the way to fix this issue is simply by increasing the version number (and the short version string) before publishing it.</p>



<h2 class="wp-block-heading">Testing with TestFlight</h2>



<p>When you create a new app record in App Store Connect and access it, one of the tabs at the top of the page is named &#8220;TestFlight.&#8221; Click on it, and you will see all the uploaded builds of your app that are eligible for testing.</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="2348" height="1164" src="https://blog.xojo.com/wp-content/uploads/2025/02/25-TestFlight.png" alt="" class="wp-image-14567" srcset="https://blog.xojo.com/wp-content/uploads/2025/02/25-TestFlight.png 2348w, https://blog.xojo.com/wp-content/uploads/2025/02/25-TestFlight-300x149.png 300w, https://blog.xojo.com/wp-content/uploads/2025/02/25-TestFlight-1024x508.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/02/25-TestFlight-768x381.png 768w, https://blog.xojo.com/wp-content/uploads/2025/02/25-TestFlight-1536x761.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/02/25-TestFlight-2048x1015.png 2048w" sizes="auto, (max-width: 2348px) 100vw, 2348px" /></figure>



<p>As you can see, there is a warning icon next to the app build we just uploaded (A). This is because Apple requires additional information from you regarding the app&#8217;s compliance with Encryption Export Regulations. To provide this information, click the associated &#8220;Manage&#8221; link to access the dialog where you can make your choice about it.</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1406" height="964" src="https://blog.xojo.com/wp-content/uploads/2025/02/26-TestFlight-B.png" alt="" class="wp-image-14568" srcset="https://blog.xojo.com/wp-content/uploads/2025/02/26-TestFlight-B.png 1406w, https://blog.xojo.com/wp-content/uploads/2025/02/26-TestFlight-B-300x206.png 300w, https://blog.xojo.com/wp-content/uploads/2025/02/26-TestFlight-B-1024x702.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/02/26-TestFlight-B-768x527.png 768w" sizes="auto, (max-width: 1406px) 100vw, 1406px" /></figure>
</div>


<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>TIP</strong>: Use the new Property List Editor in Xojo’s IDE and add the following Key/Value pair to avoid manually going through the Encryption Export Regulations compliance process:</p>



<ul class="wp-block-list">
<li><strong>Key:</strong> ITSAppUsesNonExemptEncryption</li>



<li><strong>Value:</strong> False</li>
</ul>
</blockquote>



<p>Once the requirement has been completed, the build status will change to &#8220;Ready to Submit.&#8221; As you can see, it also indicates that this build will be available to your testers for the next 90 days before expiring. This should be enough time before you send new test builds to them, anyway.</p>



<p>For each of your apps, you can create as many tester groups as needed. By default, there is only one entry: &#8220;Internal Testing.&#8221; You can create additional groups and add any members of your Apple Development Team to the groups you create. Click on the &#8220;+&#8221; icon to create your first group.</p>



<ul class="wp-block-list">
<li>Give the new group a name and uncheck the &#8220;Enable automatic distribution&#8221; checkbox. Then, click the &#8220;Create&#8221; button.</li>



<li>Once the new internal testing group is created, you will be able to assign any uploaded (and not expired) builds of your app to it. You can also add members to the group (remember, these should be members of your Apple Developer Team!).</li>
</ul>



<p>However, having internal testing groups might not be very helpful if you are a solo developer or part of a small team. The good news is that once you create the first, mandatory internal group, a new option will be added to the TestFlight sidebar.</p>



<h4 class="wp-block-heading">External Testing</h4>



<p>In this case, you will be able to invite up to 10,000 members to test your app. The main difference compared to internal groups is that once you select a build to be tested in any of the external groups, it must go through the Beta App Review process. This means the build won&#8217;t be immediately available to your testers until the review is complete. However, this process is only required for the first build—subsequent builds will be available immediately, just like in internal groups.</p>



<p>When inviting members to an external group, you have several options: you can create and share a public link, manually add testers, or even import them from a .csv file.</p>



<p>In any case, your testers will be able to download, install, and begin testing your app, as well as provide feedback!</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="2024" height="1386" src="https://blog.xojo.com/wp-content/uploads/2025/02/TestFlightInstallApp.png" alt="" class="wp-image-14569" srcset="https://blog.xojo.com/wp-content/uploads/2025/02/TestFlightInstallApp.png 2024w, https://blog.xojo.com/wp-content/uploads/2025/02/TestFlightInstallApp-300x205.png 300w, https://blog.xojo.com/wp-content/uploads/2025/02/TestFlightInstallApp-1024x701.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/02/TestFlightInstallApp-768x526.png 768w, https://blog.xojo.com/wp-content/uploads/2025/02/TestFlightInstallApp-1536x1052.png 1536w" sizes="auto, (max-width: 2024px) 100vw, 2024px" /></figure>



<h2 class="wp-block-heading">In Summary</h2>



<p>The new Publish feature simplifies the process of submitting your macOS and iOS apps to App Store Connect, making them available on the Mac App Store and iOS App Store directly from the IDE, without needing any external apps (such as Transporter).</p>



<p><em>Javier Menendez is an engineer at Xojo and has been using Xojo since 1998. He lives in Castellón</em>, <em>Spain and hosts regular Xojo hangouts en español. Ask Javier questions on Twitter at <a href="https://twitter.com/xojoes" target="_blank" rel="noreferrer noopener">@XojoES</a> or on the <a href="https://forum.xojo.com/u/javier_menendez/summary" target="_blank" rel="noreferrer noopener">Xojo Forum</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>macOS Window Menu</title>
		<link>https://blog.xojo.com/2025/03/25/macos-window-menu/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Tue, 25 Mar 2025 15:32:24 +0000</pubDate>
				<category><![CDATA[Desktop]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[2025r1]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[macOS]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=14672</guid>

					<description><![CDATA[Starting in Xojo 2025r1, all new Desktop projects will include the Window menu by default, as it is a standard feature across most applications. Xojo&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Starting in Xojo 2025r1, all new Desktop projects will include the Window menu by default, as it is a standard feature across most applications. Xojo macOS apps will immediately benefit from this update!</p>



<span id="more-14672"></span>



<p>In previous Xojo releases, the Window menu in macOS-built apps didn&#8217;t quite feel native when run on macOS. This was because newer versions of macOS introduced default options that allowed apps to leverage various features automatically, without requiring developers to write additional code. For example, macOS extended available screens by using the surface of any nearby iPad.</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="2046" height="670" src="https://blog.xojo.com/wp-content/uploads/2025/03/Screenshot-2025-03-11-at-12.09.58 PM.png" alt="" class="wp-image-14673" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/Screenshot-2025-03-11-at-12.09.58 PM.png 2046w, https://blog.xojo.com/wp-content/uploads/2025/03/Screenshot-2025-03-11-at-12.09.58 PM-300x98.png 300w, https://blog.xojo.com/wp-content/uploads/2025/03/Screenshot-2025-03-11-at-12.09.58 PM-1024x335.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/03/Screenshot-2025-03-11-at-12.09.58 PM-768x251.png 768w, https://blog.xojo.com/wp-content/uploads/2025/03/Screenshot-2025-03-11-at-12.09.58 PM-1536x503.png 1536w" sizes="auto, (max-width: 2046px) 100vw, 2046px" /></figure>
</div>


<p>Of course, it was always possible to add these capabilities using Declares (as explained in <a href="https://blog.xojo.com/2024/12/16/macos-add-more-options-to-the-window-menu/">this blog post</a>), but this wasn&#8217;t the ideal solution for developers. It required additional effort and knowledge, making it more cumbersome than having the features available in the framework.</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="2270" height="1646" src="https://blog.xojo.com/wp-content/uploads/2025/03/Screenshot-2025-03-11-at-11.54.31 AM.png" alt="" class="wp-image-14674" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/Screenshot-2025-03-11-at-11.54.31 AM.png 2270w, https://blog.xojo.com/wp-content/uploads/2025/03/Screenshot-2025-03-11-at-11.54.31 AM-300x218.png 300w, https://blog.xojo.com/wp-content/uploads/2025/03/Screenshot-2025-03-11-at-11.54.31 AM-1024x743.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/03/Screenshot-2025-03-11-at-11.54.31 AM-768x557.png 768w, https://blog.xojo.com/wp-content/uploads/2025/03/Screenshot-2025-03-11-at-11.54.31 AM-1536x1114.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/03/Screenshot-2025-03-11-at-11.54.31 AM-2048x1485.png 2048w" sizes="auto, (max-width: 2270px) 100vw, 2270px" /></figure>



<p>Now, with the Window menu item automatically included in your Desktop projects, you don’t need to do anything extra to take advantage of the macOS functionality. Without writing a single line of code, your Xojo-built Mac apps will feel much more native starting with Xojo 2025r1!</p>



<p><em>Javier Menendez is an engineer at Xojo and has been using Xojo since 1998. He lives in Castellón</em>, <em>Spain and hosts regular Xojo hangouts en español. Ask Javier questions on Twitter at <a href="https://twitter.com/xojoes" target="_blank" rel="noreferrer noopener">@XojoES</a> or on the <a href="https://forum.xojo.com/u/javier_menendez/summary" target="_blank" rel="noreferrer noopener">Xojo Forum</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Provisioning Profiles for macOS Apps</title>
		<link>https://blog.xojo.com/2025/01/30/provisioning-profiles-for-macos-apps/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Thu, 30 Jan 2025 15:22:00 +0000</pubDate>
				<category><![CDATA[Learning]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[App Development]]></category>
		<category><![CDATA[App Store]]></category>
		<category><![CDATA[App Store Connect]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Distribution]]></category>
		<category><![CDATA[Mac App Store]]></category>
		<category><![CDATA[Native App Development]]></category>
		<category><![CDATA[Xcode]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=14405</guid>

					<description><![CDATA[Continuing our series on distributing Mac apps, this post will take you through properly setting up a provisioning profile, which is required for your apps&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Continuing our series on distributing Mac apps, this post will take you through properly setting up a <a href="https://developer.apple.com/help/account/manage-profiles/create-a-development-provisioning-profile/" target="_blank" rel="noreferrer noopener">provisioning profile</a>, which is required for your apps to get tested by others in <a href="https://developer.apple.com/testflight/" target="_blank" rel="noreferrer noopener">TestFlight</a>. To review or catch up on earlier steps in this process, see my posts on <a href="https://blog.xojo.com/2024/12/10/sandboxing-hardened-runtime-and-notarization-arrives-to-the-xojo-ide/" target="_blank" rel="noreferrer noopener">Sandboxing, Hardened Runtime and Notarization arrives to the Xojo IDE</a>, <a href="https://blog.xojo.com/2024/08/22/macos-apps-from-sandboxing-to-notarization-the-basics/" target="_blank" rel="noreferrer noopener">macOS Apps: From Sandboxing to Notarization, The Basics</a> and <a href="https://blog.xojo.com/2025/01/14/uploading-macos-builds-to-app-store-connect/" target="_blank" rel="noreferrer noopener">Uploading macOS Builds to App Store Connect</a>. But if you have those steps done, let&#8217;s set up the provisioning profile you need.</p>



<span id="more-14405"></span>



<h2 class="wp-block-heading">Development or Distribution</h2>



<p>There are two types of provisioning profiles: Development and Distribution. Development provisioning profiles are for builds sent to the AppStore Connect service that are not meant to be available on the Mac App Store. Development profiles allow apps to be tested by the eligible users associated with that app in TestFlight. For Development provisioning profiles, set the Stage Code value (under Build Settings &gt; Shared) to &#8220;Development&#8221;, &#8220;Alpha&#8221; or &#8220;Beta&#8221;.</p>



<p>On the other hand, Distribution provisioning profiles for macOS are required for builds meant to be publicly available on the Mac App Store once approved by the <a href="https://developer.apple.com/distribute/app-review/" target="_blank" rel="noreferrer noopener">App Store Reviewing Process</a>, they are also available for TestFlight. For Distribution provisioning profiles, make sure the Stage Code value is set to &#8220;Final&#8221; under Build Settings &gt; Shared.</p>



<h2 class="wp-block-heading">Creating Provisioning Profiles</h2>



<p>Regardless of which type of provisioning profile you are creating, you&#8217;ll need to do it from the Apple Developer website (using  your paid developer membership).</p>



<p>In this example we will create a Distribution provisioning profile.</p>



<ul class="wp-block-list">
<li>Login into the <a href="https://developer.apple.com" target="_blank" rel="noreferrer noopener">Apple Developer Website</a>.</li>



<li>Select the Profiles option found under the &#8220;Certificates, IDs &amp; Profiles&#8221; section.</li>



<li>Click on the &#8220;+&#8221; icon found next to the &#8220;Profiles&#8221; header.</li>



<li>Next, select the &#8220;Mac AppStore Connect&#8221; option under the Distribution section, and click on the &#8220;Continue&#8221; button.</li>
</ul>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="2489" height="1595" src="https://blog.xojo.com/wp-content/uploads/2025/01/1-TypeOfProfile.png" alt="" class="wp-image-14406" srcset="https://blog.xojo.com/wp-content/uploads/2025/01/1-TypeOfProfile.png 2489w, https://blog.xojo.com/wp-content/uploads/2025/01/1-TypeOfProfile-300x192.png 300w, https://blog.xojo.com/wp-content/uploads/2025/01/1-TypeOfProfile-1024x656.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/01/1-TypeOfProfile-768x492.png 768w, https://blog.xojo.com/wp-content/uploads/2025/01/1-TypeOfProfile-1536x984.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/01/1-TypeOfProfile-2048x1312.png 2048w" sizes="auto, (max-width: 2489px) 100vw, 2489px" /></figure>
</div>


<ul class="wp-block-list">
<li>Select the &#8220;Mac&#8221; option under the Profile Type section, and select the App ID value from those available in the associated Popup menu. Make sure that the chosen one (without the value between parentheses) matches the one entered under Build Settings &gt; macOS &gt; Bundle Identifier. Then, click on the &#8220;Continue&#8221; button.</li>
</ul>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="2358" height="731" src="https://blog.xojo.com/wp-content/uploads/2025/01/2-SelectAppID.png" alt="" class="wp-image-14407" srcset="https://blog.xojo.com/wp-content/uploads/2025/01/2-SelectAppID.png 2358w, https://blog.xojo.com/wp-content/uploads/2025/01/2-SelectAppID-300x93.png 300w, https://blog.xojo.com/wp-content/uploads/2025/01/2-SelectAppID-1024x317.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/01/2-SelectAppID-768x238.png 768w, https://blog.xojo.com/wp-content/uploads/2025/01/2-SelectAppID-1536x476.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/01/2-SelectAppID-2048x635.png 2048w" sizes="auto, (max-width: 2358px) 100vw, 2358px" /></figure>
</div>


<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>For example the selected one in the screenshot (that, is BW7PU32485.com.aprendexojo.vcardtoqr), matches the one used as the Bundle Identifier for the app in the Xojo IDE (com.aprendexojo.vcardtoqr).</p>
</blockquote>



<ul class="wp-block-list">
<li>Next, select the &#8220;Distribution&#8221; Certificate to be included in the generated provisioning profile. The one selected must be the same one entered in the Developer ID field when building the App from the Xojo IDE (Build Settings &gt; macOS &gt; Sign). For example, I&#8217;m going to use the value (without the quotes) &#8220;Apple Distribution: Francisco Javier Rodriguez Menendez (BW7PU32485)&#8221; as the Developer ID value in Xojo, so I&#8217;m selecting that same Distribution certificate here. Next, click the &#8220;Continue&#8221; button.</li>
</ul>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="2377" height="564" src="https://blog.xojo.com/wp-content/uploads/2025/01/3-SelectCertificate.png" alt="" class="wp-image-14408" srcset="https://blog.xojo.com/wp-content/uploads/2025/01/3-SelectCertificate.png 2377w, https://blog.xojo.com/wp-content/uploads/2025/01/3-SelectCertificate-300x71.png 300w, https://blog.xojo.com/wp-content/uploads/2025/01/3-SelectCertificate-1024x243.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/01/3-SelectCertificate-768x182.png 768w, https://blog.xojo.com/wp-content/uploads/2025/01/3-SelectCertificate-1536x364.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/01/3-SelectCertificate-2048x486.png 2048w" sizes="auto, (max-width: 2377px) 100vw, 2377px" /></figure>
</div>


<ul class="wp-block-list">
<li>Name the provisioning profile using a significative name, so you can easily distinguish it later among the many available ones. Next, click the &#8220;Generate&#8221; button so the provisioning profile is generated and downloaded to your local Mac disk (probably in the Downloads folder).</li>



<li>The downloaded provisioning profile will have the name you entered in the previous step. Select it and use the Finder options to rename it as &#8220;embedded.provisionprofile&#8221;.</li>
</ul>



<h2 class="wp-block-heading">Adding the Provisioning Profile to the Project</h2>



<p>macOS provisioning profiles need to be added to the Contents folder on the app bundle, and that is easy to do from the Xojo IDE!</p>



<ul class="wp-block-list">
<li>Open your project in the Xojo IDE and add a new Copy Files build step under Build Settings &gt; MacOS.</li>



<li>Add the &#8220;embedded.provisionprofile&#8221; file to the just added CopyFile build step.</li>



<li>Select the &#8220;Contents Folder&#8221; option from the Destination popup menu in the associated Inspector Panel for the Copy Files build step.</li>



<li>Select the &#8220;Release&#8221; option from the &#8220;Applies To&#8221; popup menu in the associated Inspector Panel for the Copy Files build step, so only this file is copied to the Contents folder when the app is built as a standalone app.</li>
</ul>



<h2 class="wp-block-heading">Adding New Entries to the Entitlements File</h2>



<p>In order for the provisioning profile to be recognized by TestFlight when the app package is sent to AppStore Connect, we need to add a couple more entries to the Entitlements file (see &#8220;<a href="https://blog.xojo.com/2025/01/14/uploading-macos-builds-to-app-store-connect/" target="_blank" rel="noreferrer noopener">Uploading macOS Builds to App Store Connect</a>&#8221; for more details on the Entitlements file).</p>



<ul class="wp-block-list">
<li><strong>Full Application Identifier</strong>. Use the &#8220;com.apple.application-identifier&#8221; as the Key for the entry. The value should be the Application Bundle Identifier (in our example com.aprendexojo.vcardtoqr) prefixed with the Team ID value of the Certificate we used both for signing our app and the provisioning profile itself. In this example it is BW7PU32485, making the string value for this key BW7PU32485.com.aprendexojo.vcardtoqr</li>



<li><strong>Team ID</strong>. Use &#8220;com.apple.developer.team-identifier&#8221; as the Key for the entry, while the value (following with our example) is just the Team ID from the certificate: BW7PU32485</li>
</ul>



<p>All in all, the final Entitlements file will look like this:</p>



<pre class="wp-block-code"><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
&lt;plist version="1.0"&gt;
&lt;dict&gt;
	&lt;key&gt;com.apple.security.app-sandbox&lt;/key&gt;
	&lt;true/&gt;
	&lt;key&gt;com.apple.security.files.user-selected.read-write&lt;/key&gt;
	&lt;true/&gt;
	&lt;key&gt;com.apple.application-identifier&lt;/key&gt;
	&lt;string&gt;BW7PU32485.com.aprendexojo.vcardtoqr&lt;/string&gt;
	&lt;key&gt;com.apple.developer.team-identifier&lt;/key&gt;
	&lt;string&gt;BW7PU32485&lt;/string&gt;
&lt;/dict&gt;
&lt;/plist&gt;</code></pre>



<p>That is: Sandboxing enabled, plus the ability for the app to read/write the selected user files, plus the two new entries required so the provisioning profile is recognized by TestFlight when the package is submitted to the AppStore Connect.</p>



<p>Save the changes to the modified Entitlements file (in our example named as &#8220;myEntitlements.entitlements&#8221;).</p>



<h2 class="wp-block-heading">Resign, Re-Package, and Uploading</h2>



<p>If you followed the two previous blog posts in this series, you may have already guessed the next step! Yep, because we modified our &#8220;myEntitlements.entitlements&#8221; file, we need to re-sign the app bundle, package it and submit it to AppStore Connect.</p>



<p>So for re-signing, type the following in a new Terminal window:</p>



<pre class="wp-block-code"><code>codesign --force --timestamp --entitlements path-to-your-myEntitlements.entitlements-file  -s "Apple Distribution: whatever-name-you-use (BZXXXXXXX)" path-to-the-bundle-of-the-compiled-app.app</code></pre>



<p>In order to create a package from the bundle, issue this command from the Terminal:</p>



<pre class="wp-block-code"><code>productbuild --sign "3rd Party Mac Developer Installer: whatever-name-you-use (BZXXXXXXX)"  --component path-to-the-bundle-of-the-compiled-app.app  /Applications path-to-the-generated-package-file.pkg</code></pre>



<p>And in order to upload the package to the AppStore Connect, type the following command in a Terminal window:</p>



<pre class="wp-block-code"><code>xcrun altool  --upload-package path-to-the-package-file.pkg -u your-apple-developer-login-id-goes-here -p "your-app-specific-password-goes-here" --type osx -apple-id "6111111111" --bundle-id "com.yourcomany.yourIdentifier" --bundle-short-version-string "current-short-value" --bundle-version "current-version-value"</code></pre>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1970" height="270" src="https://blog.xojo.com/wp-content/uploads/2025/01/4-AddedToTestFlight.png" alt="" class="wp-image-14410" srcset="https://blog.xojo.com/wp-content/uploads/2025/01/4-AddedToTestFlight.png 1970w, https://blog.xojo.com/wp-content/uploads/2025/01/4-AddedToTestFlight-300x41.png 300w, https://blog.xojo.com/wp-content/uploads/2025/01/4-AddedToTestFlight-1024x140.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/01/4-AddedToTestFlight-768x105.png 768w, https://blog.xojo.com/wp-content/uploads/2025/01/4-AddedToTestFlight-1536x211.png 1536w" sizes="auto, (max-width: 1970px) 100vw, 1970px" /></figure>
</div>


<p>If everything went OK, open your Internet Browser and go to <a href="http://appstoreconnect.apple.com">http://appstoreconnect.apple.com</a>, select your app record from the Apps section and click on the TestFlight tab. You should be able to see the just submitted build ready for testing!</p>



<h2 class="wp-block-heading">In Summary</h2>



<p>As you see, adding provisioning profiles to macOS apps sent to the AppStore Connect website to be tested by in TestFlight, requires a bit of previous preparation for the provisioning profile generation itself, copying the file to the project using a Copy Files build step and, then, adding a couple more entries to the Entitlements file.</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="2048" height="1422" src="https://blog.xojo.com/wp-content/uploads/2025/01/5-macOSTestFlightApp.png" alt="" class="wp-image-14409" srcset="https://blog.xojo.com/wp-content/uploads/2025/01/5-macOSTestFlightApp.png 2048w, https://blog.xojo.com/wp-content/uploads/2025/01/5-macOSTestFlightApp-300x208.png 300w, https://blog.xojo.com/wp-content/uploads/2025/01/5-macOSTestFlightApp-1024x711.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/01/5-macOSTestFlightApp-768x533.png 768w, https://blog.xojo.com/wp-content/uploads/2025/01/5-macOSTestFlightApp-1536x1067.png 1536w" sizes="auto, (max-width: 2048px) 100vw, 2048px" /></figure>
</div>


<p>Once everything this is done, your testers will be able to use the TestFlight app to download and test your builds and report feedback, crash reports and other information about it!</p>



<p><em>Javier Menendez is an engineer at Xojo and has been using Xojo since 1998. He lives in Castellón</em>, <em>Spain and hosts regular Xojo hangouts en español. Ask Javier questions on Twitter at <a href="https://twitter.com/xojoes" target="_blank" rel="noreferrer noopener">@XojoES</a> or on the <a href="https://forum.xojo.com/u/javier_menendez/summary" target="_blank" rel="noreferrer noopener">Xojo Forum</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p><strong>More in this series on distributing Mac apps:</strong></p>



<ul class="wp-block-list">
<li><a href="https://blog.xojo.com/2024/12/10/sandboxing-hardened-runtime-and-notarization-arrives-to-the-xojo-ide/" target="_blank" rel="noreferrer noopener">Sandboxing, Hardened Runtime and Notarization arrives to the Xojo IDE</a></li>



<li><a href="https://blog.xojo.com/2024/08/22/macos-apps-from-sandboxing-to-notarization-the-basics/" target="_blank" rel="noreferrer noopener">macOS Apps: From Sandboxing to Notarization, The Basics</a></li>



<li><a href="https://blog.xojo.com/2025/01/14/uploading-macos-builds-to-app-store-connect/" target="_blank" rel="noreferrer noopener">Uploading macOS Builds to App Store Connect</a></li>



<li><a href="https://blog.xojo.com/2025/01/30/provisioning-profiles-for-macos-apps/">Provisioning Profiles for macOS Apps</a></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Uploading macOS Builds to App Store Connect</title>
		<link>https://blog.xojo.com/2025/01/14/uploading-macos-builds-to-app-store-connect/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Tue, 14 Jan 2025 20:53:32 +0000</pubDate>
				<category><![CDATA[Desktop]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[App Development]]></category>
		<category><![CDATA[App Store]]></category>
		<category><![CDATA[App Store Connect]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Distribution]]></category>
		<category><![CDATA[Mac App Store]]></category>
		<category><![CDATA[Native App Development]]></category>
		<category><![CDATA[Xcode]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=14314</guid>

					<description><![CDATA[Since Xojo 2024r4 the IDE includes the ability to automatically compile macOS apps with Sandboxing, Hardened Runtime and Notarization. Continue reading to learn that extra&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Since Xojo 2024r4 the IDE includes the ability to automatically compile macOS apps with Sandboxing, Hardened Runtime and Notarization. Continue reading to learn that extra step in order to submit the created bundle directly to the App Store Connect website!</p>



<span id="more-14314"></span>



<p>There is a Xojo-made tool out there that can simplify the process, and if that&#8217;s your route, check out <a href="https://xojo.com/store/addons/ohanaware.php" target="_blank" rel="noreferrer noopener">AppWrapper from Ohanaware</a>. But if you are the kind of developer that enjoys &#8220;how things work under the hood&#8221;, then follow these steps to do it manually from the command line (or convert these instructions into Xojo Scripts that can be executed as part of the build process itself from the Xojo project).</p>



<p>There are some requirements for all of this to work, but you took care of them already if you already followed our <a href="https://blog.xojo.com/2024/08/22/macos-apps-from-sandboxing-to-notarization-the-basics/">previous post about how to apply Sandboxing, Hardened Runtime and Notarize</a> manually to your Xojo macOS builds. Perhaps, the most important one is that this requires a paid Apple Developer Program membership (around US $99/yr). Additionally, Xcode needs to be installed on your Mac in order to use its included <em>altool</em> and <em>productbuild</em> command line tools. Create an app-specific password in order to execute the <em>notarytool</em> command line tool, which is also required when using the <em>altool</em> command line. You likely created one already for the <em>notarytool</em> command line tool which you can use as the password required by the <em>altool</em> command line tool.</p>



<p>If distributing your macOS apps from your website, these need to be signed using the &#8220;Apple Development&#8221; Certificate, but if you are compiling a macOS app for distribution through the Mac App Store, you need to sign it using the &#8220;Apple Distribution&#8221; certificate. So make sure to fill-in the macOS &gt; Signing &gt; Developer ID field properly.</p>



<p>Also important, in order to upload the app to App Store Connect, you need to create a package file from the app bundle, and that package file (.pkg) needs to be signed using the &#8220;3rd Party Mac Developer Installer&#8221;. Make sure you have this certificate installed in your Mac Keychain.</p>



<h2 class="wp-block-heading">First things … First</h2>



<p>Before you can upload you .pkg file to the App Store Connect website, there are some things you need to take care of that are required by Apple for apps to be distributed through the Mac App Store.</p>



<ol class="wp-block-list">
<li>The first thing is to register an App ID (or Identifier) in the <a href="https://developer.apple.com/account/resources/identifiers/">Apple Developer Portal</a>. When doing it, make sure you are creating an explicit Identifier instead of a wildcard one. Also very important, make sure that the identifier (in the reversed DNS form) is the same one you are using in the field macOS &gt; Build &gt; Bundle Identifier of your Xojo project. If they don&#8217;t match, then you can expect errors throughout the process.</li>



<li>The second thing is to create a new record for the App itself in the App Store Connect website. This is the place where you need to provide all the information requested by Apple for two main things: 1. what will be available as the app information when the users reach your app in the Mac App Store (for example product description, price, images, etc.), and, 2. what is for internal and compliance use. All in all, make sure you create a new macOS app record and go through all the available sections to fill in the requested information.</li>
</ol>



<p>Once these two steps are completed, we can focus on the command line itself to create the .pkg file and upload it manually (optionally, it is possible to use the Transporter app to select the .pkg file and upload it).</p>



<h2 class="wp-block-heading">Sing, sing, sing … the re-signing song!</h2>



<p>When building the macOS app from the Xojo IDE, it will be correctly signed based on the settings selected in the Build Settings &gt; Sign section. But because of the way Apple requires some entries to be formatted (specifically those for the CFBundleShortVersionString and CFBundleVersion keys), and the fact that it also requires the LSApplicationCategoryType key to be present in the Plist file with the associated value (the app category value <a href="https://developer.apple.com/documentation/bundleresources/information-property-list/lsapplicationcategorytype?language=objc">among those you can find here</a>), we need to manually edit the generated Info.Plist file for the compiled app.</p>



<p>Yeah, sure we can create an additional text file named Info.Plist file with the appropriate/expected keys and values and drop such file in the IDE navigator for our project so this information gets added/modified, as for example this one:</p>



<pre class="wp-block-code"><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;&lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
&lt;plist version="1.0"&gt;
&lt;dict&gt;
	&lt;key&gt;CFBundleShortVersionString&lt;/key&gt;
	&lt;string&gt;1.0.0&lt;/string&gt;
	&lt;key&gt;CFBundleVersion&lt;/key&gt;
	&lt;string&gt;1.0.0&lt;/string&gt;
	&lt;key&gt;LSApplicationCategoryType&lt;/key&gt;
	&lt;string&gt;public.app-category.business&lt;/string&gt;
&lt;/dict&gt;
&lt;/plist&gt;</code></pre>



<p>The bad news is that the value for the CFBundleVersion key will not be replaced with the one from our Info.Plist file.</p>



<p>What&#8217;s the downside of manually editing the Info.Plist file for the already compiled app? Well, as soon you make a change and save it,&nbsp;the app bundle signature will be invalidated. But no fear!&nbsp;We know how to do it already, right? If not, I suggest you to <a href="https://blog.xojo.com/2024/08/22/macos-apps-from-sandboxing-to-notarization-the-basics/">take a look to the blog post about Sandboxing</a>, Hardened Runtime and Notarization for macOS apps that I mentioned earlier.</p>



<p>Go ahead, select your compiled app in the Finder, click on its icon and select the option &#8220;Show package Contents&#8221; from the contextual menu. This action will show the &#8220;inner files&#8221; of the bundle that composes your app. Inside the Contents folder you will see the Info.Plist file. Click on it and select the option from the contextual menu allowing you to edit it with the text editor of your preference (mine is to use <a href="https://www.barebones.com/products/bbedit/index.html">BBEdit</a> from BareBones Software).</p>



<ul class="wp-block-list">
<li>Locate the CFBundleVersion key entry and change its string value so it doesn&#8217;t have more than three numbers separated by the dot character (as shown in the previous Plist example file).</li>



<li>Locate the CFBundleShortVersionString and change its string to make sure it has three version numbers separated by the dot character.</li>
</ul>



<p>Of course for both of the previous keys, make sure these match your expected version numbers for the app! In the example I used 1.0.0 as it&#8217;s typical for the initial release of an app.</p>



<p>Next, add the expected LSApplicationCategoryType key with the value that better fits your app among those available at the <a href="https://developer.apple.com/documentation/bundleresources/information-property-list/lsapplicationcategorytype?language=objc">Apple Documentation website</a>. In the previous Plist file example I&#8217;m using the one for the Business category:</p>



<pre class="wp-block-code"><code>	&lt;key&gt;LSApplicationCategoryType&lt;/key&gt;
	&lt;string&gt;public.app-category.business&lt;/string&gt;</code></pre>



<p>Save the changes to our modified Info.Plist file. Now it is time to sign it again!</p>



<h2 class="wp-block-heading">What about the Entitlements?</h2>



<p>Heh… wait! Because we need to re-sign our app bundle again, we also need to attach the expected entitlements to it! That means at least one very-important-and-required entitlement: enabling Sandboxing, which needs to be done to any app sent for distribution through the Mac App Store.</p>



<p>While Xojo 2024r4+ is able to do it automatically when building the app, now we also need to do it manually. That means creating our own .entitlements file that will be used when re-signing the app. For example, for a very typical (and bare-bones) app that only needs to read and write files it would look like this:</p>



<pre class="wp-block-code"><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;&lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
&lt;plist version="1.0"&gt;
&lt;dict&gt;
	&lt;key&gt;com.apple.security.app-sandbox&lt;/key&gt;
	&lt;true/&gt;
	&lt;key&gt;com.apple.security.files.user-selected.read-write&lt;/key&gt;
	&lt;true/&gt;
&lt;/dict&gt;
&lt;/plist&gt;</code></pre>



<p>Save it as &#8220;myEntitlements.entitlements&#8221; to your Mac drive. Of course, if you app requires more entitlements, go ahead and add them to the previous &#8220;template&#8221; .entitlements file.</p>



<p>We now have our modified .Plist file and the required .Entitlements file… so we have everything we need to re-sign the app bundle again!</p>



<p>Open a Terminal window and type the following command:</p>



<pre class="wp-block-code"><code>codesign --force --timestamp --entitlements path-to-your-myEntitlements.entitlements-file  -s "Apple Distribution: whatever-name-you-use (BZXXXXXXX)" path-to-the-bundle-of-the-compiled-app.app</code></pre>



<p>Look how we are using the reference to the entitlements file, and the &#8220;Apple Distribution&#8221; certificate instead of the &#8220;Apple Development&#8221; certificate.</p>



<h2 class="wp-block-heading">Packaging Acme</h2>



<p>So far so good. We have our app bundle signed again, so we are ready now to create a .pkg file from it! All you need to do is to type the following command from a Terminal window:</p>



<pre class="wp-block-code"><code>productbuild --sign "3rd Party Mac Developer Installer: whatever-name-you-use (BZXXXXXXX)"  --component path-to-the-bundle-of-the-compiled-app.app  /Applications path-to-the-generated-package-file.pkg</code></pre>



<p>As you can see, we are using the &#8220;3rd Party Mac Developer Installer&#8221; certificate in order to create the package file.</p>



<h2 class="wp-block-heading">Uploading it!</h2>



<p>With the package file already created, we now have all we need to upload it to the App Store Connect website. At this point you can follow two paths. The first one is to use the Transporter App that you can download from the Mac App Store itself. In that case:</p>



<ul class="wp-block-list">
<li>Open the Transporter app.</li>



<li>Click on the &#8220;+&#8221; icon. That action will bring a dialog where you can select the previously created .pkg file.</li>



<li>Once it is added, Transporter will make some early checks on the package contents. If everything goes OK, you should see something like this:</li>
</ul>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1824" height="1420" src="https://blog.xojo.com/wp-content/uploads/2025/01/TransporterA.png" alt="" class="wp-image-14320" srcset="https://blog.xojo.com/wp-content/uploads/2025/01/TransporterA.png 1824w, https://blog.xojo.com/wp-content/uploads/2025/01/TransporterA-300x234.png 300w, https://blog.xojo.com/wp-content/uploads/2025/01/TransporterA-1024x797.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/01/TransporterA-768x598.png 768w, https://blog.xojo.com/wp-content/uploads/2025/01/TransporterA-1536x1196.png 1536w" sizes="auto, (max-width: 1824px) 100vw, 1824px" /></figure>
</div>


<p>The interesting thing about using Transporter is that you can select the &#8220;Verify&#8221; option from the associated contextual menu (the one with the three dots icon). That action will start some more deeply checking on the package (and its contents) so you can get some early information about things that need to be fixed prior uploading it to the App Store Connect Website. For example, this error generated when the bundle version is duplicated:</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1824" height="1420" src="https://blog.xojo.com/wp-content/uploads/2025/01/TransporterB.png" alt="" class="wp-image-14333" srcset="https://blog.xojo.com/wp-content/uploads/2025/01/TransporterB.png 1824w, https://blog.xojo.com/wp-content/uploads/2025/01/TransporterB-300x234.png 300w, https://blog.xojo.com/wp-content/uploads/2025/01/TransporterB-1024x797.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/01/TransporterB-768x598.png 768w, https://blog.xojo.com/wp-content/uploads/2025/01/TransporterB-1536x1196.png 1536w" sizes="auto, (max-width: 1824px) 100vw, 1824px" /></figure>
</div>


<p>The second option involves using the aforementioned <em>altool</em> command line to automatically upload the package to the App Store Connect website. If you choose this path, all you need to do is to execute the following command from a Terminal window:</p>



<pre class="wp-block-code"><code>xcrun altool  --upload-package path-to-the-package-file.pkg -u your-apple-developer-login-id-goes-here -p "your-app-specific-password-goes-here" --type osx -apple-id "6111111111" --bundle-id "com.yourcomany.yourIdentifier" --bundle-short-version-string "1.0.0" --bundle-version "1.0.0"     </code></pre>



<p>Some considerations about the provided options/values for this command:</p>



<ul class="wp-block-list">
<li><strong>-u</strong>: This is the login name you use when accessing the Apple Developer website</li>



<li><strong>-p</strong>: This is the app-specific password you created from scratch following the steps provided in the aforementioned blog post.</li>



<li><strong>-apple-id</strong>: This is the numeric value you can find under General &gt; App Information at the appstoreconnect.apple.com website for the record created for this app:</li>
</ul>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1358" height="788" src="https://blog.xojo.com/wp-content/uploads/2025/01/AppStoreConnectA.png" alt="" class="wp-image-14321" srcset="https://blog.xojo.com/wp-content/uploads/2025/01/AppStoreConnectA.png 1358w, https://blog.xojo.com/wp-content/uploads/2025/01/AppStoreConnectA-300x174.png 300w, https://blog.xojo.com/wp-content/uploads/2025/01/AppStoreConnectA-1024x594.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/01/AppStoreConnectA-768x446.png 768w" sizes="auto, (max-width: 1358px) 100vw, 1358px" /></figure>
</div>


<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>This information can also be retrieved using:</p>



<pre class="wp-block-code"><code>xcrun altool --list-apps -u your-apple-developer-login-id-goes-here -p "your-app-specific-password-goes-here" --output-format json</code></pre>
</blockquote>



<ul class="wp-block-list">
<li><strong>&#8211;bundle-id</strong>: Make sure to provide the same value as the one used when creating the Identifier for the App and, thus, the same one used under Build Settings &gt; macOS &gt; Build &gt; Build Identifier field in your Xojo project.</li>



<li><strong>&#8211;bundle-short-version-string</strong>: Make sure it&#8217;s the same value used for the CFBundleShortVersionString key in the .Plist file.</li>



<li><strong>&#8211;bundle-version</strong>: Make sure to provide the same value as the one used for the CFBundleVersion key in the .Plist file.</li>
</ul>



<p>Once the command is executed, your package file will be uploaded to the App Store Connect website and, once completed, eligible as a new Build to be added to your app record so you can send it to review as part of the Apple reviewing process.</p>



<h2 class="wp-block-heading">In Summary</h2>



<p>There are several details to take care of, but Xojo has simplified the process of covering the &#8220;last mile&#8221; of sending you compiled app for review at the App Store Connect website.</p>



<p><em>Javier Menendez is an engineer at Xojo and has been using Xojo since 1998. He lives in Castellón</em>, <em>Spain and hosts regular Xojo hangouts en español. Ask Javier questions on Twitter at <a href="https://twitter.com/xojoes" target="_blank" rel="noreferrer noopener">@XojoES</a> or on the <a href="https://forum.xojo.com/u/javier_menendez/summary" target="_blank" rel="noreferrer noopener">Xojo Forum</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p><strong>More in this series on distributing Mac apps:</strong></p>



<ul class="wp-block-list">
<li><a href="https://blog.xojo.com/2024/12/10/sandboxing-hardened-runtime-and-notarization-arrives-to-the-xojo-ide/" target="_blank" rel="noreferrer noopener">Sandboxing, Hardened Runtime and Notarization arrives to the Xojo IDE</a></li>



<li><a href="https://blog.xojo.com/2024/08/22/macos-apps-from-sandboxing-to-notarization-the-basics/" target="_blank" rel="noreferrer noopener">macOS Apps: From Sandboxing to Notarization, The Basics</a></li>



<li><a href="https://blog.xojo.com/2025/01/14/uploading-macos-builds-to-app-store-connect/" target="_blank" rel="noreferrer noopener">Uploading macOS Builds to App Store Connect</a></li>



<li><a href="https://blog.xojo.com/2025/01/30/provisioning-profiles-for-macos-apps/">Provisioning Profiles for macOS Apps</a></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>macOS: Add More Options to the Window Menu</title>
		<link>https://blog.xojo.com/2024/12/16/macos-add-more-options-to-the-window-menu/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Mon, 16 Dec 2024 16:00:00 +0000</pubDate>
				<category><![CDATA[Learning]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[App Localization]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Declares]]></category>
		<category><![CDATA[macOS]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=14163</guid>

					<description><![CDATA[By default, macOS adds several menu options to the Window menu of any Desktop app. Those options have been getting more interesting in the latest&#8230;]]></description>
										<content:encoded><![CDATA[
<p>By default, macOS adds several menu options to the Window menu of any Desktop app. Those options have been getting more interesting in the latest releases of the operating system, allowing, among other things, to set the position and arrangement of the Window on the screen, split the screen between the Window of one app and another app, or even sending a window of an app to an iPad as an &#8220;extended&#8221; screen in your macOS setup. Read on, adding these options to your Xojo-built macOS apps is just a few Declares away!</p>



<span id="more-14163"></span>



<p>Once you add this ability to your macOS apps, they will fit better when compared with other apps running alongside them. Even better, you don&#8217;t need to write additional code in order to handle these additional menu options.</p>



<p>Create a new Desktop project and add a new Module to it called &#8220;macOSExtra&#8221;. Then add a new method to it using the following signature, make sure to set the Scope of the property to Global:</p>



<pre class="wp-block-code"><code>AddMacOSWindowMenu(item as DesktopMenuItem)</code></pre>



<p>As you can see, this method expects to receive a DesktopMenuItem instance; but before we write a line of code for this method, select the MainMenuBar item in the project Navigator.</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="84" height="62" src="https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.50.03 p. m.png" alt="" class="wp-image-14164"/></figure>
</div>


<p>The previous action will bring up the Menu Editor. Click on the toolbar button in charge of adding a new first level menu item to the menu bar:</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="2058" height="696" src="https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.49.08 p. m.png" alt="" class="wp-image-14165" srcset="https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.49.08 p. m.png 2058w, https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.49.08 p. m-300x101.png 300w, https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.49.08 p. m-1024x346.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.49.08 p. m-768x260.png 768w, https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.49.08 p. m-1536x519.png 1536w, https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.49.08 p. m-2048x693.png 2048w" sizes="auto, (max-width: 2058px) 100vw, 2058px" /></figure>
</div>


<p>Next, with the new menu item selected in the Navigator, change the following properties in the associated Inspector Panel:</p>



<ul class="wp-block-list">
<li><strong>Name:</strong> WindowMenu</li>



<li><strong>Text:</strong> Window</li>
</ul>



<p>Now, let&#8217;s go back to the AddMacOSWindowMenu method in the &#8220;macOSEXtra&#8221; module, type the following code in the associated Code Editor:</p>



<pre class="wp-block-code"><code>// This code will be only executed when compiling the project
// for the macOS target

#if TargetMacOS then
  
  // We declare the function allowing us to get the reference to a class
  // from the macOS framework (Foundation, in this case), from the parameter passed
  // to it as a String (the class name we want to get the reference to).
  // You can get additional information about this from the Apple Documentation at: https://developer.apple.com/documentation/foundation/1395135-nsclassfromstring?language=objc
  Declare Function NSClassFromString Lib "Foundation" ( name As CFStringRef) As Ptr
  Var theClass As Ptr = NSClassFromString("NSApplication")
  
  // Now that we have the reference to the class
  // we will use it to call the shared method / selector from the NSApplication
  // class in charge or returning a reference to the running app (that is "our" app in this case).
  // You can get additional information about this from the Apple Documentation at:
https:&#47;&#47;developer.apple.com/documentation/appkit/nsapplication/shared?language=objc
  
  Declare Function GetSharedApplication Lib "AppKit" Selector "sharedApplication" (Application As ptr) As Ptr
  Var theApp As Ptr = GetSharedApplication(theClass)
  
  // Now that we have a reference to the app object, we need to get a reference to the "submenu" hanging from the menu instance received as parameter by the method. For that
  // we need to call the method / selector "submenu" passing along the underlying native
  // menu object retrieved via the "Handle" property from DesktopMenuItem.
  
  Declare Function GetSubmenu Lib "AppKit" Selector "submenu" (menuReference As Ptr) As Ptr
  Var subMenu As Ptr = GetSubmenu(item.Handle)
  
  // The last step is to assign the previous reference to the window property from the app reference.
  // You can get additional information about this from the Apple Documentation at: https://developer.apple.com/documentation/appkit/nsapplication/windowsmenu?language=objc
  
  Declare Sub setWindowMenu Lib "AppKit" selector "setWindowsMenu:" ( appReference As Ptr, menuReference As Ptr)
  setWindowMenu(theApp, subMenu)
  
#EndIf
</code></pre>



<h2 class="wp-block-heading">Testing it!</h2>



<p>In order to see how this new method works, select the App item under the IDE Navigator and add the Opening event. Then, type the following line of code in the associated Code Editor:</p>



<pre class="wp-block-preformatted">AddMacOSWindowMenu(WindowMenu)</pre>



<p>Run the app and click on the Window item in the main menu bar. You should see that the operating system has added several menu options, similar to the ones displayed in this screenshot (they will vary depending the macOS version the app is running on):</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1686" height="1054" src="https://blog.xojo.com/wp-content/uploads/2024/12/WindowMenu.png" alt="" class="wp-image-14166" srcset="https://blog.xojo.com/wp-content/uploads/2024/12/WindowMenu.png 1686w, https://blog.xojo.com/wp-content/uploads/2024/12/WindowMenu-300x188.png 300w, https://blog.xojo.com/wp-content/uploads/2024/12/WindowMenu-1024x640.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/12/WindowMenu-768x480.png 768w, https://blog.xojo.com/wp-content/uploads/2024/12/WindowMenu-1536x960.png 1536w" sizes="auto, (max-width: 1686px) 100vw, 1686px" /></figure>
</div>


<p>Choose any of the options added and you will see how macOS handles them, without the need to write a line of code in you Xojo project to do it.</p>



<h2 class="wp-block-heading">Localizing the Window Menu</h2>



<p>At this point, the Window menu with the added menu options will look great, but if your app is localized to other languages, then it will be a bit odd to read &#8220;Window&#8221; for the menu (as well as the English text in the added menu items). To improve this experience, let&#8217;s localize the WindowMenu item too!</p>



<p>Let&#8217;s add a new Constant to the &#8220;macOSExtra&#8221; Module and name it &#8220;kWindowName&#8221; setting its default value to &#8220;Window&#8221; and switching on the &#8220;Localized&#8221; field in the Inspector Panel:</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="606" height="502" src="https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.33.42 p. m.png" alt="" class="wp-image-14167" srcset="https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.33.42 p. m.png 606w, https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.33.42 p. m-300x249.png 300w" sizes="auto, (max-width: 606px) 100vw, 606px" /></figure>
</div>


<p>Then, use the associated Constant Editor to add new entries (in as many as languages you support). In this case we will just add the entries to support both English and Spanish:</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="920" height="378" src="https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.34.17 p. m.png" alt="" class="wp-image-14168" srcset="https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.34.17 p. m.png 920w, https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.34.17 p. m-300x123.png 300w, https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.34.17 p. m-768x316.png 768w" sizes="auto, (max-width: 920px) 100vw, 920px" /></figure>
</div>


<p>Next, select the WindowMenu item hanging from the MainMenuBar item in the Navigator, and change the value of the Text property to use the new constant:</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="2058" height="738" src="https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.37.44 p. m.png" alt="" class="wp-image-14169" srcset="https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.37.44 p. m.png 2058w, https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.37.44 p. m-300x108.png 300w, https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.37.44 p. m-1024x367.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.37.44 p. m-768x275.png 768w, https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.37.44 p. m-1536x551.png 1536w, https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.37.44 p. m-2048x734.png 2048w" sizes="auto, (max-width: 2058px) 100vw, 2058px" /></figure>
</div>


<p>Change the macOS Settings &gt; General &gt; Idiom and Region so the Spanish language is the main language. Then run the Xojo project again from the IDE and you will see how the &#8220;Window&#8221; menu entry now reads &#8220;Ventana&#8221;. Moreover, macOS will add the right localizations for the added menu items so they are in Spanish too.</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1654" height="1508" src="https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.31.27 p. m.png" alt="" class="wp-image-14170" srcset="https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.31.27 p. m.png 1654w, https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.31.27 p. m-300x274.png 300w, https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.31.27 p. m-1024x934.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.31.27 p. m-768x700.png 768w, https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.31.27 p. m-1536x1400.png 1536w" sizes="auto, (max-width: 1654px) 100vw, 1654px" /></figure>
</div>

<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1764" height="1104" src="https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.37.04 p. m.png" alt="" class="wp-image-14171" srcset="https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.37.04 p. m.png 1764w, https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.37.04 p. m-300x188.png 300w, https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.37.04 p. m-1024x641.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.37.04 p. m-768x481.png 768w, https://blog.xojo.com/wp-content/uploads/2024/12/Captura-de-pantalla-2024-12-09-a-las-1.37.04 p. m-1536x961.png 1536w" sizes="auto, (max-width: 1764px) 100vw, 1764px" /></figure>
</div>


<h2 class="wp-block-heading">In Brief</h2>



<p>As you have seen, using just a few Declares we have been able to add the expected options for the Window menu to our macOS apps, without the need to write the code in charge of handling them! This doesn&#8217;t just mean more options for your users, it also means your Xojo apps will look and feel better when running on macOS.</p>



<p><em>Javier Menendez is an engineer at Xojo and has been using Xojo since 1998. He lives in Castellón</em>, <em>Spain and hosts regular Xojo hangouts en español. Ask Javier questions on Twitter at <a href="https://twitter.com/xojoes" target="_blank" rel="noreferrer noopener">@XojoES</a> or on the <a href="https://forum.xojo.com/u/javier_menendez/summary" target="_blank" rel="noreferrer noopener">Xojo Forum</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>macOS Apps: From Sandboxing to Notarization, The Basics</title>
		<link>https://blog.xojo.com/2024/08/22/macos-apps-from-sandboxing-to-notarization-the-basics/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Thu, 22 Aug 2024 15:45:28 +0000</pubDate>
				<category><![CDATA[Learning]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[App Development]]></category>
		<category><![CDATA[App Store]]></category>
		<category><![CDATA[App Store Connect]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Distribution]]></category>
		<category><![CDATA[Entitlements]]></category>
		<category><![CDATA[Hardened Runtime]]></category>
		<category><![CDATA[Mac App Store]]></category>
		<category><![CDATA[Native App Development]]></category>
		<category><![CDATA[Notarization]]></category>
		<category><![CDATA[Sandboxing]]></category>
		<category><![CDATA[Xcode]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13510</guid>

					<description><![CDATA[You are likely already familiar with terms like Sandboxing, hardened runtime and Notarization. After all, these are required if you plan to distribute your macOS&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You are likely already familiar with terms like Sandboxing, hardened runtime and Notarization. After all, these are required if you plan to distribute your macOS apps through the Mac App Store. But, starting with macOS Sequoia 15 (expected in the fall of 2024), Apple has tightened the runtime security protections even more. For example, it was common to Control + click on any downloaded macOS app from Internet that has not been signed and simply choose the Open option from the contextual menu to open it. That won&#8217;t be an option under Sequoia (although it still possible to run the unsigned app).</p>



<p>In fact, Apple recommends to Notarize the software even if you are going to distribute it from your own website, outside of the Mac App Store. But, don&#8217;t be scared! Currently there are good third parties options available that ease the path, like <a href="https://ohanaware.com/appwrapper/">App Wrapper from Ohanaware</a>, or some OpenSource options as for example <a href="https://github.com/jo-tools/xojo2dmg">Xojo2DMG</a>; and through this article you will see how to enable Sandboxing, runtime hardening and even Notarizing on a simple example app. Of course, this will touch only the basics and it is up to you to read the related Apple Documentation to add the entries, both the Entitlements and additional keys/values in the app Info.plist file, required by the purposes of your particular app, for example file access, camera or mic access, network access, etc.</p>



<h2 class="wp-block-heading">A Bit of Common Ground</h2>



<p>At this point, your head may be spinning if you are unfamiliar with these app security terms; so, what do Sandbox, hardened runtime and Notarizing mean when they are applied to macOS apps?</p>



<h3 class="wp-block-heading">Sandboxing</h3>



<p>When a macOS app is sandboxed, that means that macOS will create an exclusive container for everything related to the app the first time it is launched. This is what happens when installing an iOS app, too! Such a container will have its own structure to access things like documents, pictures, downloads, etc. Think about it as the own private execution space for the app:</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1006" height="640" src="https://blog.xojo.com/wp-content/uploads/2024/08/1-Container.png" alt="" class="wp-image-13511" srcset="https://blog.xojo.com/wp-content/uploads/2024/08/1-Container.png 1006w, https://blog.xojo.com/wp-content/uploads/2024/08/1-Container-300x191.png 300w, https://blog.xojo.com/wp-content/uploads/2024/08/1-Container-768x489.png 768w" sizes="auto, (max-width: 1006px) 100vw, 1006px" /></figure>
</div>


<p>Of course, there are <a href="https://developer.apple.com/documentation/security/app_sandbox?language=objc">entitlements waiting for you</a> so your sandboxed app can access the files created by other apps (including the Desktop, Downloads, Movies, Music and Picture folders), among other things.</p>



<h3 class="wp-block-heading">Hardened Runtime</h3>



<p>When enabled for your macOS app, hardened runtime adds an extra layer of protection to the running code itself. For example, it prevents certain classes of exploits, like code injection, dynamically linked library (DLL) hijacking, and process memory space tampering. This kind of protection is also enhanced by the <a href="https://support.apple.com/en-us/102149">System Integrity Protection (SIP)</a>.</p>



<h3 class="wp-block-heading">Notarization</h3>



<p>In brief, this is a third layer of confidence for the potential users of your macOS app. When the app is notarized, that ensures to the user that the Developer ID-signed software you distribute has been checked by Apple for malicious components. This is not related with the Apple Review process of your app when it is submitted to the Mac App Store, it&#8217;s related to the <a href="https://support.apple.com/en-gb/guide/security/sec5599b66df/web">macOS Gatekeeper technology</a>. So, when a Notarized app is downloaded from Internet, for example, Gatekeeper will use the notarization ticket attached to your app/DMG file to provide more meaningful information about the origin of the app, including if it is safe for the user to open it.</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="744" height="752" src="https://blog.xojo.com/wp-content/uploads/2024/08/2-Gatekeeper.png" alt="" class="wp-image-13513" srcset="https://blog.xojo.com/wp-content/uploads/2024/08/2-Gatekeeper.png 744w, https://blog.xojo.com/wp-content/uploads/2024/08/2-Gatekeeper-297x300.png 297w" sizes="auto, (max-width: 744px) 100vw, 744px" /></figure>
</div>


<h2 class="wp-block-heading">Preparation</h2>



<p>In order to follow this article, you will need:</p>



<ul class="wp-block-list">
<li><strong>Xojo</strong>. <a href="https://www.xojo.com/download">Download it for macOS</a> if you have not done yet.</li>



<li><strong>macOS 11.3</strong> or later.</li>



<li><strong>Xcode 13</strong> or later. Run it at least one time and make sure that all its required components and SDKs are installed.</li>



<li><strong>Apple Developer ID</strong>. This needs to be a paid Apple Developer membership. Also, make sure you have your Developer certificates installed in the Mac.</li>



<li>A working <strong>Internet</strong> connection.</li>
</ul>



<p>With all of this in place, open Xojo to create a macOS Desktop project and do some basic layout in the by default window. It is not required to add any functionality to keep the focus in the task at hand. Then, use Build Settings &gt; macOS &gt; Mac App Name to give an appropriate name to the built application (for this example I named it &#8220;SandboxedApp&#8221;).</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="594" height="654" src="https://blog.xojo.com/wp-content/uploads/2024/08/3-XojoProjectName.png" alt="" class="wp-image-13512" srcset="https://blog.xojo.com/wp-content/uploads/2024/08/3-XojoProjectName.png 594w, https://blog.xojo.com/wp-content/uploads/2024/08/3-XojoProjectName-272x300.png 272w" sizes="auto, (max-width: 594px) 100vw, 594px" /></figure>
</div>


<p>Lastly, save the project (for example into the Documents folder) and click the Build button to build the app! It is not required at this point to assign the Developer ID in the Build Settings &gt; macOS &gt; Sign section, because we are going to sign it (again) in the next steps.</p>



<h2 class="wp-block-heading">Creating the Entitlements File</h2>



<p>The entitlements file is pretty similar to the Info.plist file you probably already know that is in charge of storing the required keys and values for the app to properly work. Both of these are in XML format, and the only difference is that while the Info.plist file is created for you by Xojo, the Entitlements file needs to be, currently, manually created for you.</p>



<p>So, open your text editor of choice (there a lot of there out there, both free and paid ones; personally I tend to use BBEdit from BareBones Software). Add the following lines to the text document and save it with the name &#8220;Entitlements.plist&#8221; (if you keep it next to the saved built macOS app, the better). This is the file where you will probably want to add more entitlement entries as your app requires them:</p>



<pre class="wp-block-code"><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd"&gt;
&lt;plist version="0.9"&gt;
&lt;dict&gt;
  &lt;key&gt;com.apple.security.app-sandbox&lt;/key&gt;
  &lt;true/&gt;
&lt;/dict&gt;
&lt;/plist&gt;</code></pre>



<h2 class="wp-block-heading">Sandbox Your App</h2>



<p>With the compiled app and the entitlements file in place, open the Terminal app and type the following command and press the return key:</p>



<pre class="wp-block-code"><code>&gt; codesign --force --deep --timestamp --entitlements &lt;path-to-your-entitlements.plist-file&gt; -s "Developer ID Application: &lt;your-full-developer-name (including-the-team-id)&gt;" &lt;path-to-the-bundle-of-your-app&gt;</code></pre>



<p>Once executed, run the &#8220;SandboxedApp&#8221;, open the Activity Monitor app and make sure that the Sandbox option is enabled under the View &gt; Columns options. Then, use the search box of the main window to filter the displayed processes so it only displays your app. Take a look to the value under the Sandbox column and you will see that the app is now Sandboxed, and the Container for it has been created under the Library/Containers path. Quit the app when you are done.</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1704" height="992" src="https://blog.xojo.com/wp-content/uploads/2024/08/4-Sandbox.png" alt="" class="wp-image-13514" srcset="https://blog.xojo.com/wp-content/uploads/2024/08/4-Sandbox.png 1704w, https://blog.xojo.com/wp-content/uploads/2024/08/4-Sandbox-300x175.png 300w, https://blog.xojo.com/wp-content/uploads/2024/08/4-Sandbox-1024x596.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/08/4-Sandbox-768x447.png 768w, https://blog.xojo.com/wp-content/uploads/2024/08/4-Sandbox-1536x894.png 1536w" sizes="auto, (max-width: 1704px) 100vw, 1704px" /></figure>
</div>


<h2 class="wp-block-heading">Hardened Runtime</h2>



<p>With our app already sandboxed, let&#8217;s look how to add the hardened option to it. Once again, type the following command in the Terminal prompt:</p>



<pre class="wp-block-code"><code>&gt; codesign --force --deep <strong>--options runtime</strong> --timestamp --entitlements &lt;path-to-your-entitlements.plist-file&gt; -s "Developer ID Application: &lt;your-full-developer-name (including-the-team-id)&gt;" &lt;path-to-the-bundle-of-your-app&gt;</code></pre>



<p>As you can see, it doesn&#8217;t vary much from the previous command. All it adds is the &#8220;<strong>&#8211;options runtime</strong>&#8221; text in charge of enabling the runtime hardening. Also, as you might guess, using this command will enable the Sandboxing of the app and also the runtime hardening, at all once.</p>



<p>Do you want to check if it worked? Well, type the following command at the Terminal prompt:</p>



<pre class="wp-block-code"><code>&gt; codesign --display --verbose &lt;path-to-the-bundle-of-your-app&gt;</code></pre>



<p>It will produce an output similar to this one:</p>



<pre class="wp-block-code"><code>Executable=&lt;path-to-the-executable&gt;
Identifier=com.xojo.sandboxedapp
Format=app bundle with Mach-O universal (x86_64 arm64)
CodeDirectory v=20500 size=43297 <strong>flags=0x10000(runtime)</strong> hashes=1342+7 location=embedded
Signature size=9100
Timestamp=13 Aug 2024 at 12:51:28 PM
Info.plist entries=15
TeamIdentifier=************
Runtime Version=11.1.0
Sealed Resources version=2 rules=13 files=4
Internal requirements count=1 size=184</code></pre>



<p>It is the &#8220;<strong>flags=0x1000(runtime)</strong>&#8221; which shows that, in fact, the app runtime is hardened. Congrats!</p>



<h2 class="wp-block-heading">Notarizing the App</h2>



<p>This is the final step, but is going to require an extra step from your side. Because the notarytool command line tool, used for notarizing the app, is going to require the ID and password from your Apple ID account, plus the fact that it uses 2FA authentication, it is very convenient to create an app specific password for it.</p>



<h3 class="wp-block-heading">Creating an App-Specific Password</h3>



<p>In order to create the password used by the notarytool process, follow this steps:</p>



<ol class="wp-block-list">
<li>Sign in to <a href="https://appleid.apple.com">appleid.apple.com</a></li>



<li>In the Sign-in and Security section, select the App-Specific Passwords option:</li>
</ol>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1408" height="1462" src="https://blog.xojo.com/wp-content/uploads/2024/08/5-AppSpecificPasswordA.png" alt="" class="wp-image-13515" srcset="https://blog.xojo.com/wp-content/uploads/2024/08/5-AppSpecificPasswordA.png 1408w, https://blog.xojo.com/wp-content/uploads/2024/08/5-AppSpecificPasswordA-289x300.png 289w, https://blog.xojo.com/wp-content/uploads/2024/08/5-AppSpecificPasswordA-986x1024.png 986w, https://blog.xojo.com/wp-content/uploads/2024/08/5-AppSpecificPasswordA-768x797.png 768w" sizes="auto, (max-width: 1408px) 100vw, 1408px" /></figure>
</div>


<ol start="3" class="wp-block-list">
<li>The previous action will bring a new dialog displaying all the app-specific passwords already created. Click the &#8220;+&#8221; button to add a new one:</li>
</ol>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1392" height="1308" src="https://blog.xojo.com/wp-content/uploads/2024/08/6-AppSpecificPasswordB.png" alt="" class="wp-image-13516" srcset="https://blog.xojo.com/wp-content/uploads/2024/08/6-AppSpecificPasswordB.png 1392w, https://blog.xojo.com/wp-content/uploads/2024/08/6-AppSpecificPasswordB-300x282.png 300w, https://blog.xojo.com/wp-content/uploads/2024/08/6-AppSpecificPasswordB-1024x962.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/08/6-AppSpecificPasswordB-768x722.png 768w" sizes="auto, (max-width: 1392px) 100vw, 1392px" /></figure>
</div>


<ol start="4" class="wp-block-list">
<li>Type a meaningful name for as the &#8220;Title&#8221; or description for your new password in the presented dialog (<strong>notarytool</strong> could be a good one):</li>
</ol>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="918" height="742" src="https://blog.xojo.com/wp-content/uploads/2024/08/7-AppSpecificPasswordC.png" alt="" class="wp-image-13517" srcset="https://blog.xojo.com/wp-content/uploads/2024/08/7-AppSpecificPasswordC.png 918w, https://blog.xojo.com/wp-content/uploads/2024/08/7-AppSpecificPasswordC-300x242.png 300w, https://blog.xojo.com/wp-content/uploads/2024/08/7-AppSpecificPasswordC-768x621.png 768w" sizes="auto, (max-width: 918px) 100vw, 918px" /></figure>
</div>


<ol start="5" class="wp-block-list">
<li>Once you click the Create button it is possible that you will be asked to authenticate again using your Apple ID. Once done, a new dialog will present the generated password to you. Copy it and write it down (or paste it) into a safe place, because we are going to need it in the next step.</li>
</ol>



<h3 class="wp-block-heading">Adding the notarytool specific password to the Keychain</h3>



<p>Because this app-specific password is going to be used by the notarytool command line tool, it would be very convenient to have it stored in the macOS Keychain. To do so, type the following command at the Terminal prompt, and press the Return key:</p>



<pre class="wp-block-code"><code>&gt; xcrun notarytool store-credentials "notarytool-password" --apple-id "&lt;your-apple-ID&gt;" --team-id &lt;your-developer-team-id&gt; --password &lt;the-password-copied-from-the-previous-step&gt;</code></pre>



<p>Once executed, you will be able to see the password added to the Keychain app under the name of &#8220;notarytool-password&#8221;:</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1948" height="1068" src="https://blog.xojo.com/wp-content/uploads/2024/08/8-NotaryToolPassword.png" alt="" class="wp-image-13518" srcset="https://blog.xojo.com/wp-content/uploads/2024/08/8-NotaryToolPassword.png 1948w, https://blog.xojo.com/wp-content/uploads/2024/08/8-NotaryToolPassword-300x164.png 300w, https://blog.xojo.com/wp-content/uploads/2024/08/8-NotaryToolPassword-1024x561.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/08/8-NotaryToolPassword-768x421.png 768w, https://blog.xojo.com/wp-content/uploads/2024/08/8-NotaryToolPassword-1536x842.png 1536w" sizes="auto, (max-width: 1948px) 100vw, 1948px" /></figure>
</div>


<h3 class="wp-block-heading">Creating a Zip file for your app</h3>



<p>The notarization process is handled by the Apple notary service running in the Internet, what means that notarytool needs to send (upload) the bundle of your app in an appropriate format. There are two options: as a DMG file (that needs to be signed before submitting), or as a zipped file, what is even faster and easier (Trivia: Did you know how easy it is to <a href="https://documentation.xojo.com/api/files/folderitem.html#folderitem-zip">create Zip files in Xojo code</a>?)</p>



<p>So, in order to upload our app for notarization, we need to create a Zip file first. Once again, it is time to type a new command at the Terminal prompt:</p>



<pre class="wp-block-code"><code>&gt; /usr/bin/ditto -c -k --keepParent &lt;path-to-app-bundle&gt; &lt;path-to-generated-zip-file/file-name.zip&gt;</code></pre>



<h3 class="wp-block-heading">&nbsp;</h3>



<h3 class="wp-block-heading">Uploading the app for Notarization</h3>



<p>With our Zip file in place, we now have all the pieces to send it to the notarization process. The time spent by that process may (and will) vary depending of several factors.</p>



<p>In order to send the file, type the following command at the Terminal prompt:</p>



<pre class="wp-block-code"><code>&gt; xcrun notarytool submit &lt;path-to-zip-file/file-name.zip&gt; --keychain-profile "notarytool-password" --wait </code></pre>



<p>After pressing the Return key, the process will start and the Terminal will output information about the progress; something similar to this:</p>



<pre class="wp-block-code"><code>Conducting pre-submission checks for &lt;name-of-your-zip-file&gt; and initiating connection to the Apple notary service...
Submission ID received
  id: &lt;some-id-number-goes-here&gt;
Upload progress: 100.00% (8.65 MB of 8.65 MB)   
Successfully uploaded file
  id: &lt;some-id-number-goes-here&gt;
  path: &lt;path-of-the-zip-file&gt;
Waiting for processing to complete.
Current status: Accepted........
Processing complete
  id: &lt;keep-this-id-in-a-safe-place-you-will-need-it-later&gt;
  status: Accepted</code></pre>



<p>Have you seen the last line? The &#8220;<strong>status: Accepted</strong>&#8221; means that everything worked OK, and the notarization process has been successful, but it&#8217;s better if we check! Type the following command at the Terminal prompt. This one will ask the notarytool command to download the log file in JSON format to be saved at the desired path. It is a good habit to do it, because such a log file will include some eventual error and explanation about possible errors during the notarization process, including those related to the app itself:</p>



<pre class="wp-block-code"><code>&gt; xcrun notarytool log &lt;put-here-the-value-you-saved-in-a-secure-place-from-the-id-field-in-the-previous-output&gt; --keychain-profile "notarytool-password" &lt;path-to-save-the-log.json&gt;</code></pre>



<h2 class="wp-block-heading">Staple the Ticket!</h2>



<p>Assuming that everything worked OK, it is time to staple the notarization ticket to the app itself. It is not required, but is convenient to avoid online checks when the user runs the app, or Gatekeeper inspects it.</p>



<p>Yeah, that means using a new command from Terminal on the already signed, sandboxed and runtime hardened app bundle (not the Zip file you created for submitting using notarytool):</p>



<pre class="wp-block-code"><code>&gt; xcrun stapler staple "&lt;path-to-the-signed-sandboxed-and-hardened-app-bundle&gt;"</code></pre>



<p>After that, you can check that everything went OK using the following command:</p>



<pre class="wp-block-code"><code>&gt; spctl -a -vvv -t install &lt;path-to-the-signed-sandboxed-and-hardened-app-bundle&gt;</code></pre>



<p>And you should get something similar to this as the output:</p>



<pre class="wp-block-code"><code>source=Notarized Developer ID
origin=&lt;your-full-developer-ID-Application&gt;</code></pre>



<h2 class="wp-block-heading">App Distribution</h2>



<p>That&#8217;s fine, but you will probably want to distribute your app from the Internet using a DMG container. In that case, follow these steps:</p>



<ol class="wp-block-list">
<li>Create a DMG container (file).</li>



<li>Copy your already notarized app bundle into it.</li>



<li>Notarize the DMG file.</li>



<li>Staple the ticket to the DMG file.</li>
</ol>



<p>That way the DMG container will be Notarized along with the app bundle inside it.</p>



<h2 class="wp-block-heading">In Summary</h2>



<p>As we did see, all the process of sandboxing, runtime hardening and Notarization involves a bunch of commands from the terminal, including the creation of the Zip file. But the good news is that all the process could be automated using Xojo itself! (take a look to the <a href="https://documentation.xojo.com/api/os/shell.html#executemodes">Shell</a> class and the <a href="https://documentation.xojo.com/api/files/folderitem.html#folderitem-zip">Zip method from the FolderItem class</a> if you are not familiar with them).</p>



<p>As I said before, this article only on touches the basics and doesn&#8217;t dig into Provisioning Profile creation (associated with Capabilities required by the app), the Entitlements your app may need to properly work, among other topics; so you may find these Apple Developer Documentation of interest:</p>



<p>&#8211; <a href="https://developer.apple.com/help/account/manage-profiles/create-a-development-provisioning-profile/">Provisioning profiles</a>.<br>&#8211; <a href="https://developer.apple.com/documentation/bundleresources/entitlements?language=objc">macOS Entitlements</a>.<br>&#8211; <a href="https://developer.apple.com/documentation/security/app_sandbox?language=objc">macOS Sandbox</a>.<br>&#8211; <a href="https://developer.apple.com/documentation/security/hardened_runtime?language=objc">macOS Hardened Runtime</a>.<br>&#8211; <a href="https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution?language=objc">macOS Notarization</a>.</p>



<p>Happy Xojo Coding!</p>



<p><em>Javier Menendez is an engineer at Xojo and has been using Xojo since 1998. He lives in Castellón</em>, <em>Spain and hosts regular Xojo hangouts en español. Ask Javier questions on Twitter at <a href="https://twitter.com/xojoes" target="_blank" rel="noreferrer noopener">@XojoES</a> or on the <a href="https://forum.xojo.com/u/javier_menendez/summary" target="_blank" rel="noreferrer noopener">Xojo Forum</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p><strong>More in this series on distributing Mac apps:</strong></p>



<ul class="wp-block-list">
<li><a href="https://blog.xojo.com/2024/12/10/sandboxing-hardened-runtime-and-notarization-arrives-to-the-xojo-ide/" target="_blank" rel="noreferrer noopener">Sandboxing, Hardened Runtime and Notarization arrives to the Xojo IDE</a></li>



<li><a href="https://blog.xojo.com/2024/08/22/macos-apps-from-sandboxing-to-notarization-the-basics/" target="_blank" rel="noreferrer noopener">macOS Apps: From Sandboxing to Notarization, The Basics</a></li>



<li><a href="https://blog.xojo.com/2025/01/14/uploading-macos-builds-to-app-store-connect/" target="_blank" rel="noreferrer noopener">Uploading macOS Builds to App Store Connect</a></li>



<li><a href="https://blog.xojo.com/2025/01/30/provisioning-profiles-for-macos-apps/">Provisioning Profiles for macOS Apps</a></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>iOS: Privacy Editor</title>
		<link>https://blog.xojo.com/2024/06/26/ios-privacy-editor/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Wed, 26 Jun 2024 15:00:00 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[2024r2]]></category>
		<category><![CDATA[App Store]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13171</guid>

					<description><![CDATA[Back in March we wrote about Apple’s new privacy policy for AppStore approval and how, and when, your Xojo iOS apps would meet this new requirement. In Xojo 2024r2 we've included a new Privacy Editor in the Xojo IDE. Continue reading to discover how to use the iOS Privacy Editor.]]></description>
										<content:encoded><![CDATA[
<p>Back in March we wrote about <a href="https://blog.xojo.com/2024/03/20/apples-new-privacy-manifest-requirements/">Apple’s new privacy policy for AppStore approval</a> and how, and when, your Xojo iOS apps would meet this new requirement. In Xojo 2024r2 we&#8217;ve included a new Privacy Editor in the Xojo IDE. Continue reading to discover how to use the iOS Privacy Editor.</p>



<span id="more-13171"></span>



<p>First of all, if your apps only relies on the Xojo provided iOS framework functionality, then you don&#8217;t need to do anything at all. When building or running the iOS app, Xojo will create and add the required PrivacyInfo.xcprivacy file for you.</p>



<p>If you are using Declare calls or rely on iOS third party libraries or plug-ins, then you should check with the developer to know if any of the calls made fall into the <a href="https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api?language=objc">Privacy Categories listed by Apple</a> (keep in mind that these can change over time). If so, then it is time to visit the new Privacy Editor available under the Build Settings &gt; iOS section, and click the Settings button in the associated Inspector Panel:</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="602" height="1410" src="https://blog.xojo.com/wp-content/uploads/2024/06/PrivacyEdit.png" alt="" class="wp-image-13173" srcset="https://blog.xojo.com/wp-content/uploads/2024/06/PrivacyEdit.png 602w, https://blog.xojo.com/wp-content/uploads/2024/06/PrivacyEdit-128x300.png 128w, https://blog.xojo.com/wp-content/uploads/2024/06/PrivacyEdit-437x1024.png 437w" sizes="auto, (max-width: 602px) 100vw, 602px" /></figure>
</div>


<p>Here you will find the Edit button under the Privacy section. Click on it to bring up the Privacy Editor window:</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1424" height="1080" src="https://blog.xojo.com/wp-content/uploads/2024/06/Editor.png" alt="" class="wp-image-13174" srcset="https://blog.xojo.com/wp-content/uploads/2024/06/Editor.png 1424w, https://blog.xojo.com/wp-content/uploads/2024/06/Editor-300x228.png 300w, https://blog.xojo.com/wp-content/uploads/2024/06/Editor-1024x777.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/06/Editor-768x582.png 768w" sizes="auto, (max-width: 1424px) 100vw, 1424px" /></figure>
</div>


<p>In the Privacy Editor window, select both the API Type from the entries available in the ComboBox control, plus the associated API Reasons that meet your specific requirements based on the API Type selection.</p>



<p>Of course, you will be able to add as many API Type cards as you may need using the &#8220;Add Type&#8221; button, or delete any of the previously added cards. If any of your iOS apps share the same Privacy settings, you can simplify the process by creating and saving files in the Privacy Editor. Now you can add those files to your other iOS apps from the Editor via the &#8220;Open…&#8221; button or by dragging &amp; dropping the file from its current location into the Editor itself.</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1504" height="1448" src="https://blog.xojo.com/wp-content/uploads/2024/06/PrivacyEntries.png" alt="" class="wp-image-13175" srcset="https://blog.xojo.com/wp-content/uploads/2024/06/PrivacyEntries.png 1504w, https://blog.xojo.com/wp-content/uploads/2024/06/PrivacyEntries-300x289.png 300w, https://blog.xojo.com/wp-content/uploads/2024/06/PrivacyEntries-1024x986.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/06/PrivacyEntries-768x739.png 768w" sizes="auto, (max-width: 1504px) 100vw, 1504px" /></figure>
</div>


<p>Once you finish editing the Privacy settings for the iOS project, the PrivacyInfo.xcprivacy file will be created and automatically added when building the iOS app, allowing you to run it the Simulator, any connected iOS device or send it to the AppStore review approval. Learn more about this in the <a href="https://documentation.xojo.com/versions/2024r2/topics/application_deployment/ios/meeting_apples_privacy_requirements.html">Xojo Documentation</a>. </p>



<p><em>Javier Menendez is an engineer at Xojo and has been using Xojo since 1998. He lives in Castellón</em>, <em>Spain and hosts regular Xojo hangouts en español. Ask Javier questions on Twitter at <a href="https://twitter.com/xojoes" target="_blank" rel="noreferrer noopener">@XojoES</a> or on the <a href="https://forum.xojo.com/u/javier_menendez/summary" target="_blank" rel="noreferrer noopener">Xojo Forum</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>WWDC 2024 for Xojo Users</title>
		<link>https://blog.xojo.com/2024/06/24/wwdc-2024-for-xojo-users/</link>
		
		<dc:creator><![CDATA[Gavin Smith]]></dc:creator>
		<pubDate>Mon, 24 Jun 2024 15:53:27 +0000</pubDate>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[WWDC]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13244</guid>

					<description><![CDATA[Last week, Xojo MVP Gavin Smith attended the WWDC 2024 event in Cupertino. He found the event uplifting and exciting, and I was able to talk with many people and share perspectives with them. Learn More.]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large is-style-default"><img loading="lazy" decoding="async" width="1024" height="768" src="https://blog.xojo.com/wp-content/uploads/2024/06/keynote-1024x768.jpeg" alt="" class="wp-image-13245" srcset="https://blog.xojo.com/wp-content/uploads/2024/06/keynote-1024x768.jpeg 1024w, https://blog.xojo.com/wp-content/uploads/2024/06/keynote-300x225.jpeg 300w, https://blog.xojo.com/wp-content/uploads/2024/06/keynote-768x576.jpeg 768w, https://blog.xojo.com/wp-content/uploads/2024/06/keynote-1536x1152.jpeg 1536w, https://blog.xojo.com/wp-content/uploads/2024/06/keynote-2048x1536.jpeg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Last week, I attended the WWDC 2024 event in Cupertino. It took place in both the original Infinite Loop campus, as well as the Apple Park “spaceship” campus which opened in 2017 and cost $5 billion to build. Apple’s WWDC events are no longer a traditional developer conference. The developer session videos are all uploaded for free, and even the keynote is a prerecorded, so event attendees see it at the same time as the rest of the world. Instead, this is more of a social event &#8211; an opportunity to meet fellow developers, bump into some famous people, and take advantage of Apple’s hospitality. I found the event uplifting and exciting, and I was able to talk with many people and share perspectives with them.&nbsp;</p>



<figure class="wp-block-image size-large is-style-default"><img loading="lazy" decoding="async" width="1024" height="768" src="https://blog.xojo.com/wp-content/uploads/2024/06/infiniteloop-1024x768.jpeg" alt="" class="wp-image-13246" srcset="https://blog.xojo.com/wp-content/uploads/2024/06/infiniteloop-1024x768.jpeg 1024w, https://blog.xojo.com/wp-content/uploads/2024/06/infiniteloop-300x225.jpeg 300w, https://blog.xojo.com/wp-content/uploads/2024/06/infiniteloop-768x576.jpeg 768w, https://blog.xojo.com/wp-content/uploads/2024/06/infiniteloop-1536x1152.jpeg 1536w, https://blog.xojo.com/wp-content/uploads/2024/06/infiniteloop-2048x1536.jpeg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Inside the Infinite Loop campus &#8211; rumors of a free bar may or may not be greatly exaggerated</p>



<figure class="wp-block-image size-large is-style-default"><img loading="lazy" decoding="async" width="1024" height="768" src="https://blog.xojo.com/wp-content/uploads/2024/06/applepark-1024x768.jpeg" alt="" class="wp-image-13247" srcset="https://blog.xojo.com/wp-content/uploads/2024/06/applepark-1024x768.jpeg 1024w, https://blog.xojo.com/wp-content/uploads/2024/06/applepark-300x225.jpeg 300w, https://blog.xojo.com/wp-content/uploads/2024/06/applepark-768x576.jpeg 768w, https://blog.xojo.com/wp-content/uploads/2024/06/applepark-1536x1152.jpeg 1536w, https://blog.xojo.com/wp-content/uploads/2024/06/applepark-2048x1536.jpeg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>The event was a great opportunity to share ideas and plans with other developers</p>



<p>Now, you might think that the event is solely for Swift developers, but this is not entirely true. Of course, Apple are constantly pitching their chosen language and frameworks at the event, but there is also a recognition that many people develop software for Apple platforms in tools other than Swift and Xcode. Of the people I spoke to, quite a number of people were using something other than Swift (including an Apple engineer!). Many of the sessions from WWDC are naturally catered towards Swift developers, but there are still some that will be useful to Xojo developers. I’ve highlighted a selection of videos below, along with my own description.</p>



<h2 class="wp-block-heading">I want more stuff</h2>



<p>When browsing WWDC videos, if you come across new functionality or an API that isn’t exposed in Xojo, the best course of action is to create a feature request at <a href="https://tracker.xojo.com">https://tracker.xojo.com</a>. But don’t stop there. Tell the community about your request on the forum and ask them to give the request a “thumbs up” if they agree. This helps the Xojo team gauge interest. For some requests, you may also want to rope in support from me or one of the other MVPs, so that we can potentially engage with the team directly on your behalf at one of our regular meetings.</p>



<p>At each WWDC, Apple releases beta versions of its new tools and operating systems. These are very early versions, especially at this point in the beta cycle, and should not be installed on your main machines without very good reason. Early anecdotal evidence suggestions few problems with Sequoia (the new version of macOS) and Xojo apps, but testing such software should be done in virtual machines or on machines that you don’t use for your daily coding. When Xojo support for the new OS and the new version of Xcode becomes official, the System Requirements page will be updated at <a href="https://documentation.xojo.com/resources/system_requirements_for_current_release.html?utm_term=&amp;utm_campaign=2024+PMax+DailyGreen+Sales&amp;utm_source=adwords&amp;utm_medium=ppc&amp;hsa_acc=9025323230&amp;hsa_cam=20990493106&amp;hsa_grp=&amp;hsa_ad=&amp;hsa_src=x&amp;hsa_tgt=&amp;hsa_kw=&amp;hsa_mt=&amp;hsa_net=adwords&amp;hsa_ver=3&amp;gad_source=1&amp;gclid=CjwKCAjwg8qzBhAoEiwAWagLrGLSWQQOBNOvtN7ovzQDsw1RtX4LRAJ5N-f6-qU4gbH1kv9OL03ZhxoCPHIQAvD_BwE">https://documentation.xojo.com/resources/system_requirements_for_current_release.html</a></p>



<h2 class="wp-block-heading">Highlighted WWDC 2024 videos</h2>



<p>“<a href="https://developer.apple.com/videos/play/wwdc2024/10063">What’s new in App Store Connect</a>”</p>



<p>Take better advantage of the App Store, get your app nominated for featuring and more.</p>



<p>“<a href="https://developer.apple.com/videos/play/wwdc2024/10140">Add personality to your app through UX writing</a>”</p>



<p>This is a quintessentially Apple presentation, but it may be thought provoking. What is the tone of your app? Does it matter for your market?</p>



<p>“<a href="https://developer.apple.com/videos/play/wwdc2024/10110">Implement App Store Offers</a>”</p>



<p>Self-explanatory from the title. Most of this will require the use of MBS plugins.</p>



<p>“<a href="https://developer.apple.com/videos/play/wwdc2024/111977">Platforms State of the Union 5-Minute Recap</a>”</p>



<p>The full State of the Union presentation, which follows the main keynote each WWDC, is rather lengthy and not required viewing for Xojo developers. But the five minute recap is worth watching to get an overview.</p>



<p>“<a href="https://developer.apple.com/videos/play/wwdc2024/10185">Build multilingual-ready apps</a>”</p>



<p>A lot of this video involves Swift code but there is still useful information for everyone in this.</p>



<p>Notes:&nbsp;</p>



<ul class="wp-block-list">
<li>Apple also have a “Expanding your app to new markets” document at <a href="https://developer.apple.com/localization/">https://developer.apple.com/localization/</a>. </li>



<li>To take advantage of much of this in your Xojo apps, see <a href="https://documentation.xojo.com/topics/localizing_your_apps/introduction_to_app_localization.html">https://documentation.xojo.com/topics/localizing_your_apps/introduction_to_app_localization.html</a></li>
</ul>



<p>“<a href="https://developer.apple.com/videos/play/wwdc2024/10188">What’s new in SF Symbols 6</a>”</p>



<p>SF Symbols (SF stands for San Francisco) is a library of thousands of clean and simple symbols for use in Apple platforms only. Apple typically updates this yearly.</p>



<p>Notes:</p>



<ul class="wp-block-list">
<li>To take advantage of SF Symbols in your iOS apps, use the Picture.SystemImage method. See the docs at https://documentation.xojo.com/api/graphics/picture.html#picture-systemimage</li>



<li>There is no built-in support for SF Symbols in Xojo Mac apps, but you can still take advantage of them. See this blog post for details: https://blog.xojo.com/2021/10/21/quicktip-using-sf-symbols-in-macos-revisited/</li>



<li>Tell Xojo that this support should really be built-in! Lend your support to this case; <a href="https://tracker.xojo.com/xojoinc/xojo/-/issues/60751">https://tracker.xojo.com/xojoinc/xojo/-/issues/60751</a></li>



<li>Whilst SF Symbols is Apple-only, there is also a library of images built into Xojo for Android developments, also using the Picture.SystemImage method.</li>



<li>Browse SF Symbols on your Mac (and get their names for use in Xojo) by downloading the SF Symbols utility from <a href="https://developer.apple.com/sf-symbols/">https://developer.apple.com/sf-symbols/</a></li>
</ul>



<h2 class="wp-block-heading">More videos</h2>



<p>Want to watch even more videos? (Shouldn’t you be coding?) Subscribe to the official Xojo YouTube channel and also see videos from the recent Monkeybread Software conference, including presentations from Xojo engineers and other MVPs. <a href="https://www.youtube.com/@MonkeybreadSoftware/videos">https://www.youtube.com/@MonkeybreadSoftware/videos</a></p>



<p><em>Gavin is a Xojo MVP and is based in the UK. He has been a Xojo developer since the first version in 1998.</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Over 20 years of native, cross-platform app development and still going strong</title>
		<link>https://blog.xojo.com/2023/09/06/over-20-years-of-native-cross-platform-app-development-and-still-going-strong/</link>
		
		<dc:creator><![CDATA[Xojo]]></dc:creator>
		<pubDate>Wed, 06 Sep 2023 21:32:28 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Fun]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[App Development]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Development Tools]]></category>
		<category><![CDATA[FileMaker]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Native App Development]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[VB]]></category>
		<category><![CDATA[VB Alternative]]></category>
		<category><![CDATA[VB for Mac]]></category>
		<category><![CDATA[Visual Studio]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=12012</guid>

					<description><![CDATA[The recent news about Microsoft discontinuing Visual Studio's support for Mac has got us talking about longevity in the field of software development. We all know technology changes rapidly and you, and the tools you use, can't afford to stand still. Here's an infographic that illustrates how Xojo's been continually updating and modernizing since 1996 while other development tools come and go.]]></description>
										<content:encoded><![CDATA[
<p>The recent news about Microsoft <a href="https://9to5mac.com/2023/08/30/microsoft-visual-studio-mac-discontinued/">discontinuing Visual Studio</a>&#8216;s support for Mac has got us talking about longevity in the field of software development. We all know technology changes rapidly and you, and the tools you use, can&#8217;t afford to stand still. </p>



<p>With this in mind, here&#8217;s an infographic that illustrates how Xojo&#8217;s been continually updating and modernizing since 1996 while other development tools come and go. </p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="410" height="1024" src="https://blog.xojo.com/wp-content/uploads/2023/08/FINAL-2023-black-edit-VS-ARM-edits-410x1024.jpg" alt="" class="wp-image-12014" srcset="https://blog.xojo.com/wp-content/uploads/2023/08/FINAL-2023-black-edit-VS-ARM-edits-410x1024.jpg 410w, https://blog.xojo.com/wp-content/uploads/2023/08/FINAL-2023-black-edit-VS-ARM-edits-120x300.jpg 120w, https://blog.xojo.com/wp-content/uploads/2023/08/FINAL-2023-black-edit-VS-ARM-edits-768x1920.jpg 768w, https://blog.xojo.com/wp-content/uploads/2023/08/FINAL-2023-black-edit-VS-ARM-edits.jpg 800w" sizes="auto, (max-width: 410px) 100vw, 410px" /></figure>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Microsoft’s Visual Studio for Mac Discontinued; Is it really safer to buy from a big name?</title>
		<link>https://blog.xojo.com/2023/08/31/microsofts-visual-studio-for-mac-discontinued-is-it-really-safer-to-buy-from-a-big-name/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Thu, 31 Aug 2023 16:02:00 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Native App Development]]></category>
		<category><![CDATA[RAD]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[VB Alternative]]></category>
		<category><![CDATA[VB for Mac]]></category>
		<category><![CDATA[Visual Studio]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=11991</guid>

					<description><![CDATA[Microsoft recently announced that they are discontinuing Visual Studio for Mac, which was only just introduced in 2016. So how "safe" is relying on a big company for your development tool, really? If you are an enterprise company with a large investment in software and IT, you might want to take a look outside the big names and see what Xojo can offer. Xojo makes it quicker and easier to try out software ideas before you commit expensive development resources to your primary tools. And we've been dong it since 1998, with a focus on native, cross-platform development.]]></description>
										<content:encoded><![CDATA[
<p>Back in the 80’s, &#8220;Nobody gets fired for buying IBM&#8221; was a saying that went around when discussing what computer to buy. In general it means: It’s safe to buy from a Big Name. But is it?</p>



<figure class="wp-block-image size-full is-resized"><img loading="lazy" decoding="async" src="https://blog.xojo.com/wp-content/uploads/2023/08/image.png" alt="" class="wp-image-11992" style="width:311px;height:208px" width="311" height="208" srcset="https://blog.xojo.com/wp-content/uploads/2023/08/image.png 606w, https://blog.xojo.com/wp-content/uploads/2023/08/image-300x200.png 300w" sizes="auto, (max-width: 311px) 100vw, 311px" /></figure>



<p>You still hear this same argument today in the software development world, where the big names are Microsoft, Apple and Google.</p>



<p>But how &#8220;safe&#8221; is their stuff, really? After all, they all seem to end support for products and tools rather often.</p>



<p>Microsoft recently announced that they are <a href="https://devblogs.microsoft.com/visualstudio/visual-studio-for-mac-retirement-announcement/">discontinuing Visual Studio for Mac</a>, which was only just introduced in 2016. Last I checked, Microsoft is a Very. Big. Company. Yet they somehow cannot justify resources to keep a Mac IDE viable. Clearly, they have the resources so this is a decision about Microsoft&#8217;s focus and priorities, things that Big Companies change all the time.</p>



<p>Google drops products (or drastically changes them) often. Changing their “free for life” Google Apps (G Suite) product to a <a href="https://arstechnica.com/gadgets/2022/01/google-tells-free-g-suite-users-pay-up-or-lose-your-account/" data-type="link" data-id="https://arstechnica.com/gadgets/2022/01/google-tells-free-g-suite-users-pay-up-or-lose-your-account/">rather expensive monthly cost was not popular with many businesses</a>.</p>



<p>Apple killed off iBooks Author, and although it was not a development tool, it was something that was heavily promoted for a while as the best way to make content for the iBooks Store. In the development world, Apple killed off their Carbon OS framework in favor of Cocoa after years of telling developers the two would co-exist.</p>



<p>In the 2000s before working here at Xojo, I did a lot of consulting (frequently migrating VB6 apps to Xojo) and one question that was often asked of me is “why should I go with a dev tool from a small company like Xojo instead of something from a big name like Microsoft?”.</p>



<p>The answer I always gave at the time was: “You’re coming to me to migrate a VB6 app. VB6 was from Microsoft and they killed the product off. Big companies do that all the time. A small company like Xojo focuses entirely on their product. It gets all their attention. If you had picked Xojo in 1999 instead of VB6, we would not be having this conversation right now.”</p>



<p>To that end, Xojo has been around since 1998 and has outlived many other development tools and platforms. Some of which come to mind are: Visual Basic 6, Metrowerks CodeWarrior, and (now) Microsoft Visual Studio for Mac.</p>



<p>Technologies are also regularly discontinued by the creators in favor of newer versions. It took years for the Python community to move from Python 2 to Python 3. But when Apple finally removed Python 2 from macOS last year, there were many apps and companies that had to scramble to update their code. PHP8 was release in 2020, but as of today <a href="https://w3techs.com/technologies/details/pl-php/8#:~:text=PHP%20version%208%20is%20used,77.3%25%20of%20all%20the%20websites.">adoption is only about 12%</a>. In 2017, Google switched from Java to Kotlin as the official language of Android, impacting many. Apple promotes Swift and Swift UI over Objective-C and AppKit these days. They introduced Catalyst, but it appears to not be making much headway. Microsoft pushes out new frameworks at a rapid pace, which is exciting, but can be difficult for a development team to know what to pick.</p>



<p>I don&#8217;t bring these things up to point out mistakes. Change is inevitable in technology after all. I only bring these up to point out that, even with the big names, there are still risks.</p>



<p>All this is to say that if you are an enterprise company with a large investment in software and IT, you might want to take a look outside the big names and see what Xojo can offer. I realize that if you have standardized on a set of tools from a large vendor, say C# and Microsoft, you are probably thinking “there’s no way I&#8217;m switching to Xojo no matter what this guy says”.</p>



<p>We at Xojo agree. You probably should not be switching everything over to Xojo. That would be insanely expensive and risky. But Xojo can be a great complement to the tools you already use. Professional software developers (and their companies) keep lots of tools in their toolbox and Xojo should be one of those tools.</p>



<h4 class="wp-block-heading" id="Xojo4U">So what can Xojo do for you? </h4>



<p>Xojo’s goal is to make programming easier, allowing you to get software made faster. Xojo saves you time and money. To that end, in enterprise environments Xojo is great for:</p>



<ul class="wp-block-list">
<li>Prototypes and proof-of-concepts</li>



<li>Internal tools and utilities</li>



<li>Testing</li>



<li>Demos</li>
</ul>



<p>With Xojo you can quickly build a desktop app (for mac, Windows or Linux) to test out REST APIs. You can build a web app to demonstrate some UI concepts or easily distribute information. You can build a mobile app (iOS or Android) to quickly try out ideas. Xojo lets you do All The Things without having to deal with a bunch of different complex tools and technologies. <strong>Xojo can give you the speed and power of low-code tools without all the limitations.</strong></p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" src="https://blog.xojo.com/wp-content/uploads/2023/08/image-2-1024x1014.png" alt="" class="wp-image-11996" style="width:616px;height:610px" width="616" height="610" srcset="https://blog.xojo.com/wp-content/uploads/2023/08/image-2-1024x1014.png 1024w, https://blog.xojo.com/wp-content/uploads/2023/08/image-2-300x297.png 300w, https://blog.xojo.com/wp-content/uploads/2023/08/image-2-150x150.png 150w, https://blog.xojo.com/wp-content/uploads/2023/08/image-2-768x761.png 768w, https://blog.xojo.com/wp-content/uploads/2023/08/image-2.png 1458w" sizes="auto, (max-width: 616px) 100vw, 616px" /></figure>



<p>Xojo makes it quicker and easier to try out software ideas before you commit expensive development resources to your primary tools. A company&#8217;s biggest expense is usually salary and using an expensive IT department to slowly build everything is not a great value. You spend too much money on salary and sacrifice too much time on lost opportunities. Using Xojo instead can save you significant money that you can put towards the projects you determine are viable and worth more investment.</p>



<p>And don’t forget about internal tools. Every company needs internal tools of some kind and these won&#8217;t generate revenue on their own. Forcing these tools to go through an overworked IT department is slow and expensive. But not building them at all means your staff is less productive than they could be. Your advanced power users can use Xojo to create tools that will improve productivity at a fraction of the cost and avoid lost opportunities waiting for IT.</p>



<p>Like Apple, Google and Microsoft, Xojo isn&#8217;t perfect. We’ve made our share of mistakes, such as our transition from Web 1.0 to Web 2.0 which was not as smooth as we had hoped it would be. <a href="https://www.xojo.com/company/team.php" data-type="link" data-id="https://www.xojo.com/company/team.php">The team</a> is only human, but we do our best to learn from mistakes and if nothing else we are perseverant and committed to always making Xojo better. The fact that we&#8217;ve been doing this since 1998 is a testament to that.</p>



<p>So join the many other enterprise customers that use Xojo as a secret weapon! You might find you like using a development tool from a small company that cares about its product and its customers.</p>



<p>You can <a href="https://www.xojo.com/download/" data-type="link" data-id="https://www.xojo.com/download/">try Xojo for free today</a>. Licensing is available for <a href="https://www.xojo.com/store/" data-type="link" data-id="https://www.xojo.com/store/">as low as $399 per user</a> (even lower when purchased in bulk). Contact us at <a href="mailto:hello@xojo.com">hello@xojo.com</a> for more information or to get a quote.</p>



<p><em>Paul learned to program in BASIC at age 13 and has programmed in more languages than he remembers, with Xojo being an obvious favorite. When not working on Xojo, you can find him talking about retrocomputing at <a href="https://goto10.substack.com" target="_blank" rel="noreferrer noopener">Goto 10</a> and </em>on Mastodon @lefebvre@hachyderm.io.</p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Xojo and Apple Vision Pro</title>
		<link>https://blog.xojo.com/2023/06/22/xojo-and-apple-vision-pro/</link>
		
		<dc:creator><![CDATA[Geoff Perlman]]></dc:creator>
		<pubDate>Thu, 22 Jun 2023 17:18:28 +0000</pubDate>
				<category><![CDATA[Fun]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=11647</guid>

					<description><![CDATA[Apple has released the developer documentation for Vision Pro, their recently announced mixed reality headset. So far, it looks promising that iOS apps written in Xojo will just work. Of course, we don't yet have one of these to use for testing. If we did, we'd be too busy playing with it to write this blog post, however we have tried running some Xojo iOS projects in the Vision Pro Simulator and they work without modification so that's a very good sign.]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" src="https://blog.xojo.com/wp-content/uploads/2023/06/CleanShot-2023-06-22-at-08.15.30@2x-1024x572.png" alt="" class="wp-image-11651" width="425" height="237" srcset="https://blog.xojo.com/wp-content/uploads/2023/06/CleanShot-2023-06-22-at-08.15.30@2x-1024x572.png 1024w, https://blog.xojo.com/wp-content/uploads/2023/06/CleanShot-2023-06-22-at-08.15.30@2x-300x168.png 300w, https://blog.xojo.com/wp-content/uploads/2023/06/CleanShot-2023-06-22-at-08.15.30@2x-768x429.png 768w, https://blog.xojo.com/wp-content/uploads/2023/06/CleanShot-2023-06-22-at-08.15.30@2x.png 1224w" sizes="auto, (max-width: 425px) 100vw, 425px" /></figure>



<p>Apple has released the <a href="https://developer.apple.com/documentation/visionos/checking-whether-your-app-is-compatible-with-visionos/">developer documentation</a> for <a href="https://www.apple.com/apple-vision-pro/?afid=p238%7CbDSl8o9e-dc_mtid_20925qtb42335_pcrid_77653214969036_pgrid_1242449430563648_&amp;cid=wwa-us-kwbi-VisionPro-slid---Brand-AppleVision-Announce-">Vision Pro</a>, their recently announced mixed reality headset. So far, it looks promising that iOS apps written in Xojo will just work. Of course, we don&#8217;t yet have one of these to use for testing. If we did, we&#8217;d be too busy playing with it to write this blog post, however we have tried running some Xojo iOS projects in the Vision Pro Simulator and they work without modification so that&#8217;s a very good sign.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="768" src="https://blog.xojo.com/wp-content/uploads/2023/06/xojo_app_visionpro-1024x768.jpg" alt="" class="wp-image-11655" srcset="https://blog.xojo.com/wp-content/uploads/2023/06/xojo_app_visionpro-1024x768.jpg 1024w, https://blog.xojo.com/wp-content/uploads/2023/06/xojo_app_visionpro-300x225.jpg 300w, https://blog.xojo.com/wp-content/uploads/2023/06/xojo_app_visionpro-768x576.jpg 768w, https://blog.xojo.com/wp-content/uploads/2023/06/xojo_app_visionpro-1536x1151.jpg 1536w, https://blog.xojo.com/wp-content/uploads/2023/06/xojo_app_visionpro-2048x1535.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Moving Forward &#038; Giving Back: iOS and macOS Products from Greg O&#8217;Lone</title>
		<link>https://blog.xojo.com/2023/06/15/moving-forward-giving-back-ios-and-macos-products-from-greg-olone/</link>
		
		<dc:creator><![CDATA[Xojo]]></dc:creator>
		<pubDate>Thu, 15 Jun 2023 15:35:24 +0000</pubDate>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Declares]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=11639</guid>

					<description><![CDATA[My new path has taken me deep into the world of iOS and macOS and I thought I would create some projects &#038; products which would benefit Xojo apps on those platforms by creating some products which expose some of the larger frameworks which are not already available but also cannot be accessed by declares alone...]]></description>
										<content:encoded><![CDATA[
<p>As many of you know, I was a Xojo engineer for eleven years until early 2022 when I decided to take my career in a new direction. My time at Xojo was exciting and innovative, it gave me a chance to exercise my creativity and love for creating new things and an opportunity to work with some of the most talented people I had ever known.</p>



<p>My new path has taken me deep into the world of iOS and macOS and I thought I would create some projects &amp; products which would benefit Xojo apps on those platforms by creating some products which expose some of the larger frameworks which are not already available but also cannot be accessed by declares alone&#8230;</p>



<h3 class="wp-block-heading" id="weatherkit">WeatherKit</h3>



<p>About the time that Apple ended support for the Dark Sky API, forcing users to transition to their WeatherKit Rest API, I was thinking about an iOS project which would benefit from having access to the phases of the moon and barometric pressure on a historical basis. After a bit of research, I found that Apple&#8217;s WeatherKit framework was well-suited for the purpose, but found that it was a Swift-only framework and accessing it from Xojo was going to be challenging. I proceeded to create an obj-c bridge framework and a set of Xojo classes to make it available to everyone.</p>



<p>What resulted is a framework which currently provides developers access to the WeatherKit framework as well as some helper tools for:</p>



<ul class="wp-block-list">
<li>Location Geocoding, because WeatherKit requires Latitude/Longitude and humans don&#8217;t remember locations that way.</li>



<li>Unit Conversion, for the units that are used in WeatherKit.</li>



<li>Multicolor Symbols, for a quick and easy way to access the multicolor SFSymbols which are provided by Apple for weather.</li>
</ul>



<p>You can read more information about this framework and download a demo from <a href="https://www.stretchedout.com/yaxew/products/weatherkit.html">here</a>, and it can be purchased from Xojo&#8217;s <a href="https://xojo.com/store/addons/weatherkit.php">Extras Store</a>.</p>



<h3 class="wp-block-heading" id="multipeer-connectivity">Multipeer Connectivity</h3>



<p>Another framework which caught my eye was MultipeerConnectivity. This framework allows you to make connections with up to 8 macOS and/or iOS devices simultaneously for use in games or business applications with multiple communicating workstations. It offers both automatic user-driven and manual programmatic device discovery as well as a few data transfer mechanisms. macOS devices use Wi-Fi and/or Ethernet and iOS devices use Wi-Fi and/or Bluetooth. Network selection is completely automatic so once the connection has been established, all your app needs to do is send data back and forth and disconnect when it&#8217;s done.</p>



<p>My port of the framework gives you access to nearly the whole framework, short of creating a direct socket connection between two devices, but text and file transfers are both implemented and working just fine. I was even able to transfer a 130MB file from a Mac to an iPhone in about 16 seconds.</p>



<p>You can read more information about this framework and download a demo from <a href="https://www.stretchedout.com/yaxew/products/multipeer.html">here</a>, and it can be purchased from Xojo&#8217;s <a href="https://xojo.com/store/addons/stretchedout.php">Extras Store</a>.</p>



<h3 class="wp-block-heading" id="free-stuff">Free Stuff</h3>



<p>I also have several Github repos and a number of free xojo-related items available, including my Profile Triage tool for helping developers figure out why they get errors when trying to sign or notarize their apps. You can see that list on my site <a href="https://www.stretchedout.com/yaxew/index.html#freestuff">here</a>.</p>



<h3 class="wp-block-heading" id="more-on-the-horizon">More on the horizon&#8230;</h3>



<p>There&#8217;s more to come. I have some other products which I think will benefit Xojo iOS and macOS projects in the future, so watch for posts on the Xojo forum!</p>



<p><em>Greg O&#8217;Lone spent eleven years as a member of the Xojo engineering team from 2011 through 2022. During his time at Xojo he worked on many of the parts of the product that make Xojo what it is today &#8211; from the IDE and iOS Framework to Xojo Cloud and both of the Web Frameworks.</em> You can learn more about Greg and what he&#8217;s creating now at <a href="https://www.stretchedout.com/yaxew/about.html">his website</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The Versatility of Xojo</title>
		<link>https://blog.xojo.com/2022/12/06/the-versatility-of-xojo/</link>
		
		<dc:creator><![CDATA[Jérémie Leroy]]></dc:creator>
		<pubDate>Tue, 06 Dec 2022 16:49:04 +0000</pubDate>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[App Hosting]]></category>
		<category><![CDATA[App Localization]]></category>
		<category><![CDATA[App Store]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[GraffitiSuite]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Trello]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=11006</guid>

					<description><![CDATA[Many people around the world are celebrating the holidays by giving gifts, which means more and more people are organizing Secret Santa events. In November of 2018, Jérémie Leroy had the idea of making a Secret Santa iOS app. 3 years, 32 languages and 6.5 millions downloads later, Jérémie incorporated Xojo Web to improve his highly successful Xojo iOS app. Secret Santa is a prime example of what is possible and how you can leverage your Xojo skills to expand to other platforms when you need to.]]></description>
										<content:encoded><![CDATA[
<p>It is soon time for the end of year festivities. Many people around the world are celebrating the holidays by giving gifts, which means more and more people are organizing Secret Santa events. During these events, members of a group of friends, family, or colleagues will draw names to become someone’s Secret Santa and then give them a holiday gift, usually something fun.</p>



<figure class="wp-block-table aligncenter"><table><tbody><tr><td class="has-text-align-left" data-align="left"><strong>Did you know?</strong></td></tr><tr><td class="has-text-align-left" data-align="left">Secret Santa is known by different names around the world, such as “Amigo Invisible” in Spanish, “Amigo Secreto” in Portuguese, “Тайный Санта” in Russian.</td></tr></tbody></table></figure>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:66.66%">
<p>I first made a desktop Secret Santa app back in 2015 for an event with friends. We were tired of drawing names out of a hat and having couples being paired together. The app I created solved that problem because couples were excluded from offering a gift to each other. And we didn’t need a hat!</p>



<p>In November of 2018, I had the idea of making a <a href="https://apps.apple.com/app/apple-store/id1442673273?pt=118403140&amp;ct=XojoBlog&amp;mt=8">Secret Santa iOS app</a> so that anyone with an iPhone or iPad could benefit from the same features I had been enjoying for the past 3 years.</p>



<p>The app would need to be easy to use, avoid couples getting matched with each other, send notifications by email without letting the organizer know which pairs were matched, and of course make sure no name would be assigned twice.</p>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.33%"><div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><a href="https://apps.apple.com/app/apple-store/id1442673273?pt=118403140&amp;ct=XojoBlog&amp;mt=8"><img loading="lazy" decoding="async" src="https://blog.xojo.com/wp-content/uploads/2022/12/Screen-Shot-2022-12-06-at-9.12.28-AM.png" alt="" class="wp-image-11009" width="168" height="352" srcset="https://blog.xojo.com/wp-content/uploads/2022/12/Screen-Shot-2022-12-06-at-9.12.28-AM.png 304w, https://blog.xojo.com/wp-content/uploads/2022/12/Screen-Shot-2022-12-06-at-9.12.28-AM-143x300.png 143w" sizes="auto, (max-width: 168px) 100vw, 168px" /></a></figure>
</div></div>
</div>



<p>After just 8 days of development, the app was ready to ship and sent to the App Store.</p>



<p>Within 5 days, the app had been downloaded from 35 different countries and was my fastest app to reach 1000 downloads!</p>


<div class="wp-block-image">
<figure class="aligncenter is-resized"><img decoding="async" src="https://lh6.googleusercontent.com/U-yY3aE161mfhU3H6k9ODFP4LtuwzFNWzRrvUdRIvs3cLeHG2sydLIDWL1Ic65Lnw9rJvRQ8mGn82ComNHKq2s-pDWIJoGimmA5082pg_IDuI1KCwX9U82FGIkTSFev4LRYR20Tc8Tkgfn9UlL18C2cAraTTFzJKR4Np5fDCtqwc8jDcjeP1D4e2-mPSBg" alt="" width="-43" height="-22"/></figure>
</div>


<p><a href="https://apps.apple.com/app/apple-store/id1442673273?pt=118403140&amp;ct=XojoBlog&amp;mt=8"></a></p>



<p>Having the app translated to English, French, Italian, and Spanish in the initial release helped to reach more users.</p>



<p>Version 1.1 of the app was released a few days later with German and Portuguese translations.</p>



<p>That’s when I realized that Secret Santa is something extremely common in Latin America. Many families draw names for Christmas so that they can give and receive one big gift instead of smaller trivial gifts for each family member.</p>



<p>Most updates of the app came with new localizations, which really helped in realizing more and more downloads. After 3 years of updates, the app is now available in 32 languages.</p>


<div class="wp-block-image">
<figure class="aligncenter is-resized"><img loading="lazy" decoding="async" src="https://lh5.googleusercontent.com/DJt7zuBJxMbga7qB9LWyTwy-ZwnBYIBS4XbqTmOsuBh25vtv3UN1THXY32Z55sxG0arqCOpyKo1ttUT1q7iY5Z0Y1I9XhT8lbv6C_FPMsLPuhAiZ3q0AIdH9RUhBEGiXP4ft3aGzqAyiND3qk7bH4OSXuXNo3jRc4BPFhDmtT5kHLF2w3cgO66QPT6BctQ" alt="" width="895" height="635"/></figure>
</div>


<p>A high quantity of downloads also meant that I received a lot of feedback from users. Many users were happy with the current features, but I started getting feature requests to send the gift pairs by SMS or WhatsApp instead of by email. We all have a parent or grand-parent who isn’t tech-savvy and doesn’t have an email address.</p>



<h2 class="wp-block-heading"><strong>Leveraging the biggest advantage of Xojo &#8211; Sharing code across platforms</strong></h2>



<p>From 2018 until 2022, I had become used to updating the Secret Santa app itself to add new features and new translations while also fixing bugs. This year, I received a message from an unhappy user stating that they really need a wishlist feature and downloaded my app thinking it already had one.</p>



<p>A valid wishlist feature needed to be accessible to anyone with an Internet connection, whether they used a computer, an iPhone, or an Android device.</p>



<p>Using Xojo Web and a coding language I already knew was the obvious choice for this task. Sharing important bits of code from my main iOS project to the web wishlist project was as easy as copy and paste.</p>



<p>As with any Xojo project, copying classes from one project to the other was a real time saver, especially for the API layer required to communicate between Xojo and the online database that holds all the Secret Santa data.</p>



<p>The main difficulty working on a web project came from the UI. Not that Xojo Web’s UI is difficult, but I am so used to designing mobile apps that my brain didn&#8217;t know where to start.</p>



<p>I knew I wanted to display two columns of data:</p>



<ul class="wp-block-list"><li>The user’s wishlist</li><li>The wishlist from the person they are offering a gift to</li></ul>



<p>The layout had to be responsive to be accessible on both mobile and desktop devices.</p>



<p><a href="https://graffitisuite.com">Graffitisuite</a> from Anthony Cyphers came to mind, and within a few minutes of reviewing the online demo, I was convinced to use GraffitiKanban web control. I am a big fan of <a href="https://trello.com">Trello</a> for organizing my work, displaying cards in labeled columns. That&#8217;s exactly what I needed for the wishlist feature.</p>



<p>GraffitiKanban is “responsive” (Web Design term), meaning the display changes to adapt to smaller screens such as mobile devices.</p>



<p>GraffitiSuite also offers a wide variety of UI elements that made me save a lot of time.</p>



<p>7 days after the initial feature request, the wishlist feature was available to all.</p>



<p><strong>Wishlist on a desktop browser:</strong></p>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://lh3.googleusercontent.com/idkQ031bZaWEyP1Pj4BULLGJRc-Xz95sl4xlCkYD2KZt1IsMKOvsoP9ywwY5f81wwykuMuWqofDIelJNIiwE0j0IcF93ZXyaXFBmVK991oigNXPmi7W6BR1_b44sWWWKkYO7jAXVbjDC6Io4RVwhVveV8oM4Nu1UOPMXzrcxPL-VtdgVNB3bQ58MtolkmQ" alt=""/></figure>
</div>


<p><strong>Wishlist on a mobile browser:</strong></p>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://lh6.googleusercontent.com/9KZB2JwTAt2cLXTb7Es_G2Qdwldmfa1nMRmS7F2s9Pb2iVuz0e4M5Zj_8XfUn97QTUvU-78i8cDq5JZOrMwr-ROe0ihov1R2YDZSVseEky4KwTATMxU2tQHD6TXQpouL37NXEryK86JjTv36A-N-VHSqCXKXYza6M2V8WyWmP7Wie5kY_0GuMaOeixI0" alt=""/></figure>
</div>


<p>Deploying the app to <a href="https://www.xojo.com/cloud">Xojo Cloud</a> was extremely easy.</p>



<p>A single button press in Xojo, a subdomain DNS record, 2 minutes of configuration in Cloudflare, and the web app was up, running, and accessible through HTTPS.</p>



<figure class="wp-block-image"><img decoding="async" src="https://lh6.googleusercontent.com/o76SHsHWThArJFy__WCn9HW8rgFJ2Q0lJqq12o3ReAXRszlJe5VESNgYThKLfHtsU2hfOHrm5IbBVOOjCf4n6hjdUaYMZM0vjhfHGOsVmQkugEHbHHInjG29mDEpOk4-Ef8sg98ZTZp1esNIU4JM1jQ4qTZSdxLcrY_YKlOUKCW2_lWqV84NTyp-vvnnJQ" alt=""/></figure>



<p>Customer use of the wishlist feature has blown-up more than I ever would have expected. So far 30,000 gift ideas have been added to the wishlist (and counting).</p>



<h2 class="wp-block-heading"><strong>The next feature request</strong></h2>



<p>With an app that sees 60,000 new users per month, I receive a lot of feature requests. Most recently, I received a one star review on the app store because my app isn&#8217;t accessible to the Visually Impared. When VoiceOver is activated, all it says is “button”, “button”, “button”, with no explanation.</p>



<p>Adding voice-over capabilities in Xojo is simple. The <a href="https://documentation.xojo.com/api/user_interface/mobile/mobileuicontrol.html#mobileuicontrol">MobileUIControl</a> class has two String properties, AccessibilityHint and AccessibilityLabel.</p>



<p>But it actually is a lengthy task to check each control on each screen and make sure that the translations are correct.</p>



<p>VoiceOver support will soon be released in English and French, but all other localizations will be only ready next year. It is currently a bad time to get 30 different translators to work on the project under such short notice.</p>



<p>Xojo has enabled me to create a business out of developing iOS apps for the App Store. Including all of my apps, I have had over 6.5 million downloads and counting. Secret Santa is a prime example of what is possible and how you can leverage your Xojo skills to expand to other platforms when you need to. I look forward to what’s to come and will be at <a href="https://www.xojo.com/xdc">XDC London</a> to learn more about the future.</p>



<p>If you are organizing a Secret Santa event or just curious to see the app, download Secret Santa on the <a href="https://apps.apple.com/app/apple-store/id1442673273?pt=118403140&amp;ct=XojoBlog&amp;mt=8">App Store.</a></p>



<p><em>Jérémie Leroy has been using Xojo since 2008, he won two Xojo Design Awards in the iOS App category and has released over 13 iOS apps made with Xojo on the App Store. He also released </em><a href="https://github.com/jkleroy/iOSDesignExtensions"><em>iOSDesignExtensions</em></a><em> on Github to help style and polish your Xojo made iOS apps.</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>My Thoughts on the WWDC 2022 Keynote</title>
		<link>https://blog.xojo.com/2022/06/06/my-thoughts-on-the-wwdc-2022-keynote/</link>
		
		<dc:creator><![CDATA[Geoff Perlman]]></dc:creator>
		<pubDate>Mon, 06 Jun 2022 21:45:33 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[WWDC]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=10460</guid>

					<description><![CDATA[I've learned over the years not to have any specific expectations from Apple's WWDC keynote. Some years they introduce something big and new that we were pretty much expecting. Other years they blindside us. As the CEO of a company that creates tools for building apps for most of Apple's ecosystem and given Apple's history of secrecy, I'm understandably curious just how blindsided I might be each June. Fortunately, this year's keynote was filled with features that ranged from mildly interesting to really awesome but all incremental improvements across Apple's software line.]]></description>
										<content:encoded><![CDATA[
<p>I&#8217;ve learned over the years not to have any specific expectations from Apple&#8217;s WWDC keynote. Some years they introduce something big and new that we were pretty much expecting. Other years they blindside us. As the CEO of a company that creates tools for building apps for most of Apple&#8217;s ecosystem and given Apple&#8217;s history of secrecy, I&#8217;m understandably curious just how blindsided I might be each June. Fortunately, this year&#8217;s keynote was filled with features that ranged from mildly interesting to really awesome but all incremental improvements across Apple&#8217;s software line.</p>



<p>There&#8217;s a lot of neat new features coming in<strong> </strong>iOS 16. The kinds of customizations Apple is adding to the Lock Screen are quite nice both aesthetically and practically. While I&#8217;m personally not prone to sending text messages I later regret, being able to edit messages and more importantly unsend them, is going to save many relationships. That you can easily switch between dictation and the keyboard means I will probably use dictation a lot more than I have in the past. I have a friend that uses it constantly and I can&#8217;t tell you how many times a second text message arrives to explain the incomprehensible message that had arrived moments earlier. That it now adds punctuation will make me want to use it more as dictating punctuation has always felt awkward to me. It will however likely infuriate my kids who think punctuation in text messages is rude. That ApplePay is going to have integrated order tracking is really nice. I have been using an app for that and sadly quite recently several of the companies it allows you to track have dramatically reduced the functionality of their APIs making the app almost useless. That you will be able to easily share photos amongst family members via an iCloud Shared Photo Library is a feature my family will definitely be using. It&#8217;s very cool that you can have it automatically share photos that were taken when family members were close by or when they are in the photo itself. It&#8217;s a very nice use of Apple Neural Engine.</p>



<p>That Apple announcing a feature to help people escaping abuse says a lot about what they value and how important privacy is to one’s personal safety. It goes right along with features they have added in the past that allow you to reach into your pocket and dial 911 should you need to do that in secret. I&#8217;m big into making my home smarter so I was happy to see the Home app getting a facelift as well as Apple working with other companies on smart home interoperability. I&#8217;m also a huge fan of CarPlay and seeing Apple&#8217;s vision for it becoming nearly the entire way in which you interact with displays and controls in your car and being able to customize that to your liking was far more than I had ever thought would happen. That future is clearly years away because it requires a lot of cooperation with the automakers but as they adopt it, it will certainly sway my future car purchases.</p>



<p>I wear an Apple Watch and very much care about the quality of my sleep. That they have added the ability to see your REM, core and deep sleep cycles is very cool. I will definitely be wearing my watch to bed more often as a result. They are adding a medication reminder system which I can see as being a benefit. I only take one pill a day so it&#8217;s not something I would use but my wife takes several and on her busy days sometimes forgets to take them so it&#8217;s a feature she will definitely use.</p>



<p>The M2 was something I was fully expecting and it&#8217;s nice to see it incrementally getting better. Apple made it clear that performance per watt is the key metric for them and that makes a lot of sense. We need that kind of metric in many other places in society so that we better understand the impact we are having on each other and our planet.</p>



<p>The surprise feature in macOS Ventura was Stage Manager. it makes it easy to avoid the clutter of having a lot of windows open. I wasn&#8217;t expecting it and yet I&#8217;m sure I will use it. Like Messages, Mail is getting an unsend feature and lots of other nice improvements especially to search (which has always felt weak to me) but I&#8217;ll have to test it to know just how much it has improved. Passkeys is Apple&#8217;s name for their implementation of the <a href="https://fidoalliance.org/apple-google-and-microsoft-commit-to-expanded-support-for-fido-standard-to-accelerate-availability-of-passwordless-sign-ins/">Fido</a> standard they are collaborating on with Google and Microsoft. It&#8217;s designed to get rid of passwords entirely, something of which I will definitely be an early adopter. They really have thought that one through. It will make all of our devices and data far more secure. Being able to use FaceTime with Handoff will be really nice. I&#8217;ve been on a FaceTime call and then hung up to call someone back from my Mac so it will be nice to be able to just transfer it from one device to another.</p>



<p>The new MacBook Air is a nice incremental upgrade. If you have an Intel-based MacBook Air, this is a good time to upgrade.</p>



<p>iPadOS 16<strong> </strong>is bringing some more desktop-like features to iPad. Things like standard ways for accessing documents, renaming them, collaboration, etc., all make iPad feel a little more like a desktop without it being a desktop. It feels like Apple is striking the right balance. They also previewed a new app called Freeform which is essentially a digital whiteboard that you can use to collaborate with others. Though now that I say that, it seems to not really do it justice given that you can share so many different things in a common space, from text, drawings, photos, video and more. It would be great for brainstorming with a remote team.</p>



<p>Overall, this keynote demonstrated a lot of incremental improvements across the software side of the product line and that&#8217;s a good thing. We all want something big, new and flashy but those often come at the cost of a lot fewer incremental improvements. I&#8217;m actually quite happy that we weren&#8217;t blindsided by something that could potentially change our short term plans here at Xojo. I look forward to using many of the new features they are adding this year.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>On-Device iOS Debugging in Xojo</title>
		<link>https://blog.xojo.com/2022/04/05/on-device-ios-debugging-in-xojo/</link>
		
		<dc:creator><![CDATA[Greg O'Lone]]></dc:creator>
		<pubDate>Tue, 05 Apr 2022 13:30:00 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=10008</guid>

					<description><![CDATA[You may or may not be aware that running iOS projects in the Simulator does not allow you to check all of your app's features. There are a few features which rely on hardware capabilities which the Simulator cannot emulate. This can make it hard to track down bugs, and the only recourse is console logging. Starting in Xojo 2022r1 it's possible to run your apps right on a physical device connected by USB.]]></description>
										<content:encoded><![CDATA[
<p>You may or may not be aware that running <a href="https://documentation.xojo.com/topics/debugging/testing_and_debugging_your_ios_apps.html#running-your-app-in-the-ios-simulator">iOS projects in the Simulator </a>does not allow you to check all of your app&#8217;s features. There are a few features which rely on hardware capabilities which the Simulator cannot emulate. This can make it hard to track down bugs, and the only recourse is console logging. Starting in Xojo 2022r1 it&#8217;s possible to <a href="https://documentation.xojo.com/topics/debugging/testing_and_debugging_your_ios_apps.html#running-your-app-on-device">run your apps right on a physical device</a> connected by USB. Learn how in this post.</p>



<h2 class="wp-block-heading" id="setup">Setup</h2>



<p>Debugging on device requires your device be connected to your computer using a lightning cable.</p>



<p><strong>Computer</strong><br>You&#8217;ll need to launch Xcode, plug your phone in using USB and open Xcode&#8217;s Devices and Simulators window. In the navigation pane on the left, select the device and check the Show as run destination<strong> </strong>checkbox<strong>.</strong> </p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="233" src="https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-30-at-14.14.20@2x-1024x233.png" alt="" class="wp-image-10252" srcset="https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-30-at-14.14.20@2x-1024x233.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-30-at-14.14.20@2x-300x68.png 300w, https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-30-at-14.14.20@2x-768x175.png 768w, https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-30-at-14.14.20@2x-1536x350.png 1536w, https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-30-at-14.14.20@2x-2048x466.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p><strong>Device</strong><br>If you&#8217;ll be debugging over USB, go to the Settings app on your device, select Personal Hotspot and turn that on.</p>



<h3 class="wp-block-heading" id="apple-developer-portal">Apple Developer Portal</h3>



<p>For on-device debugging, your app profiles must be set up properly. For help on this, read <a href="https://blog.xojo.com/2021/10/26/the-crazy-exercise-that-is-the-apple-signing-process/" data-type="URL" data-id="https://blog.xojo.com/2021/10/26/the-crazy-exercise-that-is-the-apple-signing-process/">The Crazy Exercise That Is The Apple Signing Process</a>.</p>



<ol class="wp-block-list">
<li><strong>Certificates</strong>: You will need a Development certificate for yourself. Download it and double-click the file to install it.</li>



<li><strong>Identifiers</strong>: You will need an Application Identifier that matches the Bundle Identifier in your app.</li>



<li><strong>Devices</strong>: You must register all of the devices that you intend to debug on.</li>



<li><strong>Profiles</strong>: You will need to create a Development profile for the app and make sure it contains your Development certificate (from step 1) as well as each of the devices that you want to debug on (step 3). Download the profile and double-click the file to install it.</li>
</ol>



<h3 class="wp-block-heading" id="xojo">Xojo</h3>



<p>Debugging on-device requires that you set the Team from your account as well as setting the Build For property to App Store.</p>



<p>When you&#8217;re ready to run on a device, from the menu select Project &gt; Run On and select your device from the list. If everything is configured properly, your app should be transferred to the device and automatically run for you.</p>



<h2 class="wp-block-heading" id="notes">Notes</h2>



<p>The first time you debug an app, you will get a dialog on the device asking if your app can connect to the local network. You will need to allow that and then run your app from Xojo again.</p>



<p>Don&#8217;t allow your device to go to sleep while waiting for the app to build and transfer or the app won&#8217;t be able to launch. You can increase the amount of time on the device by going to Settings &gt; Display &amp; Brightness and selecting a new Auto-Lock timeout. The options are 2, 5, 10 or 15 Minutes or Never.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Use Quick Look to Retrieve FolderItem Icons</title>
		<link>https://blog.xojo.com/2022/01/24/use-quick-look-to-retrieve-folderitem-icons/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Mon, 24 Jan 2022 14:08:00 +0000</pubDate>
				<category><![CDATA[Desktop]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Declares]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=9711</guid>

					<description><![CDATA[In this tutorial we will see how to retrieve the file icon using macOS' Quick Look technology and the regular file type associated with the selected file, for example JPEG, MOV, PDF, RTF, etc. Continue reading to learn how to achieve this using Declares.]]></description>
										<content:encoded><![CDATA[
<p>In this tutorial we will see how to retrieve the file icon using macOS Quick Look technology and the regular file type associated with the selected file, for example JPEG, MOV, PDF, RTF, etc. Continue reading to learn how to achieve this using Declares.</p>



<span id="more-9711"></span>



<p><a href="https://developer.apple.com/design/human-interface-guidelines/macos/system-capabilities/quick-look/">Quick Look</a> is the Apple technology in charge of creating icons and thumbnails based on a file contents. With Quick Look, the user can get a more precise preview of the contents stored in the selected file without having to open it.</p>



<p>You can retrieve this kind of information in your macOS Xojo Desktop apps using the <a href="https://documentation.xojo.com/api/language/declare.html">Declare</a> feature of the Xojo language, as we already have seen in <a href="https://blog.xojo.com/tag/declare/">other blog posts</a>. As you probably already know, Declares give you the ability to, well, &#8220;declare&#8221; from Xojo any call to functions or methods provided by external APIs and libraries as it is the case with the Frameworks available in the macOS operating system itself.</p>



<div class="wp-block-image is-style-default"><figure class="aligncenter"><img loading="lazy" decoding="async" width="618" height="446" src="https://blog.xojo.com/wp-content/uploads/2021/11/FileIconsListBox.gif" alt="" class="wp-image-9713"/></figure></div>



<p>Once we have &#8220;declared&#8221; these kind of functions from Xojo code, they will be ready to be used when calling any of your own defined methods or any of the methods directly available from the Xojo classes.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>You can download the Xojo Project file <a href="https://www.dropbox.com/s/2vshzzpbxmz4r6k/macOS-IconForFile.xojo_binary_project.zip?dl=0">from this link</a>.</p></blockquote>



<p>We will start by adding a new method to a Module in a Xojo Desktop project using the following method signature:</p>



<ul class="wp-block-list"><li><strong>Method Name:</strong> IconForFile</li><li><strong>Parameters:</strong> <code>Extends f As FolderItem, tSize As Size, Optional QuickLookIcon As Boolean = True</code></li><li><strong>Return Type:</strong> <code>Picture</code></li><li><strong>Scope:</strong> Global</li></ul>



<p>If you are new to coding in Xojo, then probably you&#8217;ll be wondering what &#8220;<a href="https://documentation.xojo.com/api/language/extends.html">Extends</a>&#8221; means in the signature method. In brief, that means that the method will be treated as a method for the data type (or class) included next to the defined parameter; in this case the <a href="https://documentation.xojo.com/api/files/folderitem.html">FolderItem</a>.</p>



<p>The main convenience of extended class methods is that your code will be more readable and you&#8217;ll be able to call the method on a data type instance using the dot notation. So, instead of using the following syntax:</p>



<pre class="wp-block-preformatted">Var f As FolderItem = FolderItem.ShowOpenFileDialog("")
Var tSize As New Size
tSize.Height = 128
tSize.Width = 128

var p As Picture = IconForFile(f, tSize) // IconForFile as a regular method definition</pre>



<p>We are able to call the method this way:</p>



<pre class="wp-block-preformatted">Var f As FolderItem = FolderItem.ShowOpenFileDialog("")
Var tSize As New Size
tSize.Height = 128
tSize.Width = 128

var p As Picture = f.IconForFile(tSize) // IconForFile as an extended method for the FolderItem class</pre>



<p>Notice as the second chunk of code is calling the method using the dot notation on the FolderItem instance referenced by the <code>f</code> variable and how, in that case, we don&#8217;t need to provide the FolderItem variable as one of the parameters in the method call.</p>



<p>The second thing you&#8217;ll probably find of interest in the method definition is the use of the <a href="https://documentation.xojo.com/api/language/optional.html">Optional</a> keyword. We include that keyword in the method signature to indicate that such parameter is… well…&nbsp;optional; that is, you can provide the parameter in the method call or not. In fact, in the previous code snippets you might have noticed the last parameter was omitted in the method call.</p>



<p>In addition, we can also provide a default value for our Optional parameter; that is the value that will receive the method if we don&#8217;t provide a value of our own. In our method definition we are setting the QuickLookIcon parameter to the default Boolean value True.</p>



<h3 class="wp-block-heading">Getting a Quick Look Icon…&nbsp;and a Regular one</h3>



<p>With our method just added, the next step is to type in the associated Code Editor the code that will be executed when we call it. As you can see, we are using a lot of Declares here from several macOS frameworks. I have added a brief commentary about their tasks on each one of these, plus a link to the associated documentation webpage on the Developers area from Apple web, so you can continue learning or digging into their functionality and, specially, the parameters and return types declared in their original signatures so you can compare how these are translated or matched from Objective-C when declared in Xojo code.</p>



<pre class="wp-block-preformatted">#If TargetMacOS Then

  #Pragma DisableBackgroundTasks
  #Pragma DisableBoundsChecking
  #Pragma NilObjectChecking False

  If f = Nil Or Not f.Exists Then Return Nil

  Var path As String = f.NativePath

  // Declare for allocating (reserving memory for) an Objective-C object
  // https://developer.apple.com/documentation/objectivec/nsobject/1571958-alloc/
  Declare Function Alloc Lib "Foundation" Selector "alloc" (classRef As ptr) As ptr

  // Declare for autoreleasing (freeing from memory) an Objective-C object
  // https://developer.apple.com/documentation/foundation/nsautoreleasepool/1807021-autorelease/
  Declare Sub AutoRelease Lib "Foundation" Selector "autorelease" (classInstance As ptr)

  // Declare for getting a reference to an Objective-C class based on the received String
  // https://developer.apple.com/documentation/foundation/1395135-nsclassfromstring?language=objc
  Declare Function NSClassFromString Lib "Foundation" (className As CFStringRef) As ptr

  // Declare for getting a reference to the shared Workspace of macOS process.
  // https://developer.apple.com/documentation/appkit/nsworkspace/1530344-sharedworkspace/
  Declare Function sharedWorkSpace Lib "AppKit" Selector "sharedWorkspace" (classObject As ptr) As ptr

  // Declare for getting the Icon object from the recived file path
  // https://developer.apple.com/documentation/appkit/nsworkspace/1528158-iconforfile/
  Declare Function iconForFile Lib "AppKit" Selector "iconForFile:" (instanceObject As ptr, path As CFStringRef) As ptr

  // Declare for setting the size of an NSImage
  Declare Function setSize Lib "AppKit" Selector "setSize:" (instanceObject As ptr, size As NSSize) As ptr

  // Declare for Lock and Unlock an NSImage in Objective-C
  // https://developer.apple.com/documentation/appkit/nsimage/1519891-lockfocus?language=objc
  // https://developer.apple.com/documentation/appkit/nsimage/1519853-unlockfocus?language=objc
  Declare Sub LockFocus Lib "AppKit" Selector "lockFocus" (imageObj As ptr)
  Declare Sub UnlockFocus Lib "AppKit" Selector "unlockFocus" (imageObj As ptr)

  // Declare for getting a new Bitmap Representation based on the Locked view
  Declare Function InitWithFocusedView Lib "AppKit" Selector "initWithFocusedViewRect:" (imageObj As ptr, rect As NSRect) As ptr

  // Declare for getting an NSData object with the specified image format from a Bitmap Representation
  // https://developer.apple.com/documentation/appkit/nsbitmapimagerep/1395458-representationusingtype/
  Declare Function RepresentationUsingType Lib "AppKit" Selector "representationUsingType:properties:" (imageRep As ptr, type As UInteger, properties As ptr) As ptr

  Var targetSize As NSSize
  targetSize.Width = tsize.Width
  targetSize.Height = tsize.Height

  Var tRect As NSRect
  tRect.Origin.x = 0
  tRect.Origin.y = 0
  tRect.RectSize = targetSize

  Var data As ptr

  If QuickLookIcon Then

    //=================
    // Let's try to retrieve the icon from Quick Look

    Var dictClass As ptr = NSClassFromString("NSDictionary")
    Var numberClass As ptr = NSClassFromString("NSNumber")

    // Declare for getting an NSNumber object from the received Boolean value
    // https://developer.apple.com/documentation/foundation/nsnumber/1551475-numberwithbool/

    Declare Function NSNumberWithBool Lib "Foundation" Selector "numberWithBool:" (numberClass As ptr, value As Boolean) As ptr
    Var numberWithBool As ptr = NSNumberWithBool(numberClass, True)

    // Declare for getting an NSDictionary object from the received Key and Value
    // https://developer.apple.com/documentation/foundation/nsdictionary/1414965-dictionarywithobject/

    Declare Function NSDictionaryWithObject Lib "Foundation" Selector "dictionaryWithObject:forKey:" (dictClass As ptr, value As ptr, key As CFStringRef) As ptr
    Var dictInstance As ptr = NSDictionaryWithObject(dictClass, numberWithBool,"IconMode")

    Var fileClass As ptr = NSClassFromString("NSURL")

    // Declare for getting an NSURL object from the received path as string
    // https://developer.apple.com/documentation/foundation/nsurl/1410828-fileurlwithpath/

    Declare Function NSFileURLWithPath Lib "Foundation" Selector "fileURLWithPath:" (fileClass As ptr, path As CFStringRef) As ptr
    Var fileInstance As ptr = NSFileURLWithPath(fileClass, f.NativePath)

    // Declare for getting the Quick Look based icon thumbnail for the received file and with the specified size
    // https://developer.apple.com/documentation/quicklook/1402623-qlthumbnailimagecreate?language=objc

    Declare Function QLThumbnailImageCreate Lib "QuickLook" (allocator As Integer, file As ptr, size As NSSize, dictRef As ptr) As ptr
    Var imageRef As ptr = QLThumbnailImageCreate(0, fileInstance, targetSize, dictInstance)

    If imageref &lt;> Nil Then

      Var BitmapImageRepClass As ptr = NSClassFromString("NSBitmapImageRep")
      Var BitmapImageRepInstance As ptr = Alloc(BitmapImageRepClass)

      // https://developer.apple.com/documentation/appkit/nsbitmapimagerep/1395423-initwithcgimage/

      Declare Function CGInitWithCGImage Lib "AppKit" Selector "initWithCGImage:" (bitmapInstance As ptr, CGImage As ptr) As ptr
      Var BitmapImageRep As ptr = CGInitWithCGImage(BitmapImageRepInstance, imageRef)

      data = RepresentationUsingType(bitmapImageRep, 4, Nil) // 4 = PNG

      AutoRelease(BitmapImageRep)
      AutoRelease(imageref)

      // Getting Xojo Picture instance from NSData object
      Var p As Picture = NSDataToPicture(data)

      data = Nil
      numberWithBool = Nil
      fileInstance = Nil
      dictInstance = Nil
      BitmapImageRepInstance = Nil
      Return p

    End If
  End If

  // If we reach this point is because there is no way to retrieve the
  // Quick Look icon for the file, it has returned a non valid object,
  // or we received the optional QuickLookIcon param set to False,
  // so we fallback to the regular one (FileType based).

  Var WorkSpace As ptr = NSClassFromString("NSWorkspace")
  Var sharedSpace As ptr = sharedWorkSpace(WorkSpace)
  Var icon As ptr = iconForFile(sharedSpace, path) // We get NSImage here

  Var resizedIcon As ptr = setSize(icon, targetSize)

  // Getting bitmap image representation in order to extract the data as PNG.

  LockFocus(resizedIcon)

  Var NSBitmapImageRepClass As ptr = NSClassFromString("NSBitmapImageRep")
  Var NSBitmapImageRepInstance As ptr = Alloc(NSBitmapImageRepClass)
  Var newRep As ptr = InitWithFocusedView(NSBitmapImageRepInstance, tRect)

  UnlockFocus(resizedIcon)

  data = RepresentationUsingType(newRep, 4, Nil) // 4 = PNG

  // Getting Xojo Picture instance from NSData object
  Var p As Picture = NSDataToPicture(data)

  data = Nil
  icon = Nil
  AutoRelease(newRep)

  Return p

#EndIf</pre>



<p>As you can see, all the code is wrapped into a compilation conditional <a href="https://documentation.xojo.com/api/compiler_directives/＃if...＃endif.html">#If… #EndIf</a> block. This means that the code will be compiled only if the condition is evaluated as true. In this case, it will compile only when we try to compile a desktop app for macOS as stated with the TargetMacOS keyword.</p>



<p>Next, we will use three #Pragma directives to speed things up a bit. In this case the pragma disable the tasks in the background, checking bound in collections like the Arrays and checking instances set to Nil, but only during the method execution, after which things return to their original settings.</p>



<p>The remaining code includes comments so you can see what happens at the more important points; for example whether to retrieve the Quick Look icon associated with the file or the regular one based on the file data type.</p>



<p>You&#8217;ll have probably noticed that we called a second method: NSDataToPicture. This method will be in charge of converting the data from an Objective-C NSDATA object to a Xojo Picture, using the technique used in previous blog posts (<a href="https://blog.xojo.com/2021/10/21/quicktip-using-sf-symbols-in-macos-revisited/">here</a> and <a href="https://blog.xojo.com/2021/08/31/how-to-create-thumbnails-from-pdfs-on-ios/">here</a>). In this case we included it as a method call to avoid the duplication of code.</p>



<p>Let&#8217;s add a second method to our Module using the following values:</p>



<ul class="wp-block-list"><li><strong>Method Name:</strong> <code>NSDataToPicture</code></li><li><strong>Parameters:</strong> <code>data As Ptr</code></li><li><strong>Return Type:</strong> <code>Picture</code></li><li><strong>Scope:</strong> Protected</li></ul>



<p>Type the following snippet of code in the associated Code Editor:</p>



<pre class="wp-block-preformatted">Declare Function DataLength Lib "Foundation" Selector "length" (obj As ptr) As Integer
Declare Sub GetDataBytes Lib "Foundation" Selector "getBytes:length:" (obj As ptr, buff As ptr, len As Integer)

Var dlen As Integer
Var mb As MemoryBlock
Var mbptr As ptr

// Getting image data to generate the Picture object in the Xojo side
// We need to get the length of the raw data…
dlen = DataLength(data)

// …in order to create a memoryblock with the right size
mb = New MemoryBlock(dlen)
mbPtr = mb

// And now we can dump the PNG data from the NSDATA objecto to the memoryblock
GetDataBytes(data, mbPtr, dlen)

// In order to create a Xojo Picture from it
Return Picture.FromData(mb)</pre>



<h3 class="wp-block-heading">Adding Required Structures</h3>



<p>As in previous tutorials dealing with Declares, we need to add several structures to the Module; these are required when calling to some of the declared functions in the IconForFile method. The required structures are:</p>



<ul class="wp-block-list"><li><strong>Structure NSOrigin</strong><br>
X As CGFloat<br>
Y As CGFloat</li><li><strong>Structure NSSize</strong><br>
Height As CGFloat<br>
Width As CGFloat</li><li><strong>Structure NSRect</strong><br>
Origin As NSOrigin<br>
RectSize As NSSize</li></ul>



<h3 class="wp-block-heading">Creating the User Interface</h3>



<p>We have prepared for retrieving the file icons on macOS, let&#8217;s continue creating a user interface for the app so we can test how it works! The final user interface will look like this:</p>



<div class="wp-block-image is-style-default"><figure class="aligncenter"><img loading="lazy" decoding="async" width="1024" height="907" src="https://blog.xojo.com/wp-content/uploads/2021/11/FinalUI-1024x907.jpg" alt="" class="wp-image-9715" srcset="https://blog.xojo.com/wp-content/uploads/2021/11/FinalUI-1024x907.jpg 1024w, https://blog.xojo.com/wp-content/uploads/2021/11/FinalUI-300x266.jpg 300w, https://blog.xojo.com/wp-content/uploads/2021/11/FinalUI-768x680.jpg 768w, https://blog.xojo.com/wp-content/uploads/2021/11/FinalUI.jpg 1270w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></div>



<p>Click on the Window1 window in the Navigator panel; that will display the window in the Layout Editor. With Window1 selected, go to the associated Inspector Panel and change the following properties:</p>



<ul class="wp-block-list"><li><strong>Name:</strong> MainWindow</li><li><strong>Title:</strong> Icon File Viewer</li></ul>



<p>Next, with the MainWindow item still selected and displayed in the Layout Editor, drag a Button control from the Library and drop it in the top-left area of the window in the Layout Editor (you can rely on the displayed alignment guides to position the control).</p>



<p>With the button selected in the Layout Editor, change the following values in the associated Inspector Panel:</p>



<ul class="wp-block-list"><li><strong>Name:</strong> SelectFileBt</li><li><strong>Locking:</strong> Top and Left closed (locked)</li><li><strong>Caption:</strong> Select File</li></ul>



<p>Return to the Library, drag a Label control and position it just under the button in the Layout Editor. Use the associated Inspector Panel to change the following values:</p>



<ul class="wp-block-list"><li><strong>Name:</strong> IconSizeLB</li><li><strong>Locking:</strong> Top and Left closed (locked)</li><li><strong>Text:</strong> Icon Size:</li></ul>



<p>Drag a Slider control from the Library and position it just to the right of the label. Drag the right corner of the Label handler in the Layout Editor to change its width so it reaches the right margin of the window. Use the associated Inspector Panel to change the following values:</p>



<ul class="wp-block-list"><li><strong>Name:</strong> IconSizeSL</li><li><strong>Locking:</strong> Top, Left and Right closed (locked)</li><li><strong>Line Step:</strong> 32</li><li><strong>Allow Live Scrolling:</strong> Enabled</li><li><strong>Page Step:</strong> 32</li><li><strong>Tick Mark Style:</strong> Bottom Right</li><li><strong>Value:</strong> 128</li><li><strong>Minimum Value:</strong> 32</li><li><strong>Maximum Value:</strong> 1024</li></ul>



<p>Once again, drag a CheckBox control from the Library and position it just below the Label in the Layout Editor. Use the associated Inspector Panel to change the following values for the CheckBox:</p>



<ul class="wp-block-list"><li><strong>Name:</strong> QuickLookCB</li><li><strong>Locking:</strong> Top and Left closed (locked)</li><li><strong>Caption:</strong> Quick Look Preview</li><li><strong>Visual State:</strong> Checked</li></ul>



<p>The last control we need to add is an ImageViewer. Drag the control from the Library and position it just below the CheckBox. Use the ImageViewer resizing handlers in the Layout Editor so its width and height matches the right and bottom alignment guides in the window. Then, use the associated Inspector Panel to set the following values:</p>



<ul class="wp-block-list"><li><strong>Name:</strong> IconPreviewIV</li><li><strong>Locking:</strong> Top, Left, Right and Bottom closed (locked)</li></ul>



<h3 class="wp-block-heading">Adding Functionality to the User Interface</h3>



<p>Let&#8217;s add the code to execute when the user interacts with certain controls. With the SelectFileBt button item selected in the Navigator or the Layout Editor, use the contextual menu to add the Pressed Event to it. Then, type the following code in the associated Code Editor:</p>



<pre class="wp-block-preformatted">file = FolderItem.ShowOpenFileDialog("")
If file &lt;&gt; Nil Then
  FileNameLB.Text = file.Name
Else
  FileNameLB.Text = ""
End If
GetIconForFile</pre>



<p>With the IconSizeSL slider control selected, use the contextual menu to add the ValueChanged Event to it, and type the following code in the associated Code Editor:</p>



<pre class="wp-block-preformatted">If Self.File &lt;> Nil Then
  GetIconForFile
End If</pre>



<p>With the QuickLookCB checkbox item selected, use the contextual menu to add the ValueChanged Event, and type the following line of code in the associated Code Editor:</p>



<pre class="wp-block-preformatted">GetIconForFile</pre>



<p>As you can see, all of these events will call the getIconForFile method, so we need to add it to the <code>MainWindow</code> window using the following signature:</p>



<ul class="wp-block-list"><li><strong>Name:</strong> GetIconForFile</li><li><strong>Scope:</strong> Public</li></ul>



<p>…and type the following snippet of code in the associated Code Editor:</p>



<pre class="wp-block-preformatted">If file &lt;&gt; Nil Then
  Var tSize As New Size
  tSize.Height = IconSizeSL.Value
  tSize.Width = IconSizeSL.Value

  IconPreviewIV.Image = file.IconForFile(tSize, QuickLookCB.Value)

End If</pre>



<p>In the final step, add the File property (as FolderItem type) to the window, because this will be the one responsible for storing the reference to the FolderItem selected by the user when they click the SelectFileBt button.</p>



<div class="wp-block-image is-style-default"><figure class="aligncenter"><img loading="lazy" decoding="async" width="618" height="534" src="https://blog.xojo.com/wp-content/uploads/2021/11/IconFilePreview.gif" alt="" class="wp-image-9712"/></figure></div>



<p>Once the File property has been added, run the app, click on the Select File button and change the slider value to retrieve the icon for the file using a different size. Try to click in the checkbox to change the retrieved icon from the Quick Look view (enabled by default) to the kind of icon associated with that particular file type.</p>



<p><em>Paul learned to program in BASIC at age 13 and has programmed in more languages than he remembers, with Xojo being an obvious favorite. When not working on Xojo, you can find him talking about retrocomputing at <a href="https://goto10.substack.com" target="_blank" rel="noreferrer noopener">Goto 10</a> and </em>on Mastodon @lefebvre@hachyderm.io.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The Crazy Exercise that is the Apple Signing Process</title>
		<link>https://blog.xojo.com/2021/10/26/the-crazy-exercise-that-is-the-apple-signing-process/</link>
		
		<dc:creator><![CDATA[Greg O'Lone]]></dc:creator>
		<pubDate>Tue, 26 Oct 2021 20:31:46 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[App Store]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Development]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=9512</guid>

					<description><![CDATA[...why (does) this process seems so complicated in the first place? What Apple is trying to do is to provide operational security...]]></description>
										<content:encoded><![CDATA[
<p>Anyone who dabbles in macOS or iOS development in Xojo (and elsewhere) has encountered what seems to be the maddening voodoo of getting their development certificates and profiles &#8220;just right&#8221; only to have them fail the next time they try to build. <br><br>Today I&#8217;m going to try to clear up some of the mystery surrounding this convoluted process and give you some pointers not only for fixing but also for figuring out where your signing issues lie.</p>



<h2 class="wp-block-heading">It&#8217;s All About Operational Security</h2>



<p>Just so we&#8217;re all clear about why this process seems so complicated in the first place. What Apple is <em>trying</em> to do is to provide operational security, that is, separation of responsibilities so that on a big team, a single developer can&#8217;t just create and push out an app without anyone&#8217;s approval. While it adds a bit of complication for individual developers, it also means that as your product (and more importantly your team) grows, you&#8217;ll be able to deal with the changes gracefully.</p>



<h2 class="wp-block-heading">Seemingly Disparate Pieces</h2>



<p>There are six different parts that need to come together to successfully sign and deploy on iOS and macOS using the App Store (or Enterprise) which need to be configured properly for all this to work. If you&#8217;re just starting out, we suggest doing them in the order specified below to avoid having to go back and regenerate things later.</p>



<ol class="wp-block-list"><li><strong>The Application Identifier</strong> – This is the identifier which Apple requires be unique for every application installed on an Apple device. Typically in the form: <code>com.yourcompany.app-name</code> You will have the best luck with this process if you decide what this is going to be up front because it affects nearly everything going forward. You will define any capabilities which require entitlements in this section. Enabling things in this section may mean that you need to check a corresponding capability in your Xojo project. <em>Changing these capabilities will invalidate the Profiles below.</em></li><li><strong>Testing Devices</strong> – This is a list of devices which are <em>allowed</em> to be used for testing. They are specified using the Apple Developer portal using the device UDID. For an iOS device, this can be found either in Finder or in iTunes when the device is connected. I suggest using a meaningful name for the device if you have a lot of them.</li><li><strong>Certificates</strong> – Development and Distribution certificates are based on a public-private key-pair (like SSH) and are used for signing applications for testing and distribution respectively. See the Troubleshooting section below for more information.<ol><li><strong>Development Certificate</strong> – Each person who is writing code for you on your projects and needs to be able to build for a testing device will need one of these which was created in <em>your account</em>. This means that if you have a contractor working for you, you&#8217;ll need to add them to your account, set their Role to <strong>Developer</strong> and specify the apps that this developer is allowed to work on. One certificate per developer, and these need to be renewed each year.</li><li><strong>Distribution Certificate</strong> – The person, group or machine that is responsible for building for the App Store (or Enterprise) has a separate key-pair certificate. One certificate per <em>account</em>, and they need to be renewed each year.</li></ol></li><li><strong>Profiles</strong><ol><li><strong>Development Profile</strong> –&nbsp;This file is used to link up the who, what and where of developing an iOS or macOS app. When creating a development profile, give it a name appropriate to the group you are creating. It&#8217;s important to understand that because these profiles rely on the testing devices and on the individual developers that changes to those groups will require regenerating this profile. If your developers and/or testing devices change often, I suggest creating individual profiles for each developer. If not, you&#8217;ll have better luck with just one profile that contains all of your developers and devices. These need to be regenerated at least once per year.<ol><li>The Application Identifier &#8211; Select the Application Identifier for the app to which this profile applies.</li><li>Certificates – Select each of the developers that should be able to test this app on the selected devices.</li><li>Devices &#8211; Select each of the devices that the developers should be able to use in their testing.</li></ol></li><li><strong>Distribution Profile</strong> – This file links together the Application Identifier and the Distribution Certificate. Remember, there is typically one Distribution Certificate per account, so this allows you to grant or revoke the ability to distribute an app. These need to be regenerated at least once per year.</li></ol></li></ol>



<h2 class="wp-block-heading">Dependencies</h2>



<p>I&#8217;ve touched on this in places above, but I want this to be perfectly clear to anyone that is having trouble with certificates or profiles. The Development and Distribution profiles are highly dependent on the integrity of the Application Identifiers, Devices and Certificates. Any change to those items will mean that either or both of the profiles will need to be regenerated. Luckily (for the profiles anyway), it&#8217;s just a matter of editing the profile, adding or updating the data (if any) and clicking Save. Once that&#8217;s done, you can download the new profile, give it to anyone on your team that needs it (anyone whose certificates are contained therein) and just by double-clicking on the new file, it will be installed on your system by Xcode.</p>



<p>The table below shows the dependencies of the Development and Distribution profiles. <em>Any</em> changes to the indicated items (including expiration of a certificate) will render the profile Invalid and require that it be regenerated.</p>



<figure class="wp-block-table aligncenter is-style-regular"><table><thead><tr><td class="has-text-align-center" data-align="center"><strong>Profile Type</strong></td><td class="has-text-align-center" data-align="center"><strong>Application Identifier</strong></td><td class="has-text-align-center" data-align="center"><strong>Devices</strong></td><td class="has-text-align-center" data-align="center"><strong>Development Certificates</strong></td><td class="has-text-align-center" data-align="center"><strong>Distribution Certificate</strong></td></tr></thead><tbody><tr><td class="has-text-align-center" data-align="center">Development</td><td class="has-text-align-center" data-align="center">X</td><td class="has-text-align-center" data-align="center">X</td><td class="has-text-align-center" data-align="center">X</td><td class="has-text-align-center" data-align="center"></td></tr><tr><td class="has-text-align-center" data-align="center">Distribution</td><td class="has-text-align-center" data-align="center">X</td><td class="has-text-align-center" data-align="center"></td><td class="has-text-align-center" data-align="center"></td><td class="has-text-align-center" data-align="center">X</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">Troubleshooting</h2>



<h3 class="wp-block-heading"><strong>Overall</strong></h3>



<p>If you&#8217;re getting errors during the build process, there&#8217;s usually some information about whether it is a Profile or a Certificate that is causing the trouble. The first thing you should do is go to your Apple Developer portal and under Certificates, Identifiers &amp; Profiles check to make sure that none of your Certificates have expired and that all of your Profiles for the current project are still Valid and have also not expired.</p>



<h3 class="wp-block-heading"><strong>Certificates</strong></h3>



<p>If for any reason you do not have both parts of the certificate you are trying to use, whether it&#8217;s the user&#8217;s Development certificate when building for your test devices or the Distribution certificate when trying to build for the App Store (or Enterprise), you&#8217;re not going to be successful. Both the public and the private key must be present on your machine for them to work.</p>



<p>It&#8217;s important to remember that these certificates can only be downloaded from Apple&#8217;s Developer portal <strong>once</strong>, after which downloading will only give you the public key. If you need to transfer a development certificate from one account to another (like if you replace your computer mid-year), you should find the certificate in your keychain, right-click on it and select <strong>Export</strong>. When the save dialog appears, make sure the file format is set to <strong>Personal Information Exchange (.p12)</strong>, and set a password for the key after you click <strong>Save</strong>. When you take the exported key to your new account/machine and double-click on it, the system will ask you for the password and you should be all set.</p>



<h2 class="wp-block-heading">Enterprise Distribution</h2>



<p>If you are a Xojo developer using an Enterprise developer account to distribute iOS applications within your own company without going through the App Store, we highly suggest checking out 2021r3 or later as some important changes have been made to make your builds more successful. </p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>QuickTip: Using SF Symbols in macOS … revisited!</title>
		<link>https://blog.xojo.com/2021/10/21/quicktip-using-sf-symbols-in-macos-revisited/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Thu, 21 Oct 2021 13:00:00 +0000</pubDate>
				<category><![CDATA[Desktop]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Font]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[SF Font]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=9397</guid>

					<description><![CDATA[Earlier this year ago I wrote a post about using the SF Font symbols on macOS Picture.SystemImagein iOS apps. However that technique has some downsides. For one, the symbol glyphs are hardcoded, which means that it's not possible to access the new symbols added to the SF Font by Apple. In addition, it isn't possible to set the font weight and scale for the glyph. In this new post, I'll show a more flexible way to work with these symbols on macOS 11+.]]></description>
										<content:encoded><![CDATA[
<p>Earlier this year ago I wrote a post about using <a href="https://blog.xojo.com/2021/02/17/quicktip-using-sf-symbols-in-your-macos-apps/">the SF Font symbols on macOS</a> <code>Picture.SystemImage</code>in <strong>iOS</strong> apps. However that technique has some downsides. For one, the symbol glyphs are hardcoded, which means that it&#8217;s not possible to access the new symbols added to the SF Font by Apple. In addition, it isn&#8217;t possible to set the font weight and scale for the glyph. In this new post, I&#8217;ll show a more flexible way to work with these symbols on macOS 11+.</p>



<span id="more-9397"></span>



<p>This technique is more on par with the current <code>Picture.SystemImage</code> you use in your Xojo iOS apps. With it you will be able to set the following attributes:</p>



<ul class="wp-block-list"><li><strong>Glyph name.</strong> You can use Apple&#8217;s Symbols SF utility to view all the available symbols and the name associated with each of these.</li><li><strong>Size</strong> (in points)</li><li><strong>Weight.</strong> The weight of the SF Font, ranging from Ultra-Light to Black. This is an Enumeration value.</li><li><strong>Scale.</strong> The scale of the SF Font symbol, ranging from Small to Large. This is an Enumeration value.</li><li><strong>TemplateColor.</strong> If you want to tint the resulting glyph, you can provide a ColorGroup parameter (Desktop apps) or a regular Color parameter (Desktop, Console apps).</li><li><strong>FallbackTemplateImage.</strong> You can provide a grayscale / black and white image to use as a fallback image, in case there is no way to create a picture from the received &#8220;name&#8221; string.</li></ul>



<div class="wp-block-image is-style-default"><figure class="aligncenter"><img loading="lazy" decoding="async" width="1024" height="851" src="https://blog.xojo.com/wp-content/uploads/2021/10/Captura-de-pantalla-2021-10-04-a-las-15.43.57-1024x851.png" alt="" class="wp-image-9400" srcset="https://blog.xojo.com/wp-content/uploads/2021/10/Captura-de-pantalla-2021-10-04-a-las-15.43.57-1024x851.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/10/Captura-de-pantalla-2021-10-04-a-las-15.43.57-300x249.png 300w, https://blog.xojo.com/wp-content/uploads/2021/10/Captura-de-pantalla-2021-10-04-a-las-15.43.57-768x639.png 768w, https://blog.xojo.com/wp-content/uploads/2021/10/Captura-de-pantalla-2021-10-04-a-las-15.43.57.png 1424w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></div>



<p>As it is the case with the existing iOS method, you will receive a Picture. For example you will be able to use code like this in your desktop projects:</p>



<pre class="wp-block-preformatted">Var c As New ColorGroup(Color.Red, Color.White)
Var p As Picture = SystemImage("highlighter", 120.0, SystemImageWeights.UltraLight, Symbolscale.Small, c, fallback)

IVSFGlyph.Image = p</pre>



<p>The &#8220;fallback&#8221; parameter refers to an image added to a desktop project that will be used if the glyph is not found. This will produce the following glyph, assigned as the image to the <code>ImageView</code> control named <code>IVSFGlyph</code>:</p>



<div class="wp-block-image is-style-default"><figure class="aligncenter"><img loading="lazy" decoding="async" width="724" height="522" src="https://blog.xojo.com/wp-content/uploads/2021/10/Captura-de-pantalla-2021-10-04-a-las-15.25.15.png" alt="" class="wp-image-9398" srcset="https://blog.xojo.com/wp-content/uploads/2021/10/Captura-de-pantalla-2021-10-04-a-las-15.25.15.png 724w, https://blog.xojo.com/wp-content/uploads/2021/10/Captura-de-pantalla-2021-10-04-a-las-15.25.15-300x216.png 300w" sizes="auto, (max-width: 724px) 100vw, 724px" /></figure></div>



<p>In order to add this kind of functionality to your Xojo Desktop and Console projects on macOS, add a new Module to the Navigator (for example, with the name macOSLib). Then, with the macOSLib item selected in the Navigator, add two enumerations with the following values:</p>



<ul class="wp-block-list"><li><strong>Name:</strong> SymbolScale</li><li><strong>Type:</strong> Integer</li><li><strong>Scope:</strong> Global</li><li><strong>Values:</strong><br>Small = 1<br>Medium = 2<br>Large = 3</li></ul>



<ul class="wp-block-list"><li><strong>Name:</strong> SystemImageWeights</li><li><strong>Type:</strong> Integer</li><li><strong>Values:</strong><br>UltraLight = 0<br>Thin = 1<br>Light = 2<br>Regular = 3<br>Medium = 4<br>Semibold = 5<br>Bold = 6<br>Heavy = 7<br>Black = 8</li></ul>



<p>Now add to the <code>macOSLib</code> module the method that will run both on Desktop and Console macOS apps:</p>



<ul class="wp-block-list"><li><strong>Method Name:</strong> SystemImage</li><li><strong>Parameters:</strong> name As String, size As Double, weight As SystemImageWeights = SystemImageWeights.Regular, scale As SymbolScale = SymbolScale.Medium, templateColor As Color, fallbackTemplateImage As Picture = Nil</li><li><strong>Return Type:</strong> Picture</li><li><strong>Scope:</strong> Global</li></ul>



<p>Click on the cog wheel icon in the Inspector to change to the attributes section for the method, and make sure to set only the options displayed in the following picture:</p>



<div class="wp-block-image is-style-default"><figure class="aligncenter"><img loading="lazy" decoding="async" width="496" height="336" src="https://blog.xojo.com/wp-content/uploads/2021/10/Captura-de-pantalla-2021-10-04-a-las-15.32.25.png" alt="" class="wp-image-9399" srcset="https://blog.xojo.com/wp-content/uploads/2021/10/Captura-de-pantalla-2021-10-04-a-las-15.32.25.png 496w, https://blog.xojo.com/wp-content/uploads/2021/10/Captura-de-pantalla-2021-10-04-a-las-15.32.25-300x203.png 300w" sizes="auto, (max-width: 496px) 100vw, 496px" /></figure></div>



<p>Finally, put the following code in the Code Editor associated with the newly created method:</p>



<pre class="wp-block-preformatted">#If TargetMacOS

  If System.Version &gt;= "11.0" Then

    If name = "" Then Return Nil

    Declare Function Alloc Lib "Foundation" Selector "alloc" (classRef As Ptr) As Ptr
    Declare Sub AutoRelease Lib "Foundation" Selector "autorelease" (classInstance As Ptr)

    Declare Function NSClassFromString Lib "Foundation" (clsName As CFStringRef) As Ptr
    Declare Function ImageWithSystemSymbolName Lib "AppKit" Selector "imageWithSystemSymbolName:accessibilityDescription:" (imgClass As Ptr, symbolName As CFStringRef, accesibility As CFStringRef) As Ptr
    Declare Function ConfigurationWithPointSize Lib "AppKit" Selector "configurationWithPointSize:weight:scale:" (symbolConfClass As Ptr, size As CGFloat, weight As CGFloat, tscale As SymbolScale) As Ptr
    Declare Function ImageWithSymbolConfiguration Lib "AppKit" Selector "imageWithSymbolConfiguration:" (imgClass As Ptr, config As Ptr) As Ptr
    Declare Function ColorWithRGBA Lib "Foundation" Selector "colorWithRed:green:blue:alpha:" (nscolor As ptr, red As CGFloat, green As CGFloat, blue As CGFloat, alpha As CGFloat) As Ptr
    Declare Sub SetTemplate Lib "AppKit" Selector "setTemplate:" (imageObj As Ptr, value As Boolean)
    Declare Sub LockFocus Lib "AppKit" Selector "lockFocus" (imageObj As Ptr)
    Declare Sub UnlockFocus Lib "AppKit" Selector "unlockFocus" (imageObj As Ptr)
    Declare Sub Set Lib "Foundation" Selector "set" (colorObj As Ptr)
    Declare Sub NSRectFillUsingOperation Lib "AppKit" (rect As NSRect, option As UInteger)

    Declare Function RepresentationUsingType Lib "AppKit" Selector "representationUsingType:properties:" (imageRep As Ptr, type As UInteger, properties As Ptr) As Ptr
    Declare Function InitWithFocusedView Lib "AppKit" Selector "initWithFocusedViewRect:" (imageObj As Ptr, rect As NSRect) As Ptr

    Var nsimage As Ptr = NSClassFromString("NSImage")
    Var orImage As Ptr = ImageWithSystemSymbolName(nsimage, name, "")
    Var symbolConfClass As Ptr = NSClassFromString("NSImageSymbolConfiguration")

    // Getting the weight as the required SystemImageWeight float
    Var tWeight As CGFloat = SystemImageWeight(weight)

    // Creating a configuration obj for the Glyph
    Var symbolConf As Ptr = ConfigurationWithPointSize(symbolConfClass, size, tWeight, scale)

    // Getting the final NSImage from the Glyph + Conf (still in vectorial format)
    Var finalImage As Ptr = ImageWithSymbolConfiguration(orImage, symbolConf)

    // Can't create image from received glyph name, so we return Nil if fallback is not provided
    // or colorize the fallback image if there is one
    If finalImage = Nil Then

      If fallbackTemplateImage = Nil Then Return Nil

      Var fallbackData As MemoryBlock = fallbackTemplateImage.ToData(Picture.Formats.PNG)
      Var fallbackDataPtr As Ptr = fallbackData

      Declare Function DataWithBytesLength Lib "Foundation" Selector "dataWithBytes:length:" (dataClass As Ptr, data As Ptr, length As UInteger) As Ptr

      If fallbackData &lt;&gt; Nil And fallbackData.Size &gt; 0 Then

        Var NSDataClass As Ptr = NSClassFromString("NSData")
        Var NSDataObj As Ptr = DataWithBytesLength(NSDataclass, fallbackDataPtr, fallbackData.Size)

        If NSDataObj &lt;&gt; Nil Then

          Declare Function InitWithData Lib "AppKit" Selector "initWithData:" (imageInstance As Ptr, data As Ptr) As Ptr

          Var NSImageClass As Ptr = NSClassFromString("NSImage")

          finalImage = Alloc(NSImageClass)
          finalImage = InitWithData(finalImage, NSDataObj)

          AutoRelease(NSDataObj)

        End If

      End If

    End If

    If finalImage = Nil Then Return Nil

    Var c As Color
    Var nscolor As Ptr

    LockFocus(finalImage)

    // Applying tint to the image if we receive a valid ColorGroup object

    c = templateColor

    nscolor = NSClassFromString("NSColor")
    Var tColor As Ptr = ColorWithRGBA(nscolor, c.Red/255.0, c.Green/255.0, c.Blue/255.0, 1.0-c.Alpha/255.0)

    // We need to set the Template property of the NSImage to False in order to colorize it.
    SetTemplate(finalImage, False)

    Declare Function ImageSize Lib "AppKit" Selector "size" (imageObjt As Ptr) As NSSize

    Var tRect As NSRect

    tRect.Origin.X = 0
    tRect.Origin.Y = 0
    tRect.RectSize = ImageSize(finalImage)

    Set(tColor)
    NSRectFillUsingOperation(tRect, 3)

    // Getting bitmap image representation in order to extract the data as PNG.

    Var NSBitmapImageRepClass As Ptr = NSClassFromString("NSBitmapImageRep")
    Var NSBitmapImageRepInstance As Ptr = Alloc(NSBitmapImageRepClass)
    Var newRep As Ptr = InitWithFocusedView(NSBitmapImageRepInstance, tRect)

    UnlockFocus(finalImage)

    Var data As Ptr = RepresentationUsingType(newRep, 4, Nil) // 4 = PNG

    AutoRelease(newRep)
    AutoRelease(nscolor)

    // Getting image data to generate the Picture object in the Xojo side

    Declare Function DataLength Lib "Foundation" Selector "length" (obj As Ptr) As Integer
    Declare Sub GetDataBytes Lib "Foundation" Selector "getBytes:length:" (obj As Ptr, buff As ptr, len As Integer)

    // We need to get the length of the raw data…
    Var dlen As Integer = DataLength(data)

    // …in order to create a memoryblock with the right size
    Var mb As New MemoryBlock(dlen)
    Var mbPtr As Ptr = mb

    // And now we can dump the PNG data from the NSDATA objecto to the memoryblock
    GetDataBytes(data, mbPtr, dlen)

    // In order to create a Xojo Picture from it
    Return Picture.FromData(mb)
  End If

#EndIf</pre>



<p>As you can see, this method calls the <code>SystemImageWeight</code> method, and also makes use of some <code>Structs</code>. Let&#8217;s add to the method that will convert the received enum value to the required <code>CGFloat</code> value needed by the Declare:</p>



<ul class="wp-block-list"><li><strong>Method Name:</strong> SystemImageWeight</li><li><strong>Parameters:</strong>&nbsp;<span style="font-size: revert;">weight As SystemImageWeights</span></li><li><strong>Returned Type:</strong> CGFloat</li><li><strong>Scope:</strong> Global</li></ul>



<p>Add the following code in the associated Code Editor:</p>



<pre class="wp-block-preformatted">Var tWeight As CGFloat = 0

Select Case weight
Case SystemImageWeights.UltraLight
  tWeight = -1.0
Case SystemImageWeights.Thin
  tWeight = -0.75
Case SystemImageWeights.Light
  tWeight = -0.5
Case SystemImageWeights.Regular
  tWeight = -0.25
Case SystemImageWeights.Medium
  tWeight = 0
Case SystemImageWeights.Semibold
  tWeight = 0.25
Case SystemImageWeights.Bold
  tWeight = 0.5
Case SystemImageWeights.Heavy
  tWeight = 0.75
Case SystemImageWeights.Black
  tWeight = 1
End Select

Return tWeight</pre>



<p>And now add three new Structures to the macOSLib module using the following values:</p>



<ul class="wp-block-list"><li><strong>Structure Name:</strong> NSOrigin</li><li><strong>Scope:</strong> Global<br>X as CGFloat<br>Y as CGFloat</li></ul>



<ul class="wp-block-list"><li><strong>Structure Name:</strong> NSSize</li><li><strong>Scope:</strong> Global<br>Height as CGFloat<br>Width as CGFloat</li></ul>



<ul class="wp-block-list"><li><strong>Structure Name:</strong> NSRect</li><li><strong>Scope:</strong> Global<br>Origin as NSOrigin<br>RectSize as NSSize</li></ul>



<p>Add an overloaded method only intended for macOS desktop apps. The main difference is that this one can receive a <code>ColorGroup</code> parameter instead of just a <code>Color</code> object:</p>



<ul class="wp-block-list"><li><strong>Method Name:</strong> SystemImage</li><li><strong>Parameters:</strong> name As String, size As Double, weight As SystemImageWeights = SystemImageWeights.Regular, scale As SymbolScale = SymbolScale.Medium, templateColor As ColorGroup = Nil, fallbackTemplateImage As Picture = Nil</li><li><strong>Returned Type:</strong> Picture</li><li><strong>Scope:</strong> Global</li></ul>



<p>And type the following code in the associated Code Editor for the method:</p>



<pre class="wp-block-preformatted">Var c As Color

If templateColor &lt;&gt; Nil Then
  c = templateColor
End If

Return SystemImage(name, size, weight, scale, c, fallbackTemplateImage)</pre>



<p>Click on the cog wheel icon from the method Inspector and set the attributes as shown in the following picture:</p>



<div class="wp-block-image is-style-default"><figure class="aligncenter"><img loading="lazy" decoding="async" width="476" height="330" src="https://blog.xojo.com/wp-content/uploads/2021/10/Captura-de-pantalla-2021-10-04-a-las-15.50.17.png" alt="" class="wp-image-9401" srcset="https://blog.xojo.com/wp-content/uploads/2021/10/Captura-de-pantalla-2021-10-04-a-las-15.50.17.png 476w, https://blog.xojo.com/wp-content/uploads/2021/10/Captura-de-pantalla-2021-10-04-a-las-15.50.17-300x208.png 300w" sizes="auto, (max-width: 476px) 100vw, 476px" /></figure></div>



<h2 class="wp-block-heading">&nbsp;</h2>



<h2 class="wp-block-heading">Setting SF Glyphs directly to Views</h2>



<p>Let&#8217;s add now a third method to the module whose main difference is that it will not return a Picture; instead, it will set the specified SF glyph as the image for the received control handler. For example, this is neat if you want to set a SF symbol to a button in you UI interface (among other UI controls).</p>



<div class="wp-block-image is-style-default"><figure class="aligncenter"><img loading="lazy" decoding="async" width="192" height="70" src="https://blog.xojo.com/wp-content/uploads/2021/10/Captura-de-pantalla-2021-10-04-a-las-16.13.14.png" alt="" class="wp-image-9402"/></figure></div>



<p>This is the signature for the new method:</p>



<ul class="wp-block-list"><li><strong>Name:</strong> SystemImage</li><li><strong>Parameters:</strong> name As String, size As Double, weight As SystemImageWeights = SystemImageWeights.Regular, scale As SymbolScale = SymbolScale.Small, controlHandler As Integer</li><li><strong>Scope:</strong> Global</li></ul>



<p>And the code to put in the associated Code Editor:</p>



<pre class="wp-block-preformatted">#If TargetMacOS

  If System.Version &gt;= "11.0" Then

    If name = "" Then Exit

    Declare Function Alloc Lib "Foundation" Selector "alloc" (classRef As Ptr) As Ptr
    Declare Sub AutoRelease Lib "Foundation" Selector "autorelease" (classInstance As Ptr)

    Declare Function NSClassFromString Lib "Foundation" (clsName As CFStringRef) As Ptr
    Declare Function ImageWithSystemSymbolName Lib "AppKit" Selector "imageWithSystemSymbolName:accessibilityDescription:" (imgClass As Ptr, symbolName As CFStringRef, accesibility As CFStringRef) As Ptr
    Declare Function ConfigurationWithPointSize Lib "AppKit" Selector "configurationWithPointSize:weight:scale:" (symbolConfClass As Ptr, size As CGFloat, weight As CGFloat, scale As SymbolScale) As Ptr
    Declare Function ImageWithSymbolConfiguration Lib "AppKit" Selector "imageWithSymbolConfiguration:" (imgClass As Ptr, config As Ptr) As Ptr

    Var nsimage As Ptr = NSClassFromString("NSImage")
    Var orImage As Ptr = ImageWithSystemSymbolName(nsimage, name,"")
    Var symbolConfClass As Ptr = NSClassFromString("NSImageSymbolConfiguration")

    // Getting the weight as the required SystemImageWeight float
    Var tWeight As CGFloat = SystemImageWeight(weight)

    // Creating a configuration obj for the Glyph
    Var symbolConf As Ptr = ConfigurationWithPointSize(symbolConfClass, size, tWeight, scale)

    // Getting the final NSImage from the Glyph + Conf (still in vectorial format)
    Var finalImage As Ptr = ImageWithSymbolConfiguration(orImage, symbolConf)

    // We need to know if the received Handler can respond to the setImage message (that is, it's a View)

    Declare Function RespondsToSelector Lib "/usr/lib/libobjc.A.dylib" Selector "respondsToSelector:" (obj As Integer, sel As Ptr) As Boolean
    Declare Function NSSelectorFromString Lib "Foundation" (sel As CFStringRef) As Ptr

    Var sel As Ptr = NSSelectorFromString("setImage:")

    // We check if it's a valid handler, we have an NSImage object and the handler can receive the "setImage" message
    If controlHandler &lt;&gt; 0 And finalImage &lt;&gt; Nil And RespondsToSelector(controlHandler, sel) Then

      Declare Sub Set Lib "AppKit" Selector "setImage:" (control As Integer, Image As Ptr)

      // We set the NSImage to the received control
      Set(controlHandler, finalImage)

    End If

  End If

#EndIf</pre>



<p>So, for example, you can set now the Gear symbol as the image of a <code>PushButton</code> control added to the app UI using the following code in the <code>Open</code> Event Handler of the <code>PushButton</code> instance:</p>



<pre class="wp-block-preformatted">SystemImage("gearshape.2", 14.0, SystemImageWeights.Regular, SymbolScale.Small, Me.Handle)</pre>



<h2 class="wp-block-heading">Summary</h2>



<p>And that&#8217;s all! As you can see, there are no hardcoded codepoints for the SF glyphs. You&#8217;ll be able to create a picture from any SF symbol at the desired points size, weight and scale. Plus, you&#8217;ll be able to colorize it and receive a fallback image if anything goes wrong in the process.</p>



<p>You can download the example Xojo project with the Module already created from <a href="https://www.dropbox.com/s/ndorw1mxu70wmww/SF%20Symbols-macOS.zip?dl=1">this link</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Google Switches to Native on iOS</title>
		<link>https://blog.xojo.com/2021/10/12/google-switches-to-native-on-ios/</link>
		
		<dc:creator><![CDATA[Geoff Perlman]]></dc:creator>
		<pubDate>Tue, 12 Oct 2021 15:48:14 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Native App Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=9422</guid>

					<description><![CDATA[MacRumors reported that Google's design chief for Apple platforms, Jeff Verkoeyen, announced that Google is switching from using a lot of custom controls in its iOS apps. this same device. You only get that if you use native user interface controls. That's why Xojo has always provided native user interface controls, high-level access to native system functionality and compiled to native code. ]]></description>
										<content:encoded><![CDATA[
<p>MacRumors <a href="https://www.macrumors.com/2021/10/11/google-apps-for-ios-to-switch-to-uikit/">reported</a> that Google&#8217;s design chief for Apple platforms, Jeff Verkoeyen, announced that Google is switching from using a lot of custom controls in its iOS apps such as Gmail, Google Maps, Google Photos, YouTube and others, to using Apple&#8217;s native user interface controls. The purpose of using their own controls was to provide a user experience that was unified between desktop, web and mobile. Some Google users complained (unsurprisingly) that using Google&#8217;s apps on iOS was a jarring experience compared to the rest of iOS.</p>



<p>Google is making the right move here. In the overwhelming majority of cases, the paramount issue is that the user interface is consistent with other user interface experiences the user is likely to have on this same device. You only get that if you use native user interface controls. That&#8217;s why Xojo has always provided native user interface controls, high-level access to native system functionality and compiled to native code. Native provides the best experience for the end user which is what matters most. With most development tools, doing so requires a lot of extra work for the developers but reducing that should never come at the expense of a poor user experience. Fortunately, developers don&#8217;t have to make that sacrifice with Xojo.</p>



<p>Creating the best user experience extends beyond native controls. Developers must also look at what the customary design and behaviors of apps are on the target OS. Native controls help quite a bit with this but developers still must be vigilant and dedicated to avoid degrading the user experience.</p>



<p>I applaud Jeff Verkoeyen for making this difficult but correct choice. While there are a few categories of apps where custom user interface makes sense (games, kiosk apps), for all others, native is the best choice for creating the best user experience. </p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
