<?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>Guest Post &#8211; Xojo Programming Blog</title>
	<atom:link href="https://blog.xojo.com/category/community/guest-post/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.xojo.com</link>
	<description>Blog about the Xojo programming language and IDE</description>
	<lastBuildDate>Wed, 22 Apr 2026 16:12:09 +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>Quick Tip: Font Properties in DrawControlInLayoutEditor for Mobile Projects</title>
		<link>https://blog.xojo.com/2026/04/22/quick-tip-font-properties-in-drawcontrolinlayouteditor-for-mobile-projects/</link>
		
		<dc:creator><![CDATA[Martin T.]]></dc:creator>
		<pubDate>Wed, 22 Apr 2026 20:30:00 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Tips]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=16193</guid>

					<description><![CDATA[In the new DrawControlInLayoutEditor event of Xojo, which is available for MobileCanvas, AndroidMobileUserControl, and iOSMobileUserControl, there are properties available that otherwise do not exist in&#8230;]]></description>
										<content:encoded><![CDATA[
<p>In the new DrawControlInLayoutEditor event of Xojo, which is available for <a href="https://documentation.xojo.com/api/user_interface/mobile/mobilecanvas.html#mobilecanvas">MobileCanvas</a>, AndroidMobileUserControl, and iOSMobileUserControl, there are properties available that otherwise do not exist in the Graphics class for mobile projects.</p>



<p>Specifically, the following properties can be used there:</p>



<ul class="wp-block-list">
<li>Graphics.FontName</li>



<li>Graphics.FontSize</li>



<li>Graphics.FontAscent</li>
</ul>



<p>These properties are known from other Xojo targets (e.g. Desktop), but are not part of the official mobile API and are not shown in Autocomplete. They cannot be used outside of this event. </p>



<p>In contrast, the mobile API property Graphics.Font cannot be used within the DrawControlInLayoutEditor event. The usage is strictly limited to the DrawControlInLayoutEditor event. Using these properties in runtime code will result in errors.</p>



<p>These properties allow for more accurate text rendering in the layout editor, for example in custom controls where font metrics need to be considered. </p>



<p>Although these properties are not part of the mobile API, they can be used selectively within the layout editor context.</p>



<p>This code will work fine in your mobile control’s DrawControlInLayoutEditor event:</p>



<pre class="wp-block-code"><code>Var s As String = "Happy coding!"
Var x As Double = g.Width / 2 - g.TextWidth(s) / 2
Var y As Double = g.Height / 2 - g.TextHeight / 2 + g.FontAscent

g.DrawingColor = Color.Red
g.DrawOval(0, 0, g.Width, g.Height)

g.DrawingColor = TextColor
g.Bold = True
g.FontName = "Times New Roman"
g.FontSize = 16
g.DrawText(s, x, y)</code></pre>



<figure class="wp-block-image size-large is-resized"><img fetchpriority="high" decoding="async" width="571" height="1024" src="https://blog.xojo.com/wp-content/uploads/2026/04/Bildschirmfoto-2026-04-15-um-02.17.17-571x1024.png" alt="" class="wp-image-16194" style="aspect-ratio:0.557587099017292;width:325px;height:auto" srcset="https://blog.xojo.com/wp-content/uploads/2026/04/Bildschirmfoto-2026-04-15-um-02.17.17-571x1024.png 571w, https://blog.xojo.com/wp-content/uploads/2026/04/Bildschirmfoto-2026-04-15-um-02.17.17-167x300.png 167w, https://blog.xojo.com/wp-content/uploads/2026/04/Bildschirmfoto-2026-04-15-um-02.17.17-768x1377.png 768w, https://blog.xojo.com/wp-content/uploads/2026/04/Bildschirmfoto-2026-04-15-um-02.17.17.png 852w" sizes="(max-width: 571px) 100vw, 571px" /></figure>



<p>Happy coding!</p>



<p><em>Martin T. is a Xojo MVP and has been very involved in testing Android support.</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>Android Design Extensions 4.5</title>
		<link>https://blog.xojo.com/2026/04/09/android-design-extensions-4-5/</link>
		
		<dc:creator><![CDATA[Martin T.]]></dc:creator>
		<pubDate>Thu, 09 Apr 2026 15:00:00 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Android Design Extensions]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=16166</guid>

					<description><![CDATA[Xojo 2026r1 has just been released, and it was time to revisit and update the Android Design Extensions. They are now available in version 4.5.&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Xojo 2026r1 has just been released, and it was time to revisit and update the Android Design Extensions. They are now available in version 4.5. This release focuses on the MobileSlider control, which in Xojo 2026r1 now uses the modern Material Slider under the hood (<a href="https://developer.android.com/reference/com/google/android/material/slider/Slider" target="_blank" rel="noreferrer noopener">https://developer.android.com/reference/com/google/android/material/slider/Slider</a>). This update provides a huge number of new possibilities for customizing the appearance of the MobileSlider, giving your Android apps much greater flexibility in designing their UI.</p>



<p>In total, more than 60 new declares have been added for MobileSlider, allowing you to control virtually every UI parameter of the control—whether it’s the shape of the thumb, its color, the track colors (both for the active/left and inactive/right portions), and much more. You can also set the step size, similar to what you’re used to on the desktop.</p>



<figure class="wp-block-image size-large is-resized"><img decoding="async" width="461" height="1024" src="https://blog.xojo.com/wp-content/uploads/2026/04/android-image-1-461x1024.png" alt="" class="wp-image-16167" style="aspect-ratio:0.5625;object-fit:cover;width:337px;height:auto" srcset="https://blog.xojo.com/wp-content/uploads/2026/04/android-image-1-461x1024.png 461w, https://blog.xojo.com/wp-content/uploads/2026/04/android-image-1-135x300.png 135w, https://blog.xojo.com/wp-content/uploads/2026/04/android-image-1-768x1707.png 768w, https://blog.xojo.com/wp-content/uploads/2026/04/android-image-1-691x1536.png 691w, https://blog.xojo.com/wp-content/uploads/2026/04/android-image-1-922x2048.png 922w, https://blog.xojo.com/wp-content/uploads/2026/04/android-image-1.png 1080w" sizes="(max-width: 461px) 100vw, 461px" /></figure>



<p>Just take a look at the updated Android Design Extensions demo app and try it out.</p>



<p>Feel free to take a look at the developer repository, create feature requests, and provide feedback on extending this extension library. I’m happy to receive any voluntary financial support for the work I’ve done so far, which you are welcome to share <a href="https://www.paypal.com/paypalme/MTrippensee">here</a>. You can download the project with many examples at <a href="https://github.com/XojoGermany/AndroidDesignExtensions" target="_blank" rel="noreferrer noopener">https://github.com/XojoGermany/AndroidDesignExtensions</a>.</p>



<p>Happy coding!</p>



<p><em>Martin T. is a Xojo MVP and has been very involved in testing Android support.</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>Using Custom URI to Compliment your Web Application</title>
		<link>https://blog.xojo.com/2026/04/06/using-custom-uri-to-compliment-your-web-application/</link>
		
		<dc:creator><![CDATA[Wayne Golding]]></dc:creator>
		<pubDate>Mon, 06 Apr 2026 14:10:00 +0000</pubDate>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Custom URI URL Protocol]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=16094</guid>

					<description><![CDATA[There are times when you will want to use the resources of your web application’s user computer, for example, printing a sales docket for a&#8230;]]></description>
										<content:encoded><![CDATA[
<p>There are times when you will want to use the resources of your web application’s user computer, for example, printing a sales docket for a Point-Of-Sale site. In this article, I will expand on William Yu’s blog post <a href="https://blog.xojo.com/2016/08/16/custom-uri-schemes-on-windows/">Custom URI Schemes On Windows</a> from 2016. Again, I’m going to use a simple alert-type application, add an Inno Setup script to install the client app, and show how to invoke that app from your web application.</p>



<p>First, I’m going to create a headless desktop application. A console application would work, but shows a command box.</p>



<p>In the Xojo IDE, create a new desktop project and delete Window1 and MainMenuBar. Then add the Opening Event Handler to App and add this code:</p>



<pre class="wp-block-code"><code>Self.AllowAutoQuit = True</code></pre>



<p>This will allow the application to quit when done.</p>



<p>Add the DocumentOpened Event Handler to App and add this code:</p>



<pre class="wp-block-code"><code>If item _ ' Using item
 .NativePath _ ' property NativePath
 .NthField(":", 1) &lt;> "AlertDemo" Then ' Compare the value left of the ":"
 Return ' If invalid return (quit)
End If
Var alert As String ' Define the variable
alert = item _ ' Using Item
 .NativePath _ ' property NativePath
 .NthField(":", 2) ' Extract the contents to the right of the ":"

alert = DecodeURLComponent(alert) ' Convert the content to plain text
MessageBox(alert) ' Show the alert
' The app will now quit</code></pre>



<p>To test you can select Shared in Build Settings.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="366" height="183" src="https://blog.xojo.com/wp-content/uploads/2026/03/image.png" alt="" class="wp-image-16095" srcset="https://blog.xojo.com/wp-content/uploads/2026/03/image.png 366w, https://blog.xojo.com/wp-content/uploads/2026/03/image-300x150.png 300w" sizes="(max-width: 366px) 100vw, 366px" /></figure>



<p><br>And enter a value into Command Line Arguments:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="595" height="126" src="https://blog.xojo.com/wp-content/uploads/2026/03/image-1.png" alt="" class="wp-image-16096" srcset="https://blog.xojo.com/wp-content/uploads/2026/03/image-1.png 595w, https://blog.xojo.com/wp-content/uploads/2026/03/image-1-300x64.png 300w" sizes="auto, (max-width: 595px) 100vw, 595px" /></figure>



<p><br>Running the app in debug mode will show:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="231" height="237" src="https://blog.xojo.com/wp-content/uploads/2026/03/image-2.png" alt="" class="wp-image-16097"/></figure>



<p><br>Now build the project and create an installer using <a href="https://jrsoftware.org/isinfo.php">Inno Setup</a>.</p>



<pre class="wp-block-preformatted">[Setup]<br>AppId={{B4D9ABDA-9F58-4FE0-A5F3-3E39C28EAB59}<br>AppName=Alert Demo<br>AppVersion=1.0<br>DefaultDirName={commonpf64}\Axis Direct Ltd\Alert Demo<br>DefaultGroupName=Axis Direct<br>OutputDir=C:\Xojo Projects\Alert Demo\Installer<br>OutputBaseFilename=AlertDemoInstaller<br>Compression=lzma<br>SolidCompression=yes<br>ChangesEnvironment=yes<br>[Languages]<br>Name: "english"; MessagesFile: "compiler:Default.isl"<br>[Tasks]<br>[Dirs]<br>Name: "{app}\Alert Demo Libs"<br>[Files]<br>Source: "C:\Xojo Projects\Alert Demo\Project\Builds - Alert<br>Demo\Windows 64 bit\Alert Demo*"; DestDir: "{app}"; Flags:<br>ignoreversion<br>Source: "C:\Xojo Projects\Alert Demo\Project\Builds - Alert<br>Demo\Windows 64 bit\Alert Demo\Alert Demo Libs*"; DestDir:<br>"{app}\Alert Demo Libs"; Flags: ignoreversion<br>[Icons]<br>[Run]<br>[Registry]<br>Root: HKCR; Subkey: "AlertDemo"; Flags: uninsdeletekey<br>Root: HKCR; Subkey: "AlertDemo"; ValueType: "String";<br>ValueData: "URL:AlertDemo Protocol"; Flags: uninsdeletekey<br>Root: HKCR; Subkey: "AlertDemo"; ValueName: "URL Protocol";<br>ValueType: "String"; ValueData: ""; Flags: uninsdeletekey<br>Root: HKCR; Subkey: "AlertDemo\shell"; Flags: uninsdeletekey<br>Root: HKCR; Subkey: "AlertDemo\shell\open"; Flags:<br>uninsdeletekey<br>Root: HKCR; Subkey: "AlertDemo\shell\open\command"; Flags:<br>uninsdeletekey<br>Root: HKCR; Subkey: "AlertDemo\shell\open\command";<br>ValueType: String; ValueData: "{app}\Alert Demo.exe %1";<br>Flags: uninsdeletekey</pre>



<p>The registry section creates the registry entries per <a href="https://blog.xojo.com/2016/08/16/custom-uri-schemes-on-windows/">William’s blog post</a>.</p>



<p>Now that the application Is installed, we’ll look at the Web Application. For the sake of testing, I’m just adding a Button to a WebPage and adding the following code into the pressed event.</p>



<pre class="wp-block-code"><code>Var s As String = "Hello World"
Var Alert As String
Alert = EncodeURLComponent(s) ' Make the string URL safe
GoToURL("AlertDemo:" + Alert, True) ' Launch the app in a new tab</code></pre>



<p>And that is it!</p>



<p>For printing a docket, I would pass a unique identifier for the transaction using this method then access the data using URLConnection &amp; HandleURL.</p>



<p><em>Wayne Golding has been a Xojo developer since 2005 and is a Xojo MVP. He operates the IT Company <a href="http://www.axisdirect.nz">Axis Direct Ltd </a>which primarily develops applications using Xojo that integrate with Xero www.xero.com. Wayne’s hobby is robotics where he uses Xojo to build applications for his Raspberry Pi, often implementing IoT for remote control.</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>Conditional Compilation in Xojo: #If False and #If True</title>
		<link>https://blog.xojo.com/2026/04/03/conditional-compilation-in-xojo-if-false-and-if-true/</link>
		
		<dc:creator><![CDATA[Martin T.]]></dc:creator>
		<pubDate>Fri, 03 Apr 2026 13:42:00 +0000</pubDate>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Software Development]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=16107</guid>

					<description><![CDATA[If you&#8217;ve been working with Xojo for a while, you&#8217;re likely familiar with conditional compilation directives like #If TargetMacOS or #If DebugBuild. But there are&#8230;]]></description>
										<content:encoded><![CDATA[
<p>If you&#8217;ve been working with Xojo for a while, you&#8217;re likely familiar with conditional compilation directives like <code>#If TargetMacOS</code> or <code>#If DebugBuild</code>. But there are two particularly useful variants that are often overlooked in day-to-day development: <code>#If False</code> and <code>#If True</code>. In this article, we&#8217;ll look at what these directives do, when to use them, and why they can be a better choice than regular comments in certain situations.</p>



<h2 class="wp-block-heading">What Is Conditional Compilation?</h2>



<p>Conditional compilation allows you to include or completely exclude sections of code from the final application based on a condition. Unlike an <code>If</code> statement at runtime, this decision is made at compile time. Code excluded through conditional compilation simply does not exist in the compiled application.</p>



<h2 class="wp-block-heading">#If False – Completely Excluding Code</h2>



<pre class="wp-block-code"><code>#If False
  MessageBox("This line will never be compiled")
  Var result As Integer = DoSomething()
#EndIf</code></pre>



<p>When the condition is <code>False</code>, the entire block is ignored by the compiler. It is not compiled, not included in the application, and not even checked for syntax errors. The code is effectively invisible to the compiler.</p>



<h3 class="wp-block-heading">Why Not Just Comment It Out?</h3>



<p>At first glance, <code>#If False</code> seems to do the same thing as a comment. But there are key differences:</p>



<p><strong>1. Nested Comments Are No Problem</strong></p>



<p>If a code block already contains comments, commenting out the entire block quickly becomes messy:</p>



<pre class="wp-block-code"><code>' Var x As Integer = 42 ' Default value
' Var y As Integer = x * 2 ' double it
' ' This is already a comment</code></pre>



<p>With <code>#If False</code>, everything stays clean:</p>



<pre class="wp-block-code"><code>#If False
  Var x As Integer = 42 ' Default value
  Var y As Integer = x * 2 ' double it
  ' This is already a comment
#EndIf</code></pre>



<p><strong>2. Incomplete or Broken Code</strong></p>



<p>Sometimes you want to keep an unfinished code draft without it preventing the build. Since the compiler completely skips the contents of an <code>#If False</code> block, the code inside may even contain syntax errors:</p>



<pre class="wp-block-code"><code>#If False
  ' Experimental approach – not finished yet
  Var data As  = LoadFromServer(
  ProcessResult(data
#EndIf</code></pre>



<p>This code would be useless as a comment because you&#8217;d have to comment out each line individually. With <code>#If False</code>, it&#8217;s safely stored away.</p>



<p><strong>3. Quickly Disabling Large Code Blocks</strong></p>



<p>For larger sections, <code>#If False</code> / <code>#EndIf</code> is far more practical than prefixing every line with <code>'</code>. Plus, the block can be reactivated instantly by simply changing <code>False</code> to <code>True</code>.</p>



<h2 class="wp-block-heading">#If True – Always Including Code</h2>



<pre class="wp-block-code"><code>#If True
  MessageBox("This line will always be compiled")
#EndIf</code></pre>



<p>An <code>#If True</code> block is always compiled — it behaves identically to regular code. This might sound useless at first, but it does have practical applications.</p>



<h3 class="wp-block-heading">When Is <code>#If True</code> Useful?</h3>



<p><strong>1. Quick Toggling During Development</strong></p>



<p>Imagine you&#8217;re working on a feature and want to quickly enable or disable certain code sections:</p>



<pre class="wp-block-code"><code>#If True ' &lt;- Set to False to disable the new feature
  ' New feature
  Var service As New CloudSyncService
  service.SyncNow()
#EndIf</code></pre>



<p>By simply changing <code>True</code> to <code>False</code>, you can disable the feature without deleting or commenting out any code.</p>



<p><strong>2. Placeholder for Future Conditions</strong></p>



<p>Sometimes you already know that a code section will later be tied to a condition — such as a platform or build type. With <code>#If True</code>, you can prepare the structure in advance:</p>



<pre class="wp-block-code"><code>#If True ' TODO: Change to TargetMacOS once Windows alternative is ready
  Var folderPath As String = SpecialFolder.Applications.NativePath
#EndIf</code></pre>



<p><strong>3. Visual Code Grouping</strong></p>



<p>In longer methods, <code>#If True</code> can serve as a visual structural block to highlight related code:</p>



<pre class="wp-block-code"><code>#If True ' --- Initialization ---
  Var db As New SQLiteDatabase
  db.DatabaseFile = dbFile
  db.Connect
#EndIf

#If True ' --- Load data ---
  Var rs As RowSet = db.SelectSQL("SELECT * FROM users")
#EndIf</code></pre>



<h2 class="wp-block-heading">Defining Custom Compiler Constants</h2>



<p>Xojo also allows you to define your own constants for conditional compilation.</p>



<pre class="wp-block-code"><code>#If kEnableLogging
  WriteToLog("Application started")
#EndIf</code></pre>



<p>This lets you control features or debug functionality centrally through a constant without having to modify the code itself.</p>



<h2 class="wp-block-heading">Best Practices</h2>



<ol class="wp-block-list">
<li><strong><code>#If False</code> instead of mass comments</strong>: For larger code blocks that need to be temporarily disabled, <code>#If False</code> is the cleaner solution.</li>



<li><strong>Add a comment</strong>: Always document <em>why</em> a block is disabled:</li>
</ol>



<pre class="wp-block-code"><code>#If False ' Disabled until bug #1234 is fixed
  ProcessCriticalData()
 #EndIf</code></pre>



<ol start="3" class="wp-block-list">
<li><strong>Don&#8217;t use permanently</strong>: <code>#If False</code> blocks should not remain in the code indefinitely. If the code is no longer needed, remove it. If it is needed, activate it.</li>



<li><strong>Prefer platform directives</strong>: When dealing with platform-specific code, use the specific constants (<code>TargetMacOS</code>, <code>TargetWindows</code>, etc.) instead of <code>#If True</code> or <code>#If False</code>.</li>



<li><strong>Avoid deep nesting</strong>: While nested <code>#If</code> blocks are possible, use them sparingly as they quickly reduce readability.</li>
</ol>



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



<p><code>#If False</code> and <code>#If True</code> are simple yet powerful tools for everyday Xojo development. They offer a cleaner alternative to commenting out large code blocks, enable quick feature toggling during development, and lay the groundwork for a structured, cross-platform codebase. Used thoughtfully, they save time and help you stay organized — even in larger projects.</p>



<p>If you want to automatically convert a selection into a #If/#EndIf block, you can do so via the context menu: &#8220;Wrap In > #If / #EndIf&#8221;</p>



<p>Happy coding.</p>



<p><em>Martin T. is a Xojo MVP and has been very involved in testing Android support.</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>Building an AI Pair Programmer for Xojo Developers</title>
		<link>https://blog.xojo.com/2026/03/09/building-an-ai-pair-programmer-for-xojo-developers/</link>
		
		<dc:creator><![CDATA[Garry Pettet]]></dc:creator>
		<pubDate>Mon, 09 Mar 2026 15:00:00 +0000</pubDate>
				<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[AI Code Generation]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Zotto]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=15902</guid>

					<description><![CDATA[If you&#8217;ve tried using ChatGPT, Claude, or Gemini for help with Xojo code, you&#8217;ve probably experienced the same frustration most of us have: the AI&#8230;]]></description>
										<content:encoded><![CDATA[
<p>If you&#8217;ve tried using ChatGPT, Claude, or Gemini for help with Xojo code, you&#8217;ve probably experienced the same frustration most of us have: the AI doesn&#8217;t <em>know</em> your project. You end up copying and pasting classes, explaining your architecture, and then watching it hallucinate method or framework names that don&#8217;t exist. It works, sort of, but it&#8217;s clunky.</p>



<p>I wanted something better. Not a generic chatbot that happens to know some Xojo, but a tool that could actually <em>see</em> what I was working on. That&#8217;s why I built Zotto (with Xojo!).</p>



<h2 class="wp-block-heading">What Is Zotto?</h2>



<p>Zotto is a cross-platform macOS and Windows app that acts as an AI pair programmer specifically for Xojo developers. It connects directly to the Xojo IDE, reads the project you&#8217;re working on, and gives the AI real context about your code such as classes, method signatures, properties. Essentially the whole project&#8217;s structure.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="853" src="https://blog.xojo.com/wp-content/uploads/2026/03/appearance-1024x853.png" alt="" class="wp-image-15906" srcset="https://blog.xojo.com/wp-content/uploads/2026/03/appearance-1024x853.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/03/appearance-300x250.png 300w, https://blog.xojo.com/wp-content/uploads/2026/03/appearance-768x640.png 768w, https://blog.xojo.com/wp-content/uploads/2026/03/appearance.png 1154w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">The Problem It Solves</h2>



<p>The core issue with using general-purpose AI tools for Xojo development is context. When you ask Claude or ChatGPT a question about your project, the AI has no idea what your codebase looks like. You become the middleman, manually feeding it snippets and hoping it has enough information to give useful advice.</p>



<p>Zotto removes some of that friction. When connected to the IDE, the AI can explore your project on its own using built-in tools:</p>



<ul class="wp-block-list">
<li><strong>ProjectOverview</strong> gives it the high-level folder structure</li>



<li><strong>ListItems</strong> lets it drill into specific folders</li>



<li><strong>GetSignatures</strong> shows method and property signatures without dumping all the code</li>



<li><strong>ReadCode</strong> pulls up full method implementations when needed</li>



<li><strong>SearchCode</strong> does grep-like pattern searches across the codebase</li>



<li><strong>SearchDocs</strong> lets it search and retrieve Xojo documentation directly</li>
</ul>



<p>These tools are designed to be token-efficient. Instead of dumping your entire project into the context window, the AI requests only what it needs, when it needs it. A <code>ProjectOverview</code> call might use 300-500 tokens. A <code>GetSignatures</code> call on a class gives the AI the API surface without the implementation details. This layered approach means even large projects work well within context limits.</p>



<h2 class="wp-block-heading">Read-Only by Design</h2>



<p>One decision I made early on was that Zotto would be read-only. It can read your code, analyse it, suggest changes, and generate snippets — but it cannot modify your project files, create new items, or execute IDE scripts.</p>



<p>This is intentional. I think AI-generated code should be reviewed by a developer before it goes into a project. Zotto gives you copy-pasteable suggestions and lets you decide what to implement. You stay in control.</p>



<h2 class="wp-block-heading">Bring Your Own Model</h2>



<p>Zotto isn&#8217;t locked to a single AI provider. It supports Claude, OpenAI, Gemini, Ollama, LM Studio, and any OpenAI-compatible API (which covers services like Grok and OpenRouter). If you&#8217;re privacy-conscious or working on sensitive code, you can run it entirely offline with a local model through Ollama or LM Studio. Your code never has to leave your machine.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="988" height="961" src="https://blog.xojo.com/wp-content/uploads/2026/03/provider-settings.png" alt="" class="wp-image-15909" srcset="https://blog.xojo.com/wp-content/uploads/2026/03/provider-settings.png 988w, https://blog.xojo.com/wp-content/uploads/2026/03/provider-settings-300x292.png 300w, https://blog.xojo.com/wp-content/uploads/2026/03/provider-settings-768x747.png 768w" sizes="auto, (max-width: 988px) 100vw, 988px" /></figure>



<p>This also means you&#8217;re not paying for Zotto&#8217;s AI usage — you use your own API keys or local models, so you&#8217;re in full control of costs.</p>



<h2 class="wp-block-heading">How It Works in Practice</h2>



<p>A typical workflow looks like this:</p>



<ol class="wp-block-list">
<li>Open your project in the Xojo IDE</li>



<li>Launch Zotto — it detects the IDE automatically</li>



<li>Select which open project to work with</li>



<li>Start chatting</li>
</ol>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="757" src="https://blog.xojo.com/wp-content/uploads/2026/03/chat-window-1024x757.png" alt="" class="wp-image-15908" srcset="https://blog.xojo.com/wp-content/uploads/2026/03/chat-window-1024x757.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/03/chat-window-300x222.png 300w, https://blog.xojo.com/wp-content/uploads/2026/03/chat-window-768x568.png 768w, https://blog.xojo.com/wp-content/uploads/2026/03/chat-window.png 1280w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>From there, you might ask the AI to review a class, suggest how to refactor a method, help you understand unfamiliar code in a project you&#8217;ve inherited, or brainstorm an approach to a new feature. Because the AI can explore the project itself, the conversation feels much more natural than the copy-paste dance with a generic chatbot.</p>



<p>For example, you could ask: &#8220;What does the <code>ProcessOrder</code> method in <code>OrderManager</code> do?&#8221; Instead of you having to find and paste the code, Zotto&#8217;s AI will call <code>ReadCode</code> to look at the method itself, then maybe <code>GetSignatures</code> on the parent class to understand the broader context, and give you a thorough explanation.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="853" src="https://blog.xojo.com/wp-content/uploads/2026/03/coding-settings-1024x853.png" alt="" class="wp-image-15910" srcset="https://blog.xojo.com/wp-content/uploads/2026/03/coding-settings-1024x853.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/03/coding-settings-300x250.png 300w, https://blog.xojo.com/wp-content/uploads/2026/03/coding-settings-768x640.png 768w, https://blog.xojo.com/wp-content/uploads/2026/03/coding-settings.png 1154w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">Extending with MCP</h2>



<p>For developers who want to go further, Zotto supports the Model Context Protocol (MCP). This lets you add custom tool servers — for file system access, Git operations, database queries, or anything else you might want the AI to have access to during a conversation. It&#8217;s the same protocol that Claude Desktop and other AI tools support, so existing MCP servers work out of the box.</p>



<h2 class="wp-block-heading">Built for the Community</h2>



<p>Zotto exists because I needed it for my own Xojo development. I was spending too much time being the translator between AI tools and my codebase. Once I had something working, it seemed like other Xojo developers would find it useful too.</p>



<p>There&#8217;s a free version you can try that includes full IDE integration and all the built-in tools with a single conversation. A full license is a one-time purchase of £69 — no subscription. You can learn more and download it at <a href="https://zotto.app" target="_blank" rel="noreferrer noopener">zotto.app</a>.</p>



<p>If you have questions or feedback, I&#8217;d love to hear from you on the <a href="https://forum.xojo.com/" target="_blank" rel="noreferrer noopener">forum</a>.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p><em>Garry Pettet is a Consultant Radiologist, Xojo developer and the creator of Zotto. You can find him on the Xojo <a href="https://forum.xojo.com/">forum</a> or at <a href="https://zotto.app" target="_blank" rel="noreferrer noopener">zotto.app</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>Community Contributions to the Xojo Blog: Spotlight On &#038; Guest Posts in 2025</title>
		<link>https://blog.xojo.com/2025/12/18/community-contributions-to-the-xojo-blog-spotlight-on-guest-posts-in-2025/</link>
		
		<dc:creator><![CDATA[Alyssa Foley]]></dc:creator>
		<pubDate>Thu, 18 Dec 2025 20:25:07 +0000</pubDate>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Fun]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=15448</guid>

					<description><![CDATA[Besides being a great resource for everything from Xojo code tips and snippets to videos that show you cool things, plus news and announcements, the&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Besides being a great resource for everything from Xojo code tips and snippets to videos that show you cool things, plus news and announcements, the Xojo Blog also strives to build community among the wide range of people who use Xojo around the world. We welcome guest bloggers from the Xojo community and highlight the many different ways people use Xojo through our Spotlight On series.</p>



<p>In 2025, guest authors shared their expertise and real-world experience on the Xojo Blog. These posts bring fresh perspectives, practical solutions and deep technical insight that help other developers learn faster, solve problems more effectively and feel more connected to the Xojo community.</p>



<p>Guest posts in 2025 included:</p>



<ul class="wp-block-list">
<li>Martin T., Xojo MVP: <a href="https://blog.xojo.com/2025/09/25/hide-the-tabs-in-an-android-mobiletabpanel-using-declares/" target="_blank" rel="noreferrer noopener">Hide the Tabs in an Android MobileTabPanel Using Declares</a></li>



<li>Martin T., Xojo MVP: <a href="https://blog.xojo.com/2025/09/16/xojo-for-android-a-two-year-retrospective/" target="_blank" rel="noreferrer noopener">Xojo for Android: A Two-Year Retrospective</a></li>



<li>Martin T., Xojo MVP: <a href="https://blog.xojo.com/2025/07/08/its-here-android-design-extensions-4-0/" target="_blank" rel="noreferrer noopener">It’s here – Android Design Extensions 4.0</a></li>



<li>Anthony Cyphers, GraffitiSuite and Xojo MVP: <a href="https://blog.xojo.com/2025/03/15/handling-feature-requests/" target="_blank" rel="noreferrer noopener">Handling Feature Requests</a></li>



<li>Kem Tekinay, Xojo MVP: <a href="https://blog.xojo.com/2025/02/26/memoryblocks-for-speed-a-case-study/" target="_blank" rel="noreferrer noopener">MemoryBlocks For Speed: A Case Study</a></li>



<li>Kem Tekinay, Xojo MVP: <a href="https://blog.xojo.com/2025/12/16/the-beauty-of-binary-searches/">The Beauty of Binary Searches</a></li>



<li>Jürg Otter: <a href="https://blog.xojo.com/2025/02/25/build-a-xojo-plugin-with-github-actions/" target="_blank" rel="noreferrer noopener">Build a Xojo Plugin with GitHub Actions</a></li>



<li>Ezekiel Burke, <em><a href="https://ironelephantsolutions.com/" target="_blank" rel="noreferrer noopener">Iron Elephant Solutions</a></em>: <a href="https://blog.xojo.com/2025/02/19/introduction-to-pocketbase-a-backend-alternative-for-xojo-developers/" target="_blank" rel="noreferrer noopener">Introduction to PocketBase: A Backend Alternative for Xojo Developers</a></li>
</ul>



<p>We are always looking for users in the Xojo community who want to share a problem they’ve solved, a creative solution or an interesting project. If you’re interested in contributing a guest post or have an idea you’d like to explore, send it to me at <a>alyssa@xojo.com</a>.</p>



<p>In 2024, we introduced the Spotlight On series to highlight the work Xojo users do and their experiences using Xojo. Since many Xojo users don’t fit the mold of a traditional developer role, Spotlight On offers a fun and approachable way to learn how someone got started with Xojo and how they use it today. Spotlights can focus on an individual developer, a business or a specific Xojo-based project.</p>



<p>Spotlight On features in 2025:</p>



<ul class="wp-block-list">
<li><a href="https://blog.xojo.com/2024/06/13/spotlight-on-graffitisuite/" target="_blank" rel="noreferrer noopener">Spotlight On: GraffitiSuite</a></li>



<li><a href="https://blog.xojo.com/2024/07/08/spotlight-on-xdev-magazine/" target="_blank" rel="noreferrer noopener">Spotlight On: xDev Magazine</a></li>



<li><a href="https://blog.xojo.com/2024/08/14/spotlight-on-lx-aer/" target="_blank" rel="noreferrer noopener">Spotlight On: LX Aer</a></li>



<li><a href="https://blog.xojo.com/2024/10/16/spotlight-on-eklectic-accounting/" target="_blank" rel="noreferrer noopener">Spotlight On: EKlectic Accounting</a></li>



<li><a href="https://blog.xojo.com/2024/11/12/spotlight-on-raximus-studios/" target="_blank" rel="noreferrer noopener">Spotlight On: Raximus Studios</a></li>



<li><a href="https://blog.xojo.com/2024/12/19/spotlight-on-richard-klingler/" target="_blank" rel="noreferrer noopener">Spotlight On: Richard Klingler</a></li>



<li><a href="https://blog.xojo.com/2025/01/21/spotlight-on-enrique-contreras/" target="_blank" rel="noreferrer noopener">Spotlight On: Enrique Contreras</a></li>



<li><a href="https://blog.xojo.com/2025/02/11/spotlight-on-offroad-portal/" target="_blank" rel="noreferrer noopener">Spotlight On: Offroad Portal</a></li>



<li><a href="https://blog.xojo.com/2025/03/10/spotlight-on-tim-dietrich/" target="_blank" rel="noreferrer noopener">Spotlight On: Tim Dietrich</a></li>



<li><a href="https://blog.xojo.com/2025/06/11/spotlight-on-sounds-in-sync/" target="_blank" rel="noreferrer noopener">Spotlight On: Sounds In Sync</a></li>



<li><a href="https://blog.xojo.com/2025/09/22/spotlight-on-android-design-extensions/" target="_blank" rel="noreferrer noopener">Spotlight On: Android Design Extensions</a></li>



<li><a href="https://blog.xojo.com/2025/10/09/spotlight-on-aaron-andrew-hunt/" target="_blank" rel="noreferrer noopener">Spotlight On: Aaron Andrew Hunt</a></li>
</ul>



<p>If you’d like to be featured in a future Spotlight On or know someone in the Xojo community whose story would be great to share, we’d love to hear from you. Reach out with suggestions to me at <a>alyssa@xojo.com</a>.</p>



<p>The Xojo Blog is at its best when it reflects the voices, experiences and creativity of the community itself. Whether through guest posts, Spotlight On posts or shared ideas, we look forward to continuing to learn from and celebrate the people who make Xojo what it is.</p>



<p><em>Alyssa has been with Xojo for over 18 years. She loves solving problems and building community. You can reach her at alyssa@xojo.com or through any of Xojo&#8217;s social media channels. If you can&#8217;t reach her she&#8217;s probably out hiking the beautiful trails through her city of Portland, Oregon, or maybe enjoying a drink with friends by the river. </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>The Beauty of Binary Searches</title>
		<link>https://blog.xojo.com/2025/12/16/the-beauty-of-binary-searches/</link>
		
		<dc:creator><![CDATA[Kem Tekinay]]></dc:creator>
		<pubDate>Tue, 16 Dec 2025 17:14:00 +0000</pubDate>
				<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Binary]]></category>
		<category><![CDATA[Software Development]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=15715</guid>

					<description><![CDATA[Problem: you need to search an array to see if it contains a particular value. The simple solution is IndexOf if it’s a simple array, or a&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Problem: you need to search an array to see if it contains a particular value. The simple solution is <code>IndexOf</code> if it’s a simple array, or a loop like this:</p>



<pre class="wp-block-code"><code>for each item as ArrayType in myArray
  if item.Matches( myValue ) then
    YesSiree( myValue )
    exit
  end if
next</code></pre>



<p>That’s pretty easy, but what if the array is really big? And what if you have to do this many times?</p>



<p>For example, let’s say your array has 10,000 items. For each value that doesn’t match, your code will have to do 10,000 comparisons. But, if your array can be sorted, you can perform that task with, at most, 14 comparisons using a binary search.</p>



<p>The concept is simple: you take an ordered list and start in the middle. If what you’re trying to match is less than that point, you discard the upper half of the list, then start again at the midpoint of the rest. By continuously cutting the list in half, you will do, at most,&nbsp;<code>Ceil(Log2(arrayCount))</code>&nbsp;comparisons per value.</p>



<p>For simplicity’s sake, let’s say you want to search an array of strings. (Yes, a&nbsp;<code>Dictionary</code>&nbsp;would be the better choice here, but this is just for illustration.) The code would look something like this:</p>



<pre class="wp-block-code"><code>myArray.Sort

var firstIndex as integer = 0
var lastIndex as integer = myArray.LastIndex

while firstIndex &lt;= lastIndex
  var midPoint as integer = ( lastIndex - firstIndex ) \ 2 + firstIndex

  var compare as string = myArray( midPoint )

  if myValue = compare then
    YesSiree( myValue )
    exit
  end if

  if myValue &lt; compare then
    lastIndex = midPoint - 1
  else
    firstIndex = midPoint + 1
  end if
wend</code></pre>



<p>With that 10,000-item array, the first loop would look at item 5,000. If&nbsp;<code>myValue</code>&nbsp;is greater than that, it would next look at item 7,500. Still greater? Now it will look at item 8,750, and so on. The entire array will be processed efficiently with large chunks never needing examination at all. If you have to do this for 1,000 different values, you will end with, at most, 14,000 comparisons instead of 10&nbsp;million.</p>



<p>Quite the savings, right?</p>



<p><em>Kem Tekinay is a Mac consultant and programmer who has been using Xojo since its first release to create custom solutions for clients. He is the author of the popular utilities <a href="http://www.mactechnologies.com/index.php?page=downloads#tftpclient" target="_blank" rel="noreferrer noopener">TFTP Client</a> and <a href="http://www.mactechnologies.com/index.php?page=downloads#regexrx" target="_blank" rel="noreferrer noopener">RegExRX</a> (both written with Xojo) and lives in Connecticut with his wife Lisa, and their cat.</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>Hide the Tabs in an Android MobileTabPanel Using Declares</title>
		<link>https://blog.xojo.com/2025/09/25/hide-the-tabs-in-an-android-mobiletabpanel-using-declares/</link>
		
		<dc:creator><![CDATA[Martin T.]]></dc:creator>
		<pubDate>Thu, 25 Sep 2025 16:47:58 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Declares]]></category>
		<category><![CDATA[PagePanel]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=15409</guid>

					<description><![CDATA[Here’s how you can modify Xojo Android’s MobileTabPanel to behave more like the PagePanel found in Xojo Desktop and Web. A TabPanel, as the name&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Here’s how you can modify Xojo Android’s MobileTabPanel to behave more like the PagePanel found in Xojo Desktop and Web. A TabPanel, as the name suggests, shows tabs for the panels, while a PagePanel does not. Using PagePanel can be very useful in situations where you need greater freedom in designing your UI. With just a few lines of code, you can use Declares to turn a MobileTabPanel into a PagePanel on Android. Read on to see how.</p>



<p>Create a new Android project with two container controls in the IDE, to which you add some controls. Then switch back to Screen1 in the Navigator and add a MobileSegmentedButton and a MobileTabPanel. In the Inspector, set the locking for the TabPanel to all four sides and assign both container controls to the TabPanel via the Inspector. Those are the basic preparations.</p>



<p>The MobileTabPanel is a subclass of Android’s <a href="https://developer.android.com/reference/com/google/android/material/tabs/TabLayout" target="_blank" rel="noreferrer noopener">TabLayout</a> view (com.google.android.material.tabs.TabLayout). This consists of the tabs themselves and a so-called ViewPager that holds the containers.</p>



<p>First, we remove the top tab bar from the control. After that, we update the position of the area where the containers are displayed. Then we disable the swipe gesture (optional). And that’s it. </p>



<p>Now add the Opening event to TabPanel1. First, we add two Android-specific import Declares so that the following Declares don’t take up too much space and readability is maintained:</p>



<pre class="wp-block-code"><code>Declare Sub import1 Lib "android.view.*:Import"
Declare Sub import2 Lib "android.widget.*:Import"</code></pre>



<p>Next, we remove the tab bar from the control:</p>



<pre class="wp-block-code"><code>' Removes the tab bar from the MobileTabPanel.
Declare Function RemoveTabs Lib "Kotlin" Alias "(ref as ViewGroup).apply { visibility = View.GONE }" (ref As Ptr) As Ptr
Call RemoveTabs(Me.Handle)</code></pre>



<p>After that, we adjust the top position of the ViewPager by setting it to 0:</p>



<pre class="wp-block-code"><code>' Update control bounds.
Declare Function GetLayoutParams Lib "Object:Me:MobileTabPanel" Alias "_tabPager!!.layoutParams" As Ptr
Declare Function UpdateLayoutParams Lib "Kotlin" Alias "(ref as FrameLayout.LayoutParams).apply { topMargin = 0 }" (ref As Ptr) As Ptr
Call UpdateLayoutParams(GetLayoutParams)</code></pre>



<p>Now add the Pressed event to the MobileSegmentedButton with this code, which ensures switching between the panels:</p>



<pre class="wp-block-code"><code>TabPanel1.SelectedPanelIndex = segmentedIndex</code></pre>



<p>And that’s it – click Run to start the project.</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" width="912" height="1024" src="https://blog.xojo.com/wp-content/uploads/2025/09/9F36A412-1902-449D-A3DD-FD062BCA4BC9-912x1024.png" alt="" class="wp-image-15411" style="width:616px;height:auto" srcset="https://blog.xojo.com/wp-content/uploads/2025/09/9F36A412-1902-449D-A3DD-FD062BCA4BC9-912x1024.png 912w, https://blog.xojo.com/wp-content/uploads/2025/09/9F36A412-1902-449D-A3DD-FD062BCA4BC9-267x300.png 267w, https://blog.xojo.com/wp-content/uploads/2025/09/9F36A412-1902-449D-A3DD-FD062BCA4BC9-768x862.png 768w, https://blog.xojo.com/wp-content/uploads/2025/09/9F36A412-1902-449D-A3DD-FD062BCA4BC9-1369x1536.png 1369w, https://blog.xojo.com/wp-content/uploads/2025/09/9F36A412-1902-449D-A3DD-FD062BCA4BC9-1825x2048.png 1825w" sizes="auto, (max-width: 912px) 100vw, 912px" /></figure>



<p><br>To make the control feel even more like a PagePanel, we now want to eliminate the ability to switch between panels with swipe gestures. To do this, go back into the TabPanel1 Opening event and add this code:</p>



<pre class="wp-block-code"><code>' Disable swipe.
Declare Sub setUserInputEnabled Lib "Object:Me:MobileTabPanel" Alias "_tabPager!!.setUserInputEnabled" (value As Boolean) setUserInputEnabled(False)</code></pre>



<p>And that’s it: the control is now a PagePanel – without tabs and within the same bounds as the TabPanel.</p>



<p>Here you can see the PagePanel in action.</p>



<div class="wp-block-media-text is-stacked-on-mobile is-vertically-aligned-top" style="grid-template-columns:37% auto"><figure class="wp-block-media-text__media"><video controls src="https://blog.xojo.com/wp-content/uploads/2025/09/pagepanel-1.mp4"></video></figure><div class="wp-block-media-text__content">
<p></p>
</div></div>



<p>Once you know where and what to look for in the Android API, there’s almost nothing you can’t already do with Declares in Xojo Android. But if you are looking for a native solution, you can join my <a href="https://tracker.xojo.com/xojoinc/xojo/-/issues/79929" target="_blank" rel="noreferrer noopener">feature request</a> to implement MobilePagePanel on Android.  </p>



<p>Happy Coding!</p>



<p><em>Martin T. is a Xojo MVP and has been very involved in testing Android support.</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/09/pagepanel-1.mp4" length="2676015" type="video/mp4" />

			</item>
		<item>
		<title>Xojo for Android: A Two-Year Retrospective</title>
		<link>https://blog.xojo.com/2025/09/16/xojo-for-android-a-two-year-retrospective/</link>
		
		<dc:creator><![CDATA[Xojo]]></dc:creator>
		<pubDate>Tue, 16 Sep 2025 20:56:38 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Android Design Extensions]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=15375</guid>

					<description><![CDATA[Xojo 2023r2 was the version in which Xojo introduced the beta release of its Android support. Now, with the release of Xojo 2025r2, it’s time&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Xojo 2023r2 was the version in which Xojo introduced the beta release of its Android support. Now, with the release of Xojo 2025r2, it’s time to take a look at what has happened over the past two years regarding Android development. With some distance from the initial launch, it’s clear that the wait was worth it. Xojo’s decision to use a Kotlin-based framework in combination with a transpiler in the background has turned out to be a smart move. Why? Because depending on the use case and the developer’s experience, there are now very few limitations to what can be done with Android projects in Xojo—if you know how to achieve it.</p>



<p>Most of the development effort over the past two years was certainly spent fixing compiler errors. In 2023 and 2024, the framework was still encountering errors during app builds. Since then, the situation has improved significantly—thanks in large part to hundreds of issues submitted by users. Example projects were particularly helpful for the Xojo team in identifying and fixing bugs. It’s always important to show Xojo how we as users work with the IDE and write our code, as our approaches often differ and expose edge cases that Xojo doesn’t cover out of the box. The past two years have therefore also helped Xojo better understand how developers actually use the product.</p>



<p>The initial Android beta in 2023 included a basic set of UI controls. Over time, four more were added: MobilePopupMenu, AndroidMobileUserControl, MobileMapViewer, as well as classes like Barcode, TCPSocket, and UserAuthentication. This brings the Android target closer to the iOS feature set, with the long-term goal of enabling unified mobile projects that can build for both platforms. However, some steps are still needed to reach that point. The Android framework itself has seen substantial improvements over the past two years. Several new classes were added to enhance the developer and user experience compared to other platforms: RegEx, Set, ColorGroup, structures, localization, dark mode support, and more.</p>



<p>I asked Paul Levebvre, the lead developer of the Android framework, what the most challenging moments over the last two years were for him: “It may have been only two years, but I feel like I’ve aged 10! I am pleased with the forward progress and it’s always great to see the amazing things that people have created with Xojo for Android. The hardest thing to get working—by a wide margin—was the debugger. Nothing else comes close. In the past two years, the most difficult things have probably been TCPSocket, Operator_Convert, ColorGroup, MapViewer, and ByRef. Right now, the plan is to continue fixing bugs and adding features to get Android to feature parity with iOS.”</p>



<p>The development of the Android Design Extensions began early in the public alpha phase of Xojo Android. This close integration led to numerous improvements and enhancements in the Android Declare engine. Today, there’s practically nothing you can’t implement on Android using Declares, even native controls—provided there’s no built-in Xojo support yet. Naturally, this does require some knowledge of the Android API and the Kotlin programming language. With the help of the <a href="https://github.com/jkleroy/iOSDesignExtensions">Android Design Extensions</a>, you can further enhance your apps, much like you might already do in your iOS projects using <a href="https://github.com/jkleroy/iOSDesignExtensions">Jérémie Leroy’s iOS Design Extensions</a>. </p>



<p>Of course, there’s still a lot of work to be done to bring Android up to the same level as iOS. For example, support for custom attributes and AttributeInfo is still missing, along with several control-specific features, the DatabaseConnection class, XML handling, PDFDocument, and more. It’s important that we test thoroughly and cover as many edge cases as possible to make Android support truly stable—and to ensure that the full Xojo language feature set works as expected. As a welcome side effect, the Xojo documentation has also improved significantly through this extensive testing. Encouraging, indeed.</p>



<p><em>Martin T. is a Xojo MVP and has been very involved in testing Android support.</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>It’s here &#8211; Android Design Extensions 4.0</title>
		<link>https://blog.xojo.com/2025/07/08/its-here-android-design-extensions-4-0/</link>
		
		<dc:creator><![CDATA[Martin T.]]></dc:creator>
		<pubDate>Tue, 08 Jul 2025 21:20:00 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Android Design Extensions]]></category>
		<category><![CDATA[MobileMapViewer]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=15123</guid>

					<description><![CDATA[Xojo 2025r2 has just been released—time for an update to the Android Design Extensions 4.0, which are compatible with all Xojo 2025r2+ versions. With the&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Xojo 2025r2 has just been released—time for an update to the Android Design Extensions 4.0, which are compatible with all Xojo 2025r2+ versions. </p>



<p>With the introduction of the new MobileMapViewer for Android, users now have the ability to customize the behavior and appearance of MobileMapViewer instances. For example, they can hide the zoom controls by using <code>SetZoomControlsEnabledXC(False)</code>, or enable/disable certain gestures (zoom, rotation, etc.). You can also set the minimum and maximum zoom level for the control by using the <code>SetMaxZoomPreferenceXC</code> or <code>SetMinZoomPreferenceXC</code> methods. </p>



<p>Android 15 users now also gain access to 16 additional system colors.</p>



<p>Give it a try! More exciting Android features are coming soon. Stay tuned! </p>



<p>Feel free to take a look at the developer repository, create feature requests, and provide feedback on extending this extension library. </p>



<p>I’m happy to receive any voluntary financial support for the work I’ve done so far, which you are welcome to <a href="https://www.paypal.com/paypalme/MTrippensee">share here</a>. You can download the project with many examples at <a href="https://github.com/XojoGermany/AndroidDesignExtensions">https://github.com/XojoGermany/AndroidDesignExtensions</a>.</p>



<p>Happy coding.</p>



<p><em>Martin T. is a Xojo MVP and has been very involved in testing Android support.</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>Handling Feature Requests</title>
		<link>https://blog.xojo.com/2025/03/15/handling-feature-requests/</link>
		
		<dc:creator><![CDATA[Anthony Cyphers]]></dc:creator>
		<pubDate>Sat, 15 Mar 2025 20:12:28 +0000</pubDate>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Beginner Tips]]></category>
		<category><![CDATA[Software Development]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=14686</guid>

					<description><![CDATA[As a developer, feature requests are a fact of life and one’s stress level may vary based on the complexity of the requests you receive.&#8230;]]></description>
										<content:encoded><![CDATA[
<p>As a developer, feature requests are a fact of life and one’s stress level may vary based on the complexity of the requests you receive. So what’s the best way to handle a feature request? Well, I’m not sure if there’s a best way, but here’s how I do it.</p>



<h3 class="wp-block-heading">Understand the Need</h3>



<p>The first step when I tackle a feature request is to thoroughly understand what the request is really about. People rarely have the ability to articulate exactly what they need, but are great at giving you just enough details — in small bursts — to figure it out if you carefully investigate their use case.</p>



<p>If you’re unsure of what they’re really trying to accomplish, ask for clarification. It’s better to spend more time up-front finding out what you really need to do than it is to rewrite your changes later. If you find yourself frequently modifying new code based on additional requests shortly after writing it then you may need to work on your communication.</p>



<p>Slow down, ask questions, try to get it right the first time. It’s not always as simple as a specification document (assuming you have one).</p>



<h3 class="wp-block-heading">Understand the Code</h3>



<p>Now that you understand the request, it’s time to analyze the code. Let’s be real, very few people can keep their entire codebase in their mind. Read through your code. Like a book. Follow function calls, property setters, everything. Make sure you understand what you’re modifying before you proceed, and look for the areas you’ll need to modify.</p>



<p>Sometimes this is much easier than others depending on the complexity of the project. And take notes! This step is especially important if you’re working on Other People’s Code (OPC).</p>



<h3 class="wp-block-heading">Understand the Path</h3>



<p>Next, develop a plan. Since you’ve read through code and, presumably, developed some ideas on the best way to implement, develop your own specification for the change. Give yourself time to fully work out the new implementation — I use private notes in my support system for wrapping my head around everything, which has the benefit of giving me greater insight if I need to come back later for some reason.</p>



<p>Work out the path forward before you ever modify any code by noting where you’ll make changes and what those changes might entail, keeping in mind that your previous functionality should continue to work as expected. This might involve creating new code paths specifically for the new feature to ensure that you don’t break old, working code. It’s also important to note things outside the scope of the new feature that you’ll need to test afterward to be sure that you didn’t break anything.</p>



<h3 class="wp-block-heading">Build the Road</h3>



<p>After you have a plan, it’s time to start building. If your strategy has been adequately outlined and you enjoy writing code, this is probably the most fun part. Follow your plan and make changes as you’ve outlined them. Be on the lookout for edge cases or caveats that you may have missed in your specification notes, chances are that they do exist.</p>



<h3 class="wp-block-heading">Test&nbsp;<strong><em>Everything</em></strong></h3>



<p>Finally, testing! Don’t just test the new feature, test the old functionality as well. It’s common that feature requests require modifying existing systems and you don’t want to push out that new release with a cool new feature only to have existing functionality break. Your work will look rushed and careless, and that’s worse than it taking a bit longer to complete.</p>



<h3 class="wp-block-heading">Bonus Tip</h3>



<p>Know when to rewrite. Over time codebases can become monolithic and overly complex based on continually adding features that were never considered when the project or features being modified were first created. If you find yourself spending more and more time trying to understand your code paths or fixing old functionality that new features break, it may be time to develop a new project specification and start from scratch. Don’t be afraid of tossing out something that causes you endless headaches to modify.</p>



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



<p>Whether working in a team or solo, a slow and methodical approach to feature requests will ensure that your changes last and customers are happy. Don’t rely on code reviews to catch issues or multiple requests after the fact to get everything right. You’ll make mistakes and miss things, but your work will be much better received with a little additional care.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>MemoryBlocks For Speed: A Case Study</title>
		<link>https://blog.xojo.com/2025/02/26/memoryblocks-for-speed-a-case-study/</link>
		
		<dc:creator><![CDATA[Kem Tekinay]]></dc:creator>
		<pubDate>Wed, 26 Feb 2025 17:00:00 +0000</pubDate>
				<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[MemoryBlocks]]></category>
		<category><![CDATA[One Billion Row Challenge]]></category>
		<category><![CDATA[Preemptive Threads]]></category>
		<category><![CDATA[Software Development]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=14534</guid>

					<description><![CDATA[A few years ago I held a session about MemoryBlocks at the Xojo Developer Conference where I discussed how, generally, MemoryBlocks (and Ptrs) should be&#8230;]]></description>
										<content:encoded><![CDATA[
<p>A few years ago I held a <a href="https://www.youtube.com/watch?v=3_uZ62mHCkw" target="_blank" rel="noreferrer noopener">session</a> about <code><a href="https://documentation.xojo.com/api/language/memoryblock.html#memoryblock" target="_blank" rel="noreferrer noopener">MemoryBlocks</a></code> at the Xojo Developer Conference where I discussed how, generally, <code>MemoryBlocks</code> (and <code>Ptrs</code>) should be avoided except for cases where you must use them, e.g., <code>Declare</code>, or when speed is absolutely critical. I offered this advice because a <code>MemoryBlock</code> can be tedious to work with, and can lead to hard-to-trace bugs.</p>



<p>But when you do need that extra boost, it&#8217;s an option to consider, and I recently came across a scenario where it made a huge difference.</p>



<h2 class="wp-block-heading">The (One Billion Row) Challenge</h2>



<p>This came about from <a href="https://forum.xojo.com/t/xojo1brc-xojo-one-billion-row-challenge/82844" target="_blank" rel="noreferrer noopener">a discussion of the &#8220;One Billion Row Challenge&#8221;</a> on the Xojo Forum, where a programmer is tasked with reading a billion rows of temperature data and consolidating it into statistics for each given city. Our friend <a href="https://forum.xojo.com/u/mike_d/summary" target="_blank" rel="noreferrer noopener">Mike D</a> started a project to demonstrate different techniques, and I eventually started <a href="https://github.com/ktekinay/Xojo-BRC" target="_blank" rel="noreferrer noopener">my own project</a>. Using <code>MemoryBlock</code>, <code>Ptr</code>, and preemptive threading, I was able to process a billion rows in roughly 8 seconds.</p>



<p>But that&#8217;s not the point of this post.</p>



<p>See, in order to process the data, you must first create it, which isn&#8217;t as straightforward as it seems.</p>



<h2 class="wp-block-heading">Creating The Data</h2>



<p>Each row of the data file takes the form &#8220;City;temp&#8221;, where &#8220;temp&#8221; is single-place decimal between -99.9 and 99.9. For purpose of limits, I used, arbitrarily, 413 random cities out of a list of all cities. The original code looked something like this where &#8220;bs&#8221; represents a <code>BinaryStream</code>:</p>



<pre class="wp-block-code"><code>Var r As New Random

For i As Integer = 1 To rowCount
  Var city As String = cities(r.InRange(0, cities.LastIndex))
  Var temp As Double = r.InRange(-999, 999) / 10.0

  bs.Write city + ";" + temp.ToString("#0.0") + EndOfLine
Next</code></pre>



<p>This was simple, easy, and slow. To generate the full billion rows took about 2.5 hours.</p>



<h2 class="wp-block-heading">Memory-Unblocking</h2>



<p>Upon investigation, I rediscovered what I already knew. Dealing with strings, both in conversion and concatenation, can be a bottleneck. I won&#8217;t go through all the iterations here, but nothing I tried made a significant difference. The only solution was to ditch strings entirely.</p>



<p>I started with creating a <code>MemoryBlock</code> &#8220;buffer&#8221; (&#8220;outMB&#8221;) of 1 MB with an associated <code>Ptr</code> (&#8220;outPtr&#8221;). (You can access the contents of a <code>MemoryBlock</code> through its methods, but those are function calls, which have an overhead. <code>Ptr</code> methods are operators that work with the bytes directly so they are faster.) The plan was to fill the buffer as much as I could, write it to the file, then start again at the top of the buffer.</p>



<p>Keeping a position index, I started with writing the city using <code>outMB.StringValue</code> since there is no equivalent <code>Ptr</code> method for this. Next, I plugged in the value of a semicolon with <code>outPtr.Byte(outMBIndex) = 59</code>.</p>



<p>Working with integers is faster than doubles, so I used a little math to plug in the temperature values directly using <code>If</code> statements and <code>outPtr.Byte</code>.</p>



<p>Finally, I used <code>outPtr.Byte(outMBIndex) = 10</code> to plug in the linefeed (ASCII 10).</p>



<p>The final code looked something like this:</p>



<pre class="wp-block-code"><code>Const kEOL As Integer = 10
Const kHyphen As Integer = 45
Const kDot As Integer = 46
Const kZero As Integer = 48
Const kSemicolon As Integer = 59

Var r As New Random

Var outMB As New MemoryBlock(1000000)
Var outPtr As Ptr = outMB

Var outMBIndex As Integer = 0

For row As Integer = 1 To rows
  Var cityIndex As Integer = r.InRange(0, cities.LastIndex)
  Var city As string = cities(cityIndex)
  Var cityBytes As Integer = city.Bytes

  If (outMBIndex + cityBytes + 10) &gt;= outMB.Size Then
    bs.Write outMB.StringValue(0, outMBIndex)
    outMBIndex = 0
  End If

  outMB.StringValue(outMBIndex, cityBytes) = city
  outMBIndex = outMBIndex + cityBytes

  outPtr.Byte(outMBIndex) = kSemicolon
  outMBIndex = outMBIndex + 1

  If r.InRange(0, 4) = 0 Then
    outPtr.Byte(outMBIndex) = kHyphen
    outMBIndex = outMBIndex + 1
  End If

  Var temp As Integer = r.InRange(0, 999)
  Var t1 As Integer = temp \ 100
  Var t2 As Integer = (temp \ 10) Mod 10
  Var t3 As Integer = temp Mod 10

  If t1 &lt;&gt; 0 Then
    outPtr.Byte(outMBIndex) = t1 + kZero
    outMBIndex = outMBIndex + 1
  End If

  outPtr.Byte(outMBIndex) = t2 + kZero
  outMBIndex = outMBIndex + 1

  outPtr.Byte(outMBIndex) = kDot
  outMBIndex = outMBIndex + 1

  outPtr.Byte(outMBIndex) = t3 + kZero
  outMBIndex = outMBIndex + 1

  outPtr.Byte(outMBIndex) = kEOL
  outMBIndex = outMBIndex + 1
next

If outMBIndex &lt;&gt; 0 Then
  bs.Write outMB.StringValue(0, outMBIndex)
End If</code></pre>



<p>This code is far longer, harder to follow, and difficult to maintain, which goes back to my original point of why <code>MemoryBlock</code> should be avoided.</p>



<p>It also generates one billion rows of data in about a minute (as opposed to 2.5 hours).</p>



<p>It&#8217;s nice to have the option.</p>



<p><em>Kem Tekinay is a Mac consultant and programmer who has been using Xojo since its first release to create custom solutions for clients. He is the author of the popular utilities <a href="http://www.mactechnologies.com/index.php?page=downloads#tftpclient" target="_blank" rel="noreferrer noopener">TFTP Client</a> and <a href="http://www.mactechnologies.com/index.php?page=downloads#regexrx" target="_blank" rel="noreferrer noopener">RegExRX</a> (both written with Xojo) and lives in Connecticut with his wife Lisa, and their cat.</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>Build a Xojo Plugin with GitHub Actions</title>
		<link>https://blog.xojo.com/2025/02/25/build-a-xojo-plugin-with-github-actions/</link>
		
		<dc:creator><![CDATA[Jürg Otter]]></dc:creator>
		<pubDate>Tue, 25 Feb 2025 22:30:00 +0000</pubDate>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[#YearofCode]]></category>
		<category><![CDATA[cubeSQL]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[GitHub]]></category>
		<category><![CDATA[Plugins]]></category>
		<category><![CDATA[Year of Code]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=14509</guid>

					<description><![CDATA[As part of Xojo&#8217;s 2025 Year of Code initiative, February&#8217;s theme is databases—a perfect fit for my recent work on the Open Source CubeSQLPlugin. This&#8230;]]></description>
										<content:encoded><![CDATA[
<p>As part of <a href="https://forum.xojo.com/t/2025-year-of-code-february/" target="_blank" rel="noreferrer noopener">Xojo&#8217;s 2025 Year of Code</a> initiative, <a href="https://forum.xojo.com/t/2025-year-of-code-february/" target="_blank" rel="noreferrer noopener">February&#8217;s theme is databases</a>—a perfect fit for my recent work on the <a href="https://github.com/marcobambini/cubesqlplugin" target="_blank" rel="noreferrer noopener">Open Source CubeSQLPlugin</a>. This article shares insights into automating its build process with <a href="https://docs.github.com/en/actions/writing-workflows" target="_blank" rel="noreferrer noopener">GitHub Actions Workflows</a>.</p>



<p>Xojo plugins are add-ons that extend the functionality of the Xojo development environment, allowing developers to add additional features, integrate third-party libraries, and much more.</p>



<h2 class="wp-block-heading">Write a Xojo Plugin</h2>



<p>This article assumes familiarity with the <a href="https://documentation.xojo.com/topics/custom_controls/plugins_sdk.html" target="_blank" rel="noreferrer noopener">Xojo Plugin SDK</a> and focuses on automating plugin builds. If you&#8217;re new to plugin development, check out the resources in Xojo’s &#8220;Extras&#8221; folder, YouTube tutorials, and the Xojo Forum.</p>



<p>It builds on my previous blog post <a href="https://blog.xojo.com/2022/10/19/xojo-github-actions/" target="_blank" rel="noreferrer noopener">Xojo Github Actions</a> and involves <a href="https://www.docker.com/" target="_blank" rel="noreferrer noopener">Docker</a>, which has also been a part of a previous blog posts (<a href="https://blog.xojo.com/2024/06/03/docker-database-servers-and-xojo/" target="_blank" rel="noreferrer noopener">Docker, Database Servers and Xojo</a>, <a href="https://blog.xojo.com/2021/05/17/running-xojo-web-applications-in-docker/" target="_blank" rel="noreferrer noopener">Running Xojo Web Applications in Docker</a>). So read up there on what a <a href="https://docs.github.com/en/actions/writing-workflows" target="_blank" rel="noreferrer noopener">GitHub Actions workflow</a> is, what the <code>.yaml</code> files in the Folder <code>.github/workflows</code> are used for.</p>



<h2 class="wp-block-heading"><strong>Build a Xojo Plugin</strong></h2>



<p>Since Xojo is a cross platform development environment, a Xojo plugin needs to be built for all the supported platforms <em>(Windows, macOS, Linux)</em> and all their architectures <em>(Intel/ARM, 32/64Bit)</em>.</p>



<p>All the plugin parts (the Windows <code>.dll</code>&#8216;s, .macOS <code>.dylib</code>&#8216;s and Linux <code>.so</code>&#8216;s) are being packaged into a <code>.xojo_plugin</code> file.</p>



<p>One of the challenges is to have an environment to build all that. At the first glance it seems that one would need a Mac, a Windows machine &#8211; as well as some Linux environment <em>(any of which could also just be a virtual machine)</em>. And one would first think that there will be a lot of manual steps involved &#8211; building the plugin source on various machines, copying all the built plugin parts together to finally assemble the resulting <code>.xojo_plugin</code>.</p>



<p>However &#8211; all that is not required. You can build a Xojo plugin without your own machine being involved, fully automated. GitHub Actions provides all we need.</p>



<h2 class="wp-block-heading"><strong>Example: CubeSQLPlugin</strong></h2>



<p>Let us have a look at this existing <a href="https://github.com/marcobambini/cubesqlplugin" target="_blank" rel="noreferrer noopener">Open Source Plugin</a>.</p>



<p><a href="https://github.com/marcobambini/cubesqlplugin" target="_blank" rel="noreferrer noopener"><em>CubeSQLPlugin</em></a><em> is an extension for the Xojo programming environment that allows developers to use </em><a href="https://sqlabs.com/cubesql" target="_blank" rel="noreferrer noopener"><em>CubeSQL</em></a><em>, a fully featured and high performance relational database management system built on top of the SQLite database engine.</em></p>



<p>The plugin is being used in the Open Sourced Administrations Tools for CubeSQL, which are both written in Xojo: <a href="https://github.com/cubesql/webadmin" target="_blank" rel="noreferrer noopener">CubeSQL Web Admin</a> and <a href="https://github.com/cubesql/cubeSQLAdmin" target="_blank" rel="noreferrer noopener">CubeSQL (Desktop) Admin</a>.</p>



<p>Internally the plugin uses <a href="https://www.libressl.org" target="_blank" rel="noreferrer noopener">LibreSSL</a> for TLS Connections of Database Clients to CubeSQL Server. This means that first the LibreSSL libs need to be built for all build targets. Only then can the plugin source be built again for all build targets. And finally, all the plugin parts need to be assembled into the Xojo plugin structure for the final <code>.xojo_plugin</code>.</p>



<p>We have automated the whole build process of the plugin using <a href="https://docs.github.com/de/actions" target="_blank" rel="noreferrer noopener">GitHub Actions</a> by having created three workflows. You&#8217;ll find their source in the folder <a href="https://github.com/marcobambini/cubesqlplugin/tree/master/.github/workflows" target="_blank" rel="noreferrer noopener">.github/workflows</a>. All workflow executions you&#8217;ll find on GitHub in the tab named <a href="https://github.com/marcobambini/cubesqlplugin/actions" target="_blank" rel="noreferrer noopener">Actions</a> <em>(as long as they have not been deleted or removed)</em>.</p>



<p><strong>LibreSSL</strong><br>This workflow will download the <a href="https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/" target="_blank" rel="noreferrer noopener">LibreSSL Source</a>, and build it for all needed build targets. It needs to be run only once, e.g. if a new <a href="https://www.libressl.org" target="_blank" rel="noreferrer noopener">LibreSSL</a> version is available that should be included for the next plugin build. That&#8217;s why it&#8217;s a workflow that can be run manually. It asks which LibreSSL version should be built and whether the built libraries should be committed and pushed to the repository.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="367" src="https://blog.xojo.com/wp-content/uploads/2025/02/01_Workflow_LibreSSL-1024x367.png" alt="" class="wp-image-14514" srcset="https://blog.xojo.com/wp-content/uploads/2025/02/01_Workflow_LibreSSL-1024x367.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/02/01_Workflow_LibreSSL-300x108.png 300w, https://blog.xojo.com/wp-content/uploads/2025/02/01_Workflow_LibreSSL-768x276.png 768w, https://blog.xojo.com/wp-content/uploads/2025/02/01_Workflow_LibreSSL-1536x551.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/02/01_Workflow_LibreSSL-2048x735.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p><strong>CubeSQLPlugin</strong><br>This workflow will build the <a href="https://github.com/marcobambini/cubesqlplugin" target="_blank" rel="noreferrer noopener">CubeSQL Xojo Plugin</a> for all build targets using the currently committed LibreSSL libs in the repository. It will commit and push all the built <code>.dll</code>&#8216;s, .<code>dylib</code>&#8216;s and <code>.so</code>&#8216;s to the repository.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="496" src="https://blog.xojo.com/wp-content/uploads/2025/02/02_Workflow-Plugin-1024x496.png" alt="" class="wp-image-14515" srcset="https://blog.xojo.com/wp-content/uploads/2025/02/02_Workflow-Plugin-1024x496.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/02/02_Workflow-Plugin-300x145.png 300w, https://blog.xojo.com/wp-content/uploads/2025/02/02_Workflow-Plugin-768x372.png 768w, https://blog.xojo.com/wp-content/uploads/2025/02/02_Workflow-Plugin-1536x744.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/02/02_Workflow-Plugin-2048x992.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p><strong>Create Release</strong><br>That one is pretty obvious, right? It builds the structure of the final <code>.xojo_plugin</code> and creates a new <a href="https://github.com/marcobambini/cubesqlplugin/releases" target="_blank" rel="noreferrer noopener">Release</a> in the repository with the final Xojo plugin &#8211; ready to be downloaded.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="535" src="https://blog.xojo.com/wp-content/uploads/2025/02/03_Plugin-Release-1024x535.png" alt="" class="wp-image-14516" srcset="https://blog.xojo.com/wp-content/uploads/2025/02/03_Plugin-Release-1024x535.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/02/03_Plugin-Release-300x157.png 300w, https://blog.xojo.com/wp-content/uploads/2025/02/03_Plugin-Release-768x401.png 768w, https://blog.xojo.com/wp-content/uploads/2025/02/03_Plugin-Release-1536x802.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/02/03_Plugin-Release-2048x1069.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h3 class="wp-block-heading"><strong>Build for all Platforms and Architectures</strong></h3>



<p>The two workflows &#8220;LibreSSL&#8221; and &#8220;CubeSQLPlugin&#8221; are similar in their approach to building for all the supported platforms <em>(Windows, macOS, Linux)</em> and all their architectures <em>(Intel/ARM, 32/64Bit)</em>.</p>



<p>GitHub offers hosted <a href="https://docs.github.com/en/actions/using-github-hosted-runners/using-github-hosted-runners/about-github-hosted-runners" target="_blank" rel="noreferrer noopener">virtual machines to run workflows</a>. All virtual machines contain an environment of tools, packages, and settings available for <a href="https://docs.github.com/en/actions/writing-workflows" target="_blank" rel="noreferrer noopener">GitHub Actions workflows</a> to use.</p>



<p>So our workflows can simply use these environments. The workflows consist of several steps, each of which can be executed on a different runner. Remember that I&#8217;ve written: &#8220;You can build a Xojo plugin without your own machine involved&#8221;?</p>



<p>In the following ScreenShot we&#8217;re seeing that the Linux-ARM64 plugin part is being created on a Ubuntu 24.04.1 ARM machine.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="475" src="https://blog.xojo.com/wp-content/uploads/2025/02/04_Build-Linux-ARM64-1024x475.png" alt="" class="wp-image-14517" srcset="https://blog.xojo.com/wp-content/uploads/2025/02/04_Build-Linux-ARM64-1024x475.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/02/04_Build-Linux-ARM64-300x139.png 300w, https://blog.xojo.com/wp-content/uploads/2025/02/04_Build-Linux-ARM64-768x356.png 768w, https://blog.xojo.com/wp-content/uploads/2025/02/04_Build-Linux-ARM64-1536x712.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/02/04_Build-Linux-ARM64-2048x949.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h4 class="wp-block-heading"><strong>macOS</strong></h4>



<ul class="wp-block-list">
<li>Runs on a GitHub macOS virtual machine.</li>



<li>Uses the preinstalled Xcode command line tools to build &#8220;Intel x86_64&#8221; and &#8220;ARM64&#8221; and combine the two to a universal binary.</li>



<li>CodeSigns with credentials added as repository secrets.</li>
</ul>



<h4 class="wp-block-heading"><strong>Linux</strong></h4>



<ul class="wp-block-list">
<li>ARM32, ARM64
<ul class="wp-block-list">
<li>Runs on a GitHub Linux virtual ARM machine.</li>



<li>To always have exactly the same build toolset <em>(e.g. so that it doesn&#8217;t matter if GitHub updates to a newer Ubuntu version)</em> it leverages a Docker container (e.g. <a href="https://hub.docker.com/r/arm64v8/gcc/" target="_blank" rel="noreferrer noopener">arm64v8/gcc</a>) &#8211; and actually builds the source inside the Docker container.</li>
</ul>
</li>



<li>i386, x86_64
<ul class="wp-block-list">
<li>Runs on a GitHub Linux virtual Intel machine.</li>



<li>Also uses a <a href="https://hub.docker.com/_/gcc" target="_blank" rel="noreferrer noopener">gcc Docker Image</a> to build the source.</li>
</ul>
</li>
</ul>



<h4 class="wp-block-heading"><strong>Windows</strong></h4>



<ul class="wp-block-list">
<li>Runs on a GitHub Windows virtual machine.</li>



<li>Uses the preinstalled Visual Studio environment to build all &#8220;win32&#8221;, &#8220;x64&#8221; and &#8220;ARM64&#8221;.</li>
</ul>



<h2 class="wp-block-heading"><strong>How to Build your Xojo Plugin</strong></h2>



<p>I&#8217;m very well aware that this article can&#8217;t help you build your plugin. Each one is individual and needs its own steps and processes.</p>



<p>However, should you consider automating your plugin build process. You might want to look in more detail in the open-source plugin source and the <a href="https://github.com/marcobambini/cubesqlplugin/tree/master/.github/workflows" target="_blank" rel="noreferrer noopener">workflows</a> which are building <a href="https://github.com/marcobambini/cubesqlplugin" target="_blank" rel="noreferrer noopener">CubeSQLPlugin</a> for all required targets and architectures.</p>



<h2 class="wp-block-heading"><strong>How to Transition from Manual to Automated</strong></h2>



<p>While creating a plugin, one doesn&#8217;t think of its build process in the early stages, maybe not even for the first few released versions.&nbsp;</p>



<p>Plugin building is usually a manual process, requiring manual execution of a lot of steps and commands on various machines. It is tedious and prone to errors. It takes time, which adds up the more you build. There&#8217;s a point when one should think about streamlining and automate the process, allowing for building new versions without too much effort.<br>In addition, it&#8217;s certainly a good idea to have a consistent build environment other than your own development machine as you could install and change things on there which could impact the builds. That&#8217;s why building inside a Docker container is an interesting approach &#8211; it will remain exactly the same each and every time, even if the host machine is changed <em>(e.g. by being updated to a new operating system version)</em>.</p>



<p>All that used to be like that before having written the GitHub workflow.</p>



<p>How can you transition from a manual to an automated process for your own project? I won&#8217;t be able to provide all answers. But, I&#8217;d like to give a few ideas of possible steps, with no intention of them being complete or the best choice for your project.</p>



<ul class="wp-block-list">
<li>Use a version control system.
<ul class="wp-block-list">
<li>Git and GitHub are (for many use cases) free.</li>



<li>Using a Cloud solution serves as a backup should something happen to your machines.</li>



<li>You can additionally benefit from other services such as the GitHub Actions workflows mentioned in this article.</li>
</ul>
</li>



<li>Everything that is only in your head should go into some written form. Once you don&#8217;t need to do something for some time, you might forget or miss something.
<ul class="wp-block-list">
<li>Start with documenting all steps, commands, and actions.</li>
</ul>
</li>



<li>Try to get rid of manual steps. Are you copy-and-pasting several commands to a terminal each and every time?
<ul class="wp-block-list">
<li>Put them in a shell script, so that you only need to run one command.</li>



<li>You can use these scripts later when going to a fully-automated system.</li>
</ul>
</li>



<li>When initial development is finished and you&#8217;re ready to release:
<ul class="wp-block-list">
<li>Don&#8217;t do releases from your development machine. It might be defunct, broken, stolen, or you&#8217;re installing some new cool stuff and suddenly notice issues with other projects. Having a dedicated build machine is one idea. </li>



<li>Another is going the &#8220;GitHub Actions&#8221; way which also has its benefits.
<ul class="wp-block-list">
<li>Runners are virtual machines that are provisioned and &#8220;fresh&#8221; every time. It&#8217;s always the very same environment to start with for each build, no matter what you&#8217;re doing during a build.</li>



<li>You don&#8217;t need to maintain many different build machines yourself. This can even solve some security issues, as it&#8217;s probably not your main interest of keeping everything up to date. I prefer to focus on programming and not on system maintenance.</li>



<li>However, the runners might be outdated in a few years &#8211; and new runners (with newer operating systems) will be available.
<ul class="wp-block-list">
<li>That&#8217;s usually not a very big issue on macOS and Windows since their build tools are usually backwards compatible for quite a long time.</li>



<li>Especially for Linux we have decided not to rely on the provided host but use a Docker Image and run the builds inside a Docker container. So you can, for example, use a Docker container with an image that perfectly fits your lowest compatibility needs, while the host itself might only have (too) new libraries installed.</li>
</ul>
</li>
</ul>
</li>



<li>Start putting all your steps and scripts into a workflow &#8211; be it just on your dedicated build environment, or using GitHub Actions.
<ul class="wp-block-list">
<li>Certainly separate them per required host (macOS / Windows / Linux).</li>



<li>Split a long script into smaller parts, e.g: Download LibreSSL, Build x86_64, Build arm64, Build Universal.
<ul class="wp-block-list">
<li>In case of an error, it&#8217;s easier to see that &#8220;macOS: Build arm64 has failed&#8221;, compared to &#8220;Build for macOS has failed&#8221; (because it&#8217;s all in a lengthy script).</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>



<li>Running the workflows manually is great and likely more than good enough.<br>Once the project activity grows (e.g. you&#8217;re receiving a lot of pull request or have many developers working on it):
<ul class="wp-block-list">
<li>Ensure that the build and test workflows are running on each pull request, require them to complete successfully before being able to merge. That by the way has been explained in the previous blog post <a href="https://blog.xojo.com/2022/10/19/xojo-github-actions/">Xojo GitHub Actions</a>. After all, no one wants to find out after many commits that the build is no longer working, and then have to search the history for what might have caused the problem.</li>
</ul>
</li>



<li>You&#8217;ll notice that once it&#8217;s all automated you no longer miss it. It causes no additional effort for you, instead bringing a lot of benefits <em>(such as noticing early when code changes cause oddities in tests and builds)</em>.</li>
</ul>



<h3 class="wp-block-heading"><strong>A Fun Fact</strong></h3>



<p>In the early days a build of the CubeSQLPlugin often took a couple of hours &#8211; and with personal attention needed so that one couldn&#8217;t work on much else during that time.</p>



<p>The first iteration of the workflows reduced the entire build (LibreSSL + Plugin) to about 25 minutes. With no attention and manual interaction needed &#8211; which means more time for other work. What took the longest was the LibreSSL ARM builds &#8211; they have been run on Intel hardware with QEMU for ARM emulation.</p>



<p>Back to the beginning of this article and <a href="https://forum.xojo.com/t/2025-year-of-code-february/" target="_blank" rel="noreferrer noopener">Xojo&#8217;s 2025 Year of Code</a> initiative &#8211; in February I have improved the workflows to use the newly available GitHub Actions runners that run on ARM hardware. Which means that no more emulation is required &#8211; and the build time has now come down to about 4 minutes for LibreSSL Libs <em>(required only once per new LibreSSL version)</em> and 2.5 minutes for the Xojo database plugin for all its supported platforms and architectures!</p>



<h2 class="wp-block-heading"><strong>That&#8217;s All Folks!</strong></h2>



<p>I hope this brief introduction of how to use <a href="https://docs.github.com/en/actions/writing-workflows" target="_blank" rel="noreferrer noopener">GitHub Actions workflows</a> and <a href="https://www.docker.com" target="_blank" rel="noreferrer noopener">Docker</a> to build a <a href="https://documentation.xojo.com/topics/custom_controls/plugins_sdk.html" target="_blank" rel="noreferrer noopener">Xojo plugin</a> has been helpful to some, food for thought to others.</p>



<p><em><em>Jürg Otter is a long term user of Xojo and working for </em><a href="https://www.cmiag.ch/"><em>CM Informatik AG</em></a><em>. Their Application </em><a href="https://cmi-bildung.ch/"><em>CMI LehrerOffice</em></a><em> is a Xojo Design Award Winner 2018. In his leisure time Jürg provides some </em><a href="https://www.jo-tools.ch/xojo/"><em>bits and pieces for Xojo Developers</em></a><em>.</em></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></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Introduction to PocketBase: A Backend Alternative for Xojo Developers</title>
		<link>https://blog.xojo.com/2025/02/19/introduction-to-pocketbase-a-backend-alternative-for-xojo-developers/</link>
		
		<dc:creator><![CDATA[Ezekiel Burke]]></dc:creator>
		<pubDate>Wed, 19 Feb 2025 16:02:00 +0000</pubDate>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Beginner Tips]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PocketBase]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLite]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=14488</guid>

					<description><![CDATA[Introduction When developing applications with Xojo, choosing the right backend is crucial for managing data efficiently. Traditionally, Xojo developers rely on SQL databases such as&#8230;]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Introduction</h2>



<p>When developing applications with Xojo, choosing the right backend is crucial for managing data efficiently. Traditionally, Xojo developers rely on SQL databases such as SQLite, MySQL, or PostgreSQL for their desktop, web, and mobile applications. However, there is an alternative that provides a more flexible and modern approach to backend development: <a href="https://pocketbase.io/" target="_blank" rel="noreferrer noopener">PocketBase</a>.</p>



<p>PocketBase is an open-source backend perfect for your multi-platform Xojo application. It offers a simple-to-use API and a built-in admin panel to manage the data from any web browser. No other tool such as MySQL, Workbench, or SQL Studio is needed. In this post, I will explain how it compares to traditional SQL databases and demonstrate how to integrate it into a Xojo project.</p>



<h3 class="wp-block-heading">Why Choose PocketBase for Your Xojo App Backend?</h3>



<p>PocketBase is a lightweight, self-hosted backend designed for simplicity and flexibility. Unlike traditional SQL databases that require a separate backend service or API layer, PocketBase is an all-in-one solution that combines the database and API.</p>



<h3 class="wp-block-heading">Key Features:</h3>



<p>Embedded Database – Powered by SQLite, eliminating the need for a separate database server.</p>



<p>Built-in User Authentication – Supports email/password logins, OAuth2 sign-ups, and one-time password (OTP) with minimal setup.</p>



<p>File Storage – Store and retrieve files locally or via S3.</p>



<p>Cross-Platform Compatibility – Runs on macOS, Windows, and Linux. Can communicate via URLConnection making it ideal for Xojo’s desktop, web, and mobile platforms.</p>



<p>Easy Deployment – A single binary file that can be self-hosted or deployed anywhere with minimal configuration.</p>



<h2 class="wp-block-heading">Setting Up PocketBase for a Xojo App</h2>



<p>To get started, I have simplified some steps below. If you get stuck or want more in-depth instructions take a look at the <a href="https://pocketbase.io/docs/" target="_blank" rel="noreferrer noopener">documentation</a>.</p>



<ul class="wp-block-list">
<li>Download PocketBase
<ul class="wp-block-list">
<li>Visit <a href="https://pocketbase.io/" target="_blank" rel="noreferrer noopener">PocketBase</a> and download the latest release for your operating system.</li>



<li>Extract the files to your project directory.</li>
</ul>
</li>



<li>Run PocketBase
<ul class="wp-block-list">
<li>Start the PocketBase server by navigating to the extracted folder in the command prompt/terminal.</li>



<li>Run the command: <code>./pocketbase serve</code> to start the server.</li>
</ul>
</li>



<li>Access the Admin Panel
<ul class="wp-block-list">
<li>Open <code>http://127.0.0.1:8090/_/</code> in a web browser and set up an admin account.</li>
</ul>
</li>



<li>Add a User
<ul class="wp-block-list">
<li>In the PocketBase admin panel, create a new record in the users collection. (Collections are the equivalent of a table in SQL.)</li>
</ul>
</li>
</ul>



<h2 class="wp-block-heading">Connect Xojo to PocketBase</h2>



<p>Now that your PocketBase server is running, integrate authentication into your Xojo desktop app. In this example, we will handle authentication in the open event of the main window. This will demonstrate how Xojo interacts with PocketBase’s authentication API.</p>



<h3 class="wp-block-heading">Implement the Login Request</h3>



<p>Add the following code to the open event of your main window:</p>



<pre class="wp-block-code"><code>Var userEmail As String = "email@email.com"
Var userPassword As String = "MyPassword!"
Var loginURL As String = "http://127.0.0.1:8090" + "/api/collections/users/auth-with-password"
Var conn As New URLConnection
conn.RequestHeader("Content-Type") = "application/json"
 
Var loginPayload As New JSONItem
loginPayload.Value("identity" ) = userEmail
loginPayload.Value("password") = userPassword
conn.SetRequestContent(loginPayload.ToString, "application/json")
 
Var loginResponse As String = conn.SendSync("POST", loginURL)
Var jsonResponse As New JSONItem(loginResponse)
Var userInfo As JSONItem = jsonResponse.Lookup("record", New JSONItem)
Var userID As String = userInfo.Lookup("id", "")
Var authToken As String = jsonResponse.Lookup("token", "")
 
If authToken.Length > 0 Then
  MessageBox("Login successful! Welcome, User ID: " + userID)
Else
  MessageBox("Login failed. Please check your credentials.")
End If</code></pre>



<h3 class="wp-block-heading">Update Your Credentials and URL</h3>



<p>Replace userEmail and userPassword with the credentials you used to create a user in PocketBase. Also, ensure the loginURL matches your PocketBase instance (without <code>/_/</code> at the end).</p>



<h3 class="wp-block-heading">Run The App</h3>



<p>Launch your Xojo app. If authentication is successful, a message box will display the user&#8217;s ID. Otherwise, you will see an error message indicating that the credentials are incorrect.</p>



<h3 class="wp-block-heading">Wrapping Up</h3>



<p>In this article, you have successfully set up a PocketBase server, created a record, and integrated authentication into your Xojo app. PocketBase simplifies backend development by handling authentication and data storage—all without the need for a traditional SQL database.</p>



<p>With PocketBase, there is no need to set up complex user tables, hash passwords, or build a custom API. Collections can be easily managed directly from the web via the admin panel. This means you can spend less time managing infrastructure and more time focusing on bringing your app to market.</p>



<p>To help you get started, I’ve created a collection of example projects, which you can find here:</p>



<p><a href="https://github.com/Iron-Elephant-Solutions/Xojo-Pocketbase-Examples">Xojo-Pocketbase-Examples</a></p>



<p>If you’d like to discuss how Iron Elephant Solutions has used Xojo and PocketBase in real-world applications, feel free to reach out through our <a href="https://ironelephantsolutions.com/">website</a> or add me on <a href="https://www.linkedin.com/in/ezekiel-zeke-burke/">LinkedIn</a>.</p>



<p><a href="https://www.linkedin.com/in/ezekiel-zeke-burke/overlay/about-this-profile/" target="_blank" rel="noreferrer noopener">Ezekiel Burke</a><em> is the founder of <a href="https://ironelephantsolutions.com/" target="_blank" rel="noreferrer noopener">Iron Elephant Solutions</a>. He focuses on building custom, scalable, and affordable software that helps businesses work smarter. With 15+ years of experience, he specializes in full-stack development, process automation and systems integration, creating solutions that simplify complex workflows.</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Android Design Extensions 3.5 for Xojo 2024r4+</title>
		<link>https://blog.xojo.com/2024/12/10/android-design-extensions-3-5-for-xojo-2024r4/</link>
		
		<dc:creator><![CDATA[Martin T.]]></dc:creator>
		<pubDate>Tue, 10 Dec 2024 16:38:03 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Android Design Extensions]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Declares]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=14175</guid>

					<description><![CDATA[With the release of Xojo 2024r4, it’s time to unveil a new version of the Android Design Extensions. The focus of version 3.5 (compatible with&#8230;]]></description>
										<content:encoded><![CDATA[
<p>With the release of Xojo 2024r4, it’s time to unveil a new version of the Android Design Extensions. The focus of version 3.5 (compatible with all Xojo versions starting from 2024r4+) was on code maintenance and introducing exceptions for unsupported API calls, depending on the running Android version. This should make your work as a developer easier.</p>



<p>You can now use the <em>SetBottomAppBarMenuAlignmentModeXC </em>extension method for MobileScreen to set the alignment of the buttons in your MobileScreen.Toolbar.</p>



<p>Additionally, new declares for MobileMessageBox have been added, allowing you to display an icon next to the title as well as next to individual buttons.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="498" height="1024" src="https://blog.xojo.com/wp-content/uploads/2024/12/3C6F953F-1315-4016-8A7B-F2427E7F54BC-498x1024.png" alt="" class="wp-image-14176" srcset="https://blog.xojo.com/wp-content/uploads/2024/12/3C6F953F-1315-4016-8A7B-F2427E7F54BC-498x1024.png 498w, https://blog.xojo.com/wp-content/uploads/2024/12/3C6F953F-1315-4016-8A7B-F2427E7F54BC-146x300.png 146w, https://blog.xojo.com/wp-content/uploads/2024/12/3C6F953F-1315-4016-8A7B-F2427E7F54BC-768x1579.png 768w, https://blog.xojo.com/wp-content/uploads/2024/12/3C6F953F-1315-4016-8A7B-F2427E7F54BC-747x1536.png 747w, https://blog.xojo.com/wp-content/uploads/2024/12/3C6F953F-1315-4016-8A7B-F2427E7F54BC-996x2048.png 996w, https://blog.xojo.com/wp-content/uploads/2024/12/3C6F953F-1315-4016-8A7B-F2427E7F54BC.png 1080w" sizes="auto, (max-width: 498px) 100vw, 498px" /></figure>



<p>Give it a try! More exciting Android features are coming soon. Stay tuned!</p>



<p>Feel free to take a look at the developer repository, create feature requests, and provide feedback on extending this extension library.</p>



<p>I’m happy to receive any voluntary financial support for the work I’ve done so far, which you are welcome to <a href="https://www.paypal.com/paypalme/MTrippensee">share here</a>. You can download the project with many examples at <a href="https://github.com/XojoGermany/AndroidDesignExtensions">https://github.com/XojoGermany/AndroidDesignExtensions</a>.</p>



<p>Happy coding.</p>



<p><em>Martin T. is a Xojo MVP and has been very involved in testing Android support.</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Xojo Web Rescues a .NET Project</title>
		<link>https://blog.xojo.com/2024/10/23/xojo-web-rescues-a-net-project/</link>
		
		<dc:creator><![CDATA[Wayne Golding]]></dc:creator>
		<pubDate>Wed, 23 Oct 2024 16:40:14 +0000</pubDate>
				<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Encryption]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[URLConnection]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13909</guid>

					<description><![CDATA[I had a call recently from a customer whose upstream supplier informed them that they would not be accepting anything less than TLS 1.2 encryption.&#8230;]]></description>
										<content:encoded><![CDATA[
<p>I had a call recently from a customer whose upstream supplier informed them that they would not be accepting anything less than TLS 1.2 encryption. The customer’s application is written using .NET 1.1 (they are testing a new version but aren’t ready to deploy to production just yet). Their supplier insisted on a 1-week time limit. Can I help?</p>



<p>My answer was, of course, “Let me have a look and get back to you.”</p>



<p>I went to my favourite dev tool, Xojo, and went through the process of developing a solution.&nbsp;The connection is a REST API, so I’ll start with a web project and use the HandleURL event. And I’ll use a URLConnection to pass on the request.&nbsp; Wait … could it be that simple?</p>



<pre class="wp-block-code"><code>Function HandleURL(request As WebRequest, response As WebResponse) Handles HandleURL as Boolean

  // Create the outbound connection
  Var connector As New URLConnection
 
  // Copy the content of the request
  connector.SetRequestContent(request.Body, request.MIMEType)

  // Send the request
  Var result As String
  Try
    result = connector.SendSync("POST", kAddress + request.Path)
  Catch err As RuntimeException
    // Catch DNS, Certificate &amp; Timeout errors
    response.Status = 500
    response.Write(err.Message)
    Return True
  End

  // Return the result of the request
  response.Status = connector.HTTPStatusCode
  response.Write(result)

  Return True

End Function</code></pre>



<p>The answer is, &#8220;Yes!&#8221;&nbsp; This is all the code in the entire project.</p>



<p>You will notice that there is no security, but in this instance that is fine as the virtual machine is running this is on the same network as the client server and the firewall is configured to only allow connections from that server.</p>



<p>After processing over 60 thousand requests, memory use is 7.3MB and never exceeded 13MB.&nbsp;CPU usage was at the maximum 1.5%.</p>



<p>Even after using Xojo for 20 years this still blows my mind.</p>



<p><em>Wayne Golding has been a Xojo developer since 2005 and is a Xojo MVP. He operates the IT Company <a href="http://www.axisdirect.nz">Axis Direct Ltd </a>which primarily develops applications using Xojo that integrate with Xero www.xero.com. Wayne’s hobby is robotics where he uses Xojo to build applications for his Raspberry Pi, often implementing IoT for remote control.</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>Everything You Need to Know About Variants in Xojo</title>
		<link>https://blog.xojo.com/2024/10/10/everything-you-need-to-know-about-variants-in-xojo/</link>
		
		<dc:creator><![CDATA[Martin T.]]></dc:creator>
		<pubDate>Thu, 10 Oct 2024 16:45:00 +0000</pubDate>
				<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Beginner Tips]]></category>
		<category><![CDATA[Data Type]]></category>
		<category><![CDATA[Variants]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13893</guid>

					<description><![CDATA[One of the most interesting features in Xojo is the Variant data type. We will explore the so-called “Implicit Conversions,” discuss the pros and cons&#8230;]]></description>
										<content:encoded><![CDATA[
<p>One of the most interesting features in Xojo is the Variant data type. We will explore the so-called “Implicit Conversions,” discuss the pros and cons of using Variants, and analyze when it makes sense to use this data type.</p>



<p>For more detailed information, you can refer to the official Xojo documentation on <a href="https://documentation.xojo.com/api/data_types/variant.html" target="_blank" rel="noreferrer noopener">Variants</a>.</p>



<h2 class="wp-block-heading">What are Variants?</h2>



<p>A Variant in Xojo is a data type that can store any type of data. This means that a variable of type Variant can take on different data types without needing to be explicitly converted. This can be very useful when you want to be flexible, but it can also lead to unexpected problems if not handled correctly.</p>



<p>Basic Example</p>



<pre class="wp-block-code"><code>Var dynamicValue As Variant

dynamicValue = 42                              // Integer
dynamicValue = "Hello"                         // String
dynamicValue = 3.14                            // Double
dynamicValue = True                            // Boolean
dynamicValue = Color.RGB(255, 0, 0)            // Color
dynamicValue = New Dictionary("key" : "value") // Dictionary</code></pre>



<p>In the example above, you can see that dynamicValue can take on different data types without the need to explicitly change the type.</p>



<h2 class="wp-block-heading">Implicit Conversions</h2>



<p>Implicit Conversions are automatic type conversions performed by Xojo when using Variants. This means that Xojo tries to interpret the data in a Variant so that it fits the context in which it is used.</p>



<h3 class="wp-block-heading">Example of an Implicit Conversion</h3>



<pre class="wp-block-code"><code>Var dynamicValue As Variant = "123"

Var myInteger As Integer
myInteger = dynamicValue  // Implicit conversion from String to Integer</code></pre>



<p>In this example, the string “123” is automatically converted to an integer when assigned to the integer variable myInteger.</p>



<h3 class="wp-block-heading">Another Example with Data Types</h3>



<pre class="wp-block-code"><code>Var dynamicValue As Variant = "3.14159"

Var myDouble As Double
myDouble = dynamicValue  // Implicit conversion from String to Double</code></pre>



<p>Here, the string “3.14159” is automatically converted to a double. This demonstrates the flexibility of Variants and Xojo’s ability to handle different data types.</p>



<h2 class="wp-block-heading">Conversion of Floating-Point Numbers</h2>



<p>In Xojo, assigning a floating-point number to a Variant will always produce a Double. However, there are other floating-point data types such as Single, Currency, and CGFloat.</p>



<pre class="wp-block-code"><code>Var dynamicValue As Variant = 3.14

Var myDouble As Double
Var mySingle As Single
Var myCurrency As Currency
Var myCGFloat As CGFloat

myDouble = dynamicValue   // Double: 3.14
mySingle = dynamicValue   // Single 3.14 (implicitly converted)
myCurrency = dynamicValue // Currency: 3.14 (implicitly converted)
myCGFloat = dynamicValue  // CGFloat: 3.14 (implicitly converted)</code></pre>



<p>In this example, you can see that assigning dynamicValue (which contains a floating-point number) to different floating-point data types always works, with the implicit conversion performed by Xojo.</p>



<h2 class="wp-block-heading">Advantages of Implicit Conversions</h2>



<p></p>



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



<p>The biggest advantage of Variants is their flexibility. You can write functions that can work with different data types without requiring explicit type conversion.</p>



<h3 class="wp-block-heading">Example of a Flexible Function</h3>



<pre class="wp-block-code"><code>Function AddValues(value1 As Variant, value2 As Variant) As Variant
  Return value1 + value2
End Function

// Using the function with different data types
Var result As Variant
result = AddValues(10, 20)             // Integer addition
result = AddValues("Hello", " World")  // String concatenation
result = AddValues(3.14, 2.71)         // Double addition</code></pre>



<p>This function can work with integers, strings, and doubles without requiring changes to the code.</p>



<h3 class="wp-block-heading">Rapid Prototyping</h3>



<p>During rapid prototyping, Variants can be useful because they reduce the need to worry about type conversions.</p>



<h3 class="wp-block-heading">Example of a Quick Prototype</h3>



<pre class="wp-block-code"><code>Var quickData As Variant = "42"

If quickData &gt; 10 Then
  MessageBox("Greater than 10")
End If</code></pre>



<p>In this example, the string “42” is automatically converted to an integer to perform the comparison.</p>



<h2 class="wp-block-heading">Disadvantages of Implicit Conversions</h2>



<p></p>



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



<p>It can be difficult to debug errors caused by incorrect type conversions. Since the conversion happens automatically, it is sometimes not obvious why a particular error occurs.</p>



<h3 class="wp-block-heading">Performance Issues</h3>



<p>Implicit conversions can lead to performance issues, especially when large amounts of data need to be converted.</p>



<h3 class="wp-block-heading">Example of Performance Issues</h3>



<pre class="wp-block-code"><code>Var dynamicValue As Variant = "9999999999"
Var myDouble As Double

For i As Integer = 1 To 1000000
  myDouble = dynamicValue  // Performance hit due to repeated conversions
Next</code></pre>



<p>In this example, the conversion is performed during each iteration of the loop, which can impact performance.</p>



<h3 class="wp-block-heading">Loss of Type Safety</h3>



<p>Another risk is the loss of type safety, which can lead to unexpected runtime errors.</p>



<h2 class="wp-block-heading">Type Property</h2>



<p>The Type property is a useful tool to determine the data type of a Variant value. This property returns an integer that corresponds to the type of the value. This can be helpful to ensure that you are handling the correct data type.</p>



<h3 class="wp-block-heading">Example of Using the Type Property</h3>



<pre class="wp-block-code"><code>Var dynamicValue As Variant = "Hello"

Select Case dynamicValue.Type
Case Variant.TypeString
  MessageBox("The variant is a String.")
Case Variant.TypeInt32, _
     Variant.TypeInt64
  MessageBox("The variant is an Integer.")
Case Variant.TypeDouble
  MessageBox("The variant is a Double.")
Case Variant.TypeBoolean
  MessageBox("The variant is a Boolean.")
Else
  MessageBox("The variant is of another type.")
End Select</code></pre>



<p>In this example, dynamicValue.Type is used to determine the type of the Variant value and perform corresponding actions.</p>



<h2 class="wp-block-heading">When Should You Use Variants? </h2>



<p></p>



<h3 class="wp-block-heading">Suitable Use Cases</h3>



<p></p>



<h3 class="wp-block-heading">Generic Functions</h3>



<p>If you are writing functions that need to work with different data types, Variants can be very useful.</p>



<pre class="wp-block-code"><code>Function CompareValues(value1 As Variant, value2 As Variant) As Boolean
  Return value1 = value2
End Function

// Using the function with different data types
Var isEqual As Boolean
isEqual = CompareValues(10, 10)          // True
isEqual = CompareValues("Hello", "Hello")  // True
isEqual = CompareValues(3.14, 2.71)      // False</code></pre>



<h3 class="wp-block-heading">Interoperability with External APIs</h3>



<p>When working with APIs or interfaces that return different data types, Variants can provide an easy way to handle this data.</p>



<pre class="wp-block-code"><code>// Example API response that can return different data types
Function GetApiResponse() As Variant
  // Simulated API response
  Return "42"  // Could also be an Integer or a JSON object
End Function

Var apiResponse As Variant = GetApiResponse

If apiResponse.Type = Variant.TypeString Then
  MessageBox("Response is a string: " + apiResponse)
ElseIf apiResponse.Type = Variant.TypeInt32 Or _
       apiResponse.Type = Variant.TypeInt64 Then
  MessageBox("Response is an integer: " + apiResponse)
End If</code></pre>



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



<p>In situations where you need data structures that contain different data types (e.g., an array that can contain both strings and numbers), Variants are a good choice.</p>



<pre class="wp-block-code"><code>Var dataList() As Variant
dataList.Add("Xojo")
dataList.Add(2024)
dataList.Add(True)

// Accessing different data types in the array
For Each item As Variant In dataList
  Select Case item.Type
  Case Variant.TypeString
    MessageBox("String: " + item) 
  Case Variant.TypeInt32, _
       Variant.TypeInt64
    MessageBox("Integer: " + item) 
  Case Variant.TypeBoolean
    MessageBox("Boolean: " + item)
  End Select
Next</code></pre>



<h2 class="wp-block-heading">Situations to Avoid Using Variants</h2>



<p></p>



<h3 class="wp-block-heading">Performance-Critical Applications</h3>



<p>When performance is critical, you should avoid Variants because automatic type conversion introduces additional overhead.</p>



<pre class="wp-block-code"><code>Var dynamicValue As Variant = "9999999999"
Var myDouble As Double

For i As Integer = 1 To 1000000
  myDouble = dynamicValue  // Performance hit due to repeated conversions
Next</code></pre>



<h3 class="wp-block-heading">Code Clarity and Maintainability</h3>



<p>When code readability and maintainability are paramount, you should use explicit data types to ensure that the code is understandable to other developers.</p>



<pre class="wp-block-code"><code>Var myString As String = "Hello"
Var myInteger As Integer = 123

Function ConcatenateStrings(s1 As String, s2 As String) As String
  Return s1 + s2
End Function

Var result As String
result = ConcatenateStrings(myString, myInteger.ToString)  // Clear and understandable</code></pre>



<p>The use of Variants in Xojo offers both advantages and disadvantages. While flexibility and rapid prototyping capabilities are compelling arguments, you should be aware of the potential problems that can arise from implicit conversions. Variants are best suited for scenarios where flexibility and generic programming are required. In performance-critical applications or projects that require high maintainability, it is advisable to use explicit data types such as String, Integer, Double, Boolean, Color etc. or, if you decide to use Variant, you can also have the explicit data type of the Variant delivered. To do this, use the Variant &#8230;Value properties (for example StringValue, IntegerValue, BooleanValue etc.).</p>



<p>By taking a conscious and deliberate approach to using Variants, you can leverage their advantages while avoiding potential pitfalls.</p>



<p>For more detailed information, you can refer to the official Xojo documentation on <a href="https://documentation.xojo.com/api/data_types/variant.html">https://documentation.xojo.com/api/data_types/variant.html</a>.</p>



<p><em>Martin T. is a Xojo MVP and has been very involved in testing Android support.</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>Using AddHandler and Delegates in Xojo</title>
		<link>https://blog.xojo.com/2024/10/07/using-addhandler-and-delegates-in-xojo/</link>
		
		<dc:creator><![CDATA[Martin T.]]></dc:creator>
		<pubDate>Mon, 07 Oct 2024 15:00:00 +0000</pubDate>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[AddHandler]]></category>
		<category><![CDATA[Delegates]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13844</guid>

					<description><![CDATA[In Xojo, there are different ways to control the behavior of methods, events, and callbacks. Two commonly used mechanisms are AddHandler and Delegates. Both are&#8230;]]></description>
										<content:encoded><![CDATA[
<p>In Xojo, there are different ways to control the behavior of methods, events, and callbacks. Two commonly used mechanisms are <em>AddHandler </em>and <em>Delegates</em>. Both are designed to dynamically reference and invoke functions or methods at runtime. Although they share similar goals, they differ in implementation and usage. In this article, we will explain the similarities and differences between <em>AddHandler </em>and <em>Delegates </em>in Xojo and demonstrate how you can achieve the same result using both approaches.</p>



<h2 class="wp-block-heading">What are Delegates?</h2>



<p>A Delegate in Xojo is essentially a “pointer” to a method. It allows you to dynamically reference a method, treating it as if it were a variable. This means that a method can be passed to another method or function like a data variable.</p>



<pre class="wp-block-code"><code>' Defining a Delegate
Delegate Sub MyDelegateMethod(value As Integer)

' Method to be called
Sub PrintNumber(value As Integer)
  MessageBox("Number: " + value.ToString)
End Sub

' Using the Delegate
Sub UseDelegate()
  Var d As MyDelegateMethod = AddressOf PrintNumber
  d.Invoke(10) ' Calls PrintNumber with the value 10
End Sub</code></pre>



<p>In this example, a delegate <em>MyDelegateMethod </em>is defined to reference a method with an Integer parameter. Then, the method <em>PrintNumber </em>is assigned to the delegate variable <em>d</em>, and it is invoked using <em>d.Invoke()</em>.</p>



<h2 class="wp-block-heading">What is AddHandler?</h2>



<p>The <em>AddHandler </em>command is used in Xojo to dynamically associate a method with an event. Instead of assigning an event handler in the design phase, this can be done at runtime. This allows for more flexible programming, especially in situations where event handling routines need to be assigned or changed dynamically.</p>



<pre class="wp-block-code"><code>' Method that acts as an event handler
Sub ButtonPressed(sender As DesktopButton)
  MessageBox("Button was pressed!")
End Sub

' Using AddHandler
Sub SetupButtonHandler(button As DesktopButton)
  AddHandler button.Pressed, AddressOf ButtonPressed
End Sub</code></pre>



<p>In this example, the <em>ButtonPressed </em>method is dynamically associated with the <em>Pressed </em>event of a DesktopButton. When the button is pressed, the <em>ButtonPressed </em>method shows a message.</p>



<h3 class="wp-block-heading">Important Note: Using RemoveHandler with AddHandler</h3>



<p>Whenever you use <em>AddHandler</em>, it’s important to remember to use <em>RemoveHandler </em>to properly un-assign the event handler when it’s no longer needed. If you fail to remove the handler, you may encounter memory leaks or unexpected behavior, especially when working with objects that are frequently created and destroyed.</p>



<pre class="wp-block-code"><code>' Removing the event handler
Sub RemoveButtonHandler(button As DesktopButton)
  RemoveHandler button.Pressed, AddressOf ButtonPressed
End Sub</code></pre>



<p>In this case, <em>RemoveHandler </em>is used to detach the <em>ButtonPressed </em>method from the <em>Pressed </em>event of the DesktopButton. This is especially useful when a button or event source is about to be destroyed or when you no longer want the handler to respond to events.</p>



<h2 class="wp-block-heading">Similarities between AddHandler and Delegates</h2>



<ol class="wp-block-list">
<li><strong>Dynamic Behavior:</strong> Both <em>Delegates </em>and <em>AddHandler </em>allow for the dynamic assignment of methods, providing more flexibility in the flow of the program.</li>



<li><strong>Method Referencing:</strong> Both concepts use the <em>AddressOf </em>syntax to reference a method.</li>



<li><strong>Flexibility:</strong> Both mechanisms are useful for reacting to specific events or functions at runtime.</li>
</ol>



<h2 class="wp-block-heading">Differences between AddHandler and Delegates </h2>



<p>1. <strong>Purpose:</strong></p>



<ul class="wp-block-list">
<li>Delegates are more general and are used to treat methods as variables and pass them as parameters to other methods.</li>



<li>AddHandler is specifically designed for event handling. It is used to assign methods to events at runtime.</li>
</ul>



<p>2. <strong>Target Structure:</strong></p>



<ul class="wp-block-list">
<li>Delegates are strongly typed. They require an exact match between the method signature and the delegate.</li>



<li>AddHandler binds methods to events, which require a predetermined signature but are dictated by the context of the object used.</li>
</ul>



<p>3. <strong>Lifetime:</strong></p>



<ul class="wp-block-list">
<li>Delegates can exist as standalone variables within any scope.</li>



<li>AddHandler is tied to the event and object it is associated with. If the event or object is destroyed, the handler is no longer called.</li>
</ul>



<h2 class="wp-block-heading">Achieving the same functionality with both approaches</h2>



<p></p>



<h3 class="wp-block-heading">Event Handling with AddHandler</h3>



<p>Let’s assume we have a timer event and want to specify at runtime which method should be called when the timer elapses.</p>



<pre class="wp-block-code"><code>' Method called by the Timer event
Sub TimerAction(sender As Timer)
  MessageBox("Timer elapsed!")
End Sub

' Dynamically assigning the event with AddHandler
Sub SetupTimer(timer As Timer)
  #If TargetMobile
    AddHandler timer.Run, AddressOf TimerAction
  #Else
    AddHandler timer.Action, AddressOf TimerAction
  #EndIf

  timer.RunMode = Timer.RunModes.Multiple
  timer.Period = 1000
End Sub</code></pre>



<p>In this example, the <em>TimerAction </em>method is assigned to the Run/Action event of a timer at runtime.</p>



<h3 class="wp-block-heading">Same Functionality with Delegates</h3>



<p>Now, the same logic but using Delegates:</p>



<pre class="wp-block-code"><code>' Defining a Delegate for Timer actions
Delegate Sub TimerDelegate(sender As Timer)

' Method to be called
Sub TimerAction(sender As Timer)
  MessageBox("Timer elapsed!")
End Sub

' Assigning and invoking the method via a Delegate
Sub SetupTimerWithDelegate(timer As Timer)
  Var d As TimerDelegate = AddressOf TimerAction

  #If TargetMobile
    AddHandler timer.Run, d
  #Else
    AddHandler timer.Action, d
  #EndIf

  timer.RunMode = Timer.RunModes.Multiple
  timer.Period = 1000
End Sub</code></pre>



<p>In this case, a Delegate is used to reference the same <em>TimerAction </em>method, but the structure remains nearly identical.</p>



<p><em>AddHandler </em>and <em>Delegates </em>both provide ways to dynamically handle methods at runtime in Xojo. While <em>Delegates </em>are more flexible and general-purpose, <em>AddHandler </em>is specifically designed for dynamic event handling. Both mechanisms are useful depending on the use case. The main difference lies in how they are used and their target structure: <em>Delegates </em>are strongly typed and can be used anywhere in the code, whereas <em>AddHandler </em>is used to link methods to events dynamically.</p>



<p>Additionally, when using <em>AddHandler</em>, it is crucial to remember to use <em>RemoveHandler </em>to properly unbind event handlers when they are no longer needed. Failing to do so can lead to performance issues, memory leaks, or unintended behavior, especially when dealing with dynamic or temporary objects.</p>



<p>By combining these two techniques, you can make Xojo programs more flexible and dynamic.</p>



<p>Happy Coding!</p>



<p><em>Martin T. is a Xojo MVP and has been very involved in testing Android support.</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>Generating a Unique UUID in Xojo for Android</title>
		<link>https://blog.xojo.com/2024/10/02/generating-a-unique-uuid-in-xojo-for-android/</link>
		
		<dc:creator><![CDATA[Xojo]]></dc:creator>
		<pubDate>Wed, 02 Oct 2024 15:00:00 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[UUID]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13838</guid>

					<description><![CDATA[In the world of mobile app development, it’s often necessary to generate a universally unique identifier (UUID) to identify data or devices uniquely. If you’re&#8230;]]></description>
										<content:encoded><![CDATA[
<p>In the world of mobile app development, it’s often necessary to generate a universally unique identifier (UUID) to identify data or devices uniquely. If you’re a Xojo developer building apps for Android, you can easily generate a UUID using the function below. This function leverages the built-in UUID generation from Android’s Java class library.</p>



<h2 class="wp-block-heading">What is a UUID?</h2>



<p>A UUID (Universally Unique Identifier) is a 128-bit value that is unique worldwide. UUIDs are commonly used in software development to identify objects and have the format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, where each “x” is a hexadecimal digit.</p>



<h2 class="wp-block-heading">The Code: GenerateUUID</h2>



<p>The following code shows a simple Xojo function that uses the built-in Java method on Android to generate a UUID. The function allows you to create the UUID either with or without hyphens, depending on your project requirements.</p>



<h3 class="wp-block-heading">The Code:</h3>



<pre class="wp-block-code xojo"><code>Function GenerateUUID(useHyphens As Boolean = True) As String
' https://developer.android.com/reference/java/util/UUID
  Declare Function generateUUID Lib "java.util.UUID" Alias "randomUUID().toString" As CString

  Var uuid As String = generateUUID

  If useHyphens Then
    Return uuid
  Else
    Return uuid.ReplaceAll("-", "")
  End If
End Function</code></pre>



<h3 class="wp-block-heading">Code Explanation:</h3>



<p>● <em>Declare Function generateUUID</em>: This <em>Declare </em>statement gives us access to Android’s native Java library. We use the shared <em>randomUUID </em>method from the <em>java.util.UUID </em>class to generate a random UUID. This method returns the UUID as a string.</p>



<p>● <em>Var uuid As String = generateUUID</em>: The generated UUID is stored as a string.</p>



<p>● &nbsp;<em>useHyphens</em>: This optional parameter controls whether the UUID is returned with or without hyphens. The default value is <em>True</em>, meaning the UUID will be returned in its usual format with hyphens.</p>



<p>● &nbsp;<em>If useHyphens Then &#8230; Else</em>: Depending on the value of <em>useHyphens</em>, either the standard UUID is returned or a hyphen-free version, where the <em>ReplaceAll </em>method is used to replace all hyphens with an empty string. </p>



<h2 class="wp-block-heading">Use in Your Android Project: </h2>



<p>1. <em>UUID with Hyphens</em>: If you want to get the UUID in its standard format with hyphens, you can call the function without any arguments: </p>



<pre class="wp-block-code"><code>Var myUUID As String = GenerateUUID 
' Example result: 123e4567-e89b-12d3-a456-426614174000 </code></pre>



<p>2. <em>UUID without Hyphens</em>: If you prefer a UUID without hyphens, you can pass the argument <em>False </em>to the function: </p>



<pre class="wp-block-code"><code>Var myUUID As String = GenerateUUID(False) 
' Example result: 123e4567e89b12d3a456426614174000 </code></pre>



<h2 class="wp-block-heading">Why Use UUIDs? </h2>



<p>UUIDs are ideal for cases where you need to ensure that every generated identifier is unique, even if they are generated by different devices or systems. Some common use cases in Android development with Xojo include:</p>



<p>● &nbsp;Uniquely identifying users or devices</p>



<p>● &nbsp;Creating keys for database entries</p>



<p>● &nbsp;Tagging objects in a distributed application where no identifier conflicts should occur</p>



<p>With the GenerateUUID<em> </em>function, you can easily generate a unique UUID on Android devices using Xojo, without worrying about the complexities of native Android APIs. This method integrates seamlessly into your Android application and offers the flexibility to generate UUIDs with or without hyphens. If you’re working on a project where uniqueness is crucial, using UUIDs should be at the top of your list. </p>



<p>Good luck with your Android project in Xojo!</p>



<p><em>Martin T. is a Xojo MVP and has been very involved in testing Android support.</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>Android Design Extensions 3.0 for Xojo 2024r3+</title>
		<link>https://blog.xojo.com/2024/10/01/android-design-extensions-3-0-for-xojo-2024r3/</link>
		
		<dc:creator><![CDATA[Martin T.]]></dc:creator>
		<pubDate>Tue, 01 Oct 2024 15:55:28 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Android Design Extensions]]></category>
		<category><![CDATA[Declares]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13827</guid>

					<description><![CDATA[Version 2024r3 of Xojo has just been released. So it&#8217;s time for an update of the Android Design Extension 3.0. This version works from version&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Version 2024r3 of Xojo has just been released. So it&#8217;s time for an update of the Android Design Extension 3.0. This version works from version 2024r3+, because in this version Xojo has revised the Declare Framework enormously and Declares now work in Android projects in the same way as in the other targets. This means that we are no longer bound to the Object Declares introduced in Android. So what are the new features of the Android Design Extensions 3.0?</p>



<p>From now on, Buttons and TextFields can use Xojo Pictures directly and you no longer need to save images that you want to use. Take a look at the “Deprecations Version 3.0” section in the Read me to find out which methods are deprecated in this regard.</p>



<h2 class="wp-block-heading">Now it&#8217;s getting colorful!</h2>



<p>In this version, support for over 180 system colors has been added, depending on which Android version your app is running on. The sample app has a new page with the system colors. It gives you a good overview. Using these colors can help you to design your apps according to the Material Design Guidelines in light &amp; dark mode.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="498" height="1024" src="https://blog.xojo.com/wp-content/uploads/2024/10/android-screenshots-1-498x1024.png" alt="" class="wp-image-13831" srcset="https://blog.xojo.com/wp-content/uploads/2024/10/android-screenshots-1-498x1024.png 498w, https://blog.xojo.com/wp-content/uploads/2024/10/android-screenshots-1-146x300.png 146w, https://blog.xojo.com/wp-content/uploads/2024/10/android-screenshots-1-768x1579.png 768w, https://blog.xojo.com/wp-content/uploads/2024/10/android-screenshots-1-747x1536.png 747w, https://blog.xojo.com/wp-content/uploads/2024/10/android-screenshots-1-996x2048.png 996w, https://blog.xojo.com/wp-content/uploads/2024/10/android-screenshots-1.png 1080w" sizes="auto, (max-width: 498px) 100vw, 498px" /></figure>



<p>Picture objects and the content of a MobileHTMLViewer can now also be printed.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="996" height="1024" src="https://blog.xojo.com/wp-content/uploads/2024/10/android-made-with-xojo-996x1024.png" alt="" class="wp-image-13829" srcset="https://blog.xojo.com/wp-content/uploads/2024/10/android-made-with-xojo-996x1024.png 996w, https://blog.xojo.com/wp-content/uploads/2024/10/android-made-with-xojo-292x300.png 292w, https://blog.xojo.com/wp-content/uploads/2024/10/android-made-with-xojo-768x789.png 768w, https://blog.xojo.com/wp-content/uploads/2024/10/android-made-with-xojo-1494x1536.png 1494w, https://blog.xojo.com/wp-content/uploads/2024/10/android-made-with-xojo-1993x2048.png 1993w" sizes="auto, (max-width: 996px) 100vw, 996px" /></figure>



<p>We are familiar with the DrawInto method from the Desktop Framework, which draws DesktopUIControls and DesktopWindows into a Graphics object. These methods have now also been added for MobileUIControls and MobileScreen.</p>



<p>The title bar and the NavigationBar can now also be highlighted in color. The font, color and alignment of the NavigationBar can also be changed.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="498" height="1024" src="https://blog.xojo.com/wp-content/uploads/2024/10/android-019EFFD9-4A4A-48A1-A477-B1948F7B9D58-498x1024.png" alt="" class="wp-image-13832" srcset="https://blog.xojo.com/wp-content/uploads/2024/10/android-019EFFD9-4A4A-48A1-A477-B1948F7B9D58-498x1024.png 498w, https://blog.xojo.com/wp-content/uploads/2024/10/android-019EFFD9-4A4A-48A1-A477-B1948F7B9D58-146x300.png 146w, https://blog.xojo.com/wp-content/uploads/2024/10/android-019EFFD9-4A4A-48A1-A477-B1948F7B9D58-768x1579.png 768w, https://blog.xojo.com/wp-content/uploads/2024/10/android-019EFFD9-4A4A-48A1-A477-B1948F7B9D58-747x1536.png 747w, https://blog.xojo.com/wp-content/uploads/2024/10/android-019EFFD9-4A4A-48A1-A477-B1948F7B9D58-996x2048.png 996w, https://blog.xojo.com/wp-content/uploads/2024/10/android-019EFFD9-4A4A-48A1-A477-B1948F7B9D58.png 1080w" sizes="auto, (max-width: 498px) 100vw, 498px" /></figure>



<h2 class="wp-block-heading">How? What? Where?</h2>



<p>The system paths for various folders (SpecialFolder) have also been added.</p>



<p>Almost all modules have been updated according to the new Declare data types. The example app has also been further optimized for dark mode in this version.</p>



<p>The new Declare capabilities in Xojo 2024r3 are another huge step forward. You now have the possibility to declare in almost every Android API without having to go through an Android library.</p>



<p>Feel free to take a look at the developer repository, create feature requests, and provide feedback on extending this extension library.</p>



<p>I’m happy to receive any voluntary financial support for the work I’ve done so far, which you are welcome to <a href="https://www.paypal.com/paypalme/MTrippensee" target="_blank" rel="noreferrer noopener">share here</a>. You can download the project with many examples at <a href="https://github.com/XojoGermany/AndroidDesignExtensions" target="_blank" rel="noreferrer noopener">https://github.com/XojoGermany/AndroidDesignExtensions</a>.</p>



<p>Happy coding.</p>



<p><em>Martin T. is a Xojo MVP and has been very involved in testing Android support.</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>Preemptive Threads Are Here, and They Are… Pretty Good</title>
		<link>https://blog.xojo.com/2024/10/01/preemptive-threads-are-here-and-they-are-pretty-good/</link>
		
		<dc:creator><![CDATA[Kem Tekinay]]></dc:creator>
		<pubDate>Tue, 01 Oct 2024 15:39:29 +0000</pubDate>
				<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[2024r3]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Preemptive Threads]]></category>
		<category><![CDATA[Threading]]></category>
		<category><![CDATA[Threads]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13693</guid>

					<description><![CDATA[At long last, Xojo has introduced what might be the most-requested feature of all time: preemptive threads. But what are they, when and how do&#8230;]]></description>
										<content:encoded><![CDATA[
<p>At long last, Xojo has introduced what might be the most-requested feature of all time: preemptive threads. But what are they, when and how do you use them, and what are their limitations? Let&#8217;s get into it…</p>



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



<p>Threads have been a part of of the Xojo language for a long time, and by now experienced users know the basics: subclass a <code>Thread</code>, fill in the <code>Run</code> event, then call <code>Start</code>. The code in <code>Run</code> will execute independently from the rest of your code leaving your app responsive while it does work in the background.</p>



<p>Mostly.</p>



<p>See, until now, a <code>Thread</code> was only &#8220;cooperative&#8221;, meaning it ran alongside your main code with the framework deciding when to switch between them and how long each should execute. While the main code was running, the <code>Thread</code> code was paused, and while the <code>Thread</code> was running, the main code was paused.</p>



<p>Think of it like standing before two devices that perform different functions when cranked, but only having one crank available. You run the first machine for a bit, then the other, then back to the first, until they are done. And you do it really, really fast.</p>



<p>This worked pretty well when your goal was, say, to keep your user interface responsive. You could spin long-running code into a <code>Thread</code>, then present the results once it finished.</p>



<p>But it was inadequate if your objective was to speed up some intense process, or the code in your <code>Thread</code> did not present logical places to yield time back to your main code. In the former scenario, you were better off not using a <code>Thread</code>, or perhaps using <code>Worker</code> (a severely limited earlier attempt at allowing simultaneous processing), while in the latter you would have to manually yield back processing time, leading to even slower operation.</p>



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



<p>Cooperative threads are fine for many tasks, but when you need something that truly runs independently within your app, a &#8220;preemptive&#8221; thread is required.</p>



<p>A preemptive thread spins off onto another core in your machine, which probably has at least four, and runs there entirely isolated from other threads. It&#8217;s like launching a separate, mini-app that you can share information with.</p>



<p>The limitations that apply to cooperative threads drop away. Since it runs on a different core, it cannot slow down or interfere with your main code, and will run as fast as its core will allow.</p>



<h2 class="wp-block-heading">Challenging Times</h2>



<p>This sounds almost too good to be true, but it&#8217;s not without its challenges. While cooperative threads were rather easy to work with, preemptive threads require an extra layer of thought and awareness for Xojo users.</p>



<p>When a cooperative thread&#8217;s code is running, you know nothing else is, so you don&#8217;t have to worry about, say, updating a <code>Dictionary</code> or removing an element from an array. But with preemptive threads, code runs simultaneously with other code so you cannot just update that <code>Dictionary</code> if there is a chance that the main code, or another preemptive thread, might be doing it too.</p>



<p>Consider this example.</p>



<pre class="wp-block-code"><code>// In our thread
If MyArray.Count = 0 And FinishUp Then
  Exit
Else
  Process MyArray.Pop
End If

//////////////////////////////

// In the main code
FinishUp = True
MyArray.Add 1</code></pre>



<p>You might think the thread is going to process the last element and then exit its loop because <code>FinishUp</code> was set to <code>True</code>, but with preemptive threads we have to be aware of <a href="https://en.wikipedia.org/wiki/Race_condition">race conditions</a> where the order of actions is unpredictable. Here, the main code could set <code>FinishUp</code> to <code>True</code>, and the thread could see that <code>MyArray</code> was empty and exit before the main code could add the last element. Conditions can change at literally any instant, even in the middle of a single line of code.</p>



<p>Fortunately, there are ways to protect against this and you must use them to ensure orderly operation and avoid surprises.</p>



<h2 class="wp-block-heading">Know Your Type</h2>



<p>The first step is creating a preemptive thread, and Xojo&#8217;s implementation is pretty straightforward. Rather than introducing a unique class, you can continue to work with the existing <code>Thread</code> by setting its new <code>Type</code> property to <code>Thread.Types.Preemptive</code>. The <code>Type</code> can be set when instantiating the <code>Thread</code> or from within its running code. You can even switch types at will, although once running, the <code>Type</code> can only be changed from within the <code>Thread</code>.</p>



<p>Example:</p>



<pre class="wp-block-code"><code>// A subclass of Thread called PThread

MyThread = New PThread
PThread.Type = Thread.Types.Preemptive
PThread.Start</code></pre>



<p>Or within the <code>Run</code> event, you could do this:</p>



<pre class="wp-block-code xojo"><code>Me.Type = Thread.Types.Preemptive</code></pre>



<p>You can also set <code>Type</code> through the Inspector after dragging a <code>Thread</code> to a window.</p>



<h2 class="wp-block-heading">Protect Yourself</h2>



<p>Now that you have a preemptive thread ready to go, you have to think about how to protect common resources. Xojo has done a good job of making a lot of the framework safe, but that just means your app shouldn&#8217;t crash if, say, the <code>Thread</code> tries to manipulate a variable at the same time as other code. It&#8217;s up to you to make sure one area of your app doesn&#8217;t clobber the changes made by another.</p>



<p>Consider this code that maintains a <code>Dictionary</code> of Integer arrays.</p>



<pre class="wp-block-code"><code>// Thread code
Var arr() As Integer

If MyDictionary.HasKey(x) Then
  arr = MyDictionary.Value(x)
Else
  MyDictionary.Value(x) = arr
End If

arr.Add 1

//////////////////////////////

// Main code
If Not MyDictionary.HasKey(x) Then
  Var arr() As Integer
  MyDictionary.Value(x) = arr
End If</code></pre>



<p>Run this long enough and you&#8217;re going to wonder why some data got lost. Why? Because both the <code>Thread</code> and main code might be checking for the key at the exact same instant and filling it in when it&#8217;s not found. If the <code>Thread</code> does it first, the main code will almost instantly replace it with an empty array.</p>



<p>Instead, you should use a <code>Semaphore</code> or <code>CriticalSection</code> to make sure code is protected.</p>



<p>You&#8217;d first instantiate one of these in a common property like a <code>Window</code> or <code>Module</code>. (I&#8217;m using <code>Semaphore</code> here, but it works the same for <code>CriticalSection</code>.)</p>



<pre class="wp-block-code Xojo"><code>MySemaphore = New Semaphore
MySemaphore.Type = Thread.Types.Preemptive</code></pre>



<p>Notice the new <code>Type</code> property? It must match the one in <code>Thread</code> and can be used between the main code and a <code>Thread</code> or between same-typed threads. (This is one of the limitations of Xojo&#8217;s implementation: you cannot share a <code>Semaphore</code> or <code>CriticalSection</code> between preemptive and cooperative threads.)</p>



<p>The example can be updated like this:</p>



<pre class="wp-block-code"><code>// Thread code
Var arr() As Integer

MySemaphore.Signal

If MyDictionary.HasKey(x) Then
  arr = MyDictionary.Value(x)
Else
  MyDictionary.Value(x) = arr
End If

MySemaphore.Release

arr.Add 1

//////////////////////////////

// Main code
MySemaphore.Signal

If Not MyDictionary.HasKey(x) Then
  Var arr() As Integer
  MyDictionary.Value(x) = arr
End If

MySemaphore.Release</code></pre>



<p>This will force either the main code or <code>Thread</code> to wait for the other to complete before continuing, ensuring proper order and avoiding the race condition.</p>



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



<p>Using preemptive threads comes with certain restrictions. The biggest one is the aforementioned inability to share a <code>Semaphore</code> or <code>CriticalSection</code> with a cooperative thread. The other is the same as in a cooperative thread: you cannot update a user interface component directly instead relying on the <code>UserInterfaceUpdate</code> mechanism (more on that below).</p>



<p>If you are setting up multiple threads to work on different parts of some object, that may crash hard depending on the type of object. For example, writing to the same file or different parts of a <code>MemoryBlock</code> is fine, but updating a <code>Picture</code> may not be. In those cases, you will have to get creative.</p>



<h2 class="wp-block-heading">What&#8217;s It Good For?</h2>



<p>Choosing preemptive threads over cooperative means that you either have some code that needs to truly run in the background that would otherwise interfere with you user interface, or you have some large task that can be logically processed in parts.</p>



<h3 class="wp-block-heading">Window Service</h3>



<p>In the former case, the easiest technique might be to drag a <code>Thread</code> to your window, set its <code>Type</code>, and implement the <code>Run</code> event. It can be started from within the window either through a manual process like a pressing a button, or automatically when the window opens.</p>



<p>Just like with a cooperative thread, you can send data back to your window using the <code>AddUserInterfaceUpdate</code> method and implementing the <code>UserInterfaceUpdate</code> event.</p>



<h3 class="wp-block-heading">Splitting It Up</h3>



<p>If your task involves something that can be split up into logical chunks, I encourage you to look at my <code>ThreadPool</code> module, accessible through the Xojo Examples or <a href="https://github.com/ktekinay/Xojo-ThreadPool/tree/develop">my GitHub page</a>. (The latter has a README with more details.)</p>



<p>The ideal usage for <code>ThreadPool</code> is when you have some data that can be processed in sections. For example, suppose you wanted to count the vowels in a large file. You could subclass <code>ThreadPool</code> and implement its <code>Process</code> event to count one block. You would then send the file into your subclass in chunks of, say, 256k each and gather the results.</p>



<p>The benefit of <code>ThreadPool</code>, among other things, is that it will handle the coordination for you so the dangers of using preemptive threads are minimized. You still have to consider how to send your results back to your main code safely, perhaps using <code>Semaphore</code>/<code>CriticalSection</code> or the <code>AddUserInterfaceUpdate</code> method, but each block can be considered independently of the others.</p>



<p>(A big thanks to MVP Anthony Cyphers for writing the example included with Xojo.)</p>



<h2 class="wp-block-heading">Juggling Chainsaws</h2>



<p>The power of preemptive threads is clear, but the potential pitfalls can be serious. Unless you&#8217;re very careful, you can easily create bugs that may not be readily apparent, and may take hours or even days to track down. (I say this from unfortunate experience.) Unless you have a compelling reason to take on that challenge, don&#8217;t bother.</p>



<p>What I&#8217;m trying to say is, if a cooperate thread does the job adequately, there is no need to introduce the headache that preemptive threads can bring.</p>



<p>But if you do have a legitimate need, like a long-running process that needs to run quickly without blocking your UI, go for it, just be careful.</p>



<p>In any case, it&#8217;s great that we finally have that option.</p>



<p><em>Kem Tekinay is a Mac consultant and programmer who has been using Xojo since its first release to create custom solutions for clients. He is the author of the popular utilities <a href="http://www.mactechnologies.com/index.php?page=downloads#tftpclient" target="_blank" rel="noreferrer noopener">TFTP Client</a> and <a href="http://www.mactechnologies.com/index.php?page=downloads#regexrx" target="_blank" rel="noreferrer noopener">RegExRX</a> (both written with Xojo) and lives in Connecticut with his wife Lisa, and their cat.</em></p>



<p>Need More Information? Read more about <a href="https://documentation.xojo.com/api/language/thread.html#thread-type" target="_blank" rel="noreferrer noopener">preemptive threads</a> in the Xojo Documentation and <a href="https://blog.xojo.com/2024/10/01/cooperative-to-preemptive-weaving-new-threads-into-your-apps/" target="_blank" rel="noreferrer noopener">Blog</a>. Or read about <a href="https://blog.xojo.com/2024/09/05/using-semaphores-to-manage-resources/" target="_blank" rel="noreferrer noopener">Semaphore</a> and <a href="https://blog.xojo.com/2024/09/18/using-criticalsection-to-manage-resources/" target="_blank" rel="noreferrer noopener">CriticalSection</a>, also on the Xojo Blog.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Minimizing Overhead in Xojo Applications: Techniques, Tips, and Tricks</title>
		<link>https://blog.xojo.com/2024/07/10/minimizing-overhead-in-xojo-applications-techniques-tips-and-tricks/</link>
		
		<dc:creator><![CDATA[Martin T.]]></dc:creator>
		<pubDate>Wed, 10 Jul 2024 14:00:00 +0000</pubDate>
				<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Beginner Tips]]></category>
		<category><![CDATA[Code Profiling]]></category>
		<category><![CDATA[Profiler]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13295</guid>

					<description><![CDATA[In the world of software development, efficiency is a central aspect. This is especially true for applications developed in Xojo. Excessive overhead can significantly impair performance and negatively affect the user experience. In this article, we will take a detailed look at what overhead is, how to identify it, and what techniques, tips, and tricks can be used to minimize it. We will particularly focus on using code profiling.]]></description>
										<content:encoded><![CDATA[
<p>In the world of software development, efficiency is a central aspect. This is especially true for applications developed in Xojo. Excessive overhead can significantly impair performance and negatively affect the user experience. In this article, we will take a detailed look at what overhead is, how to identify it, and what techniques, tips, and tricks can be used to minimize it. We will particularly focus on using code profiling.</p>



<h2 class="wp-block-heading">What is Overhead?</h2>



<p>Overhead refers to the additional computational and memory effort that does not directly contribute to the execution of the main tasks of an application. This can arise from various factors, such as inefficient algorithms, unnecessary computations, or redundant memory allocations. High overhead can lead to slow response times and increased resource consumption.</p>



<h2 class="wp-block-heading">Identifying Overhead with Code Profiling</h2>



<p>To effectively minimize overhead, it is first important to identify it. This is where code profiling comes into play. Profiling is a runtime analysis technique that provides insight into how long certain parts of your code take to execute and how often they are called. Xojo offers integrated tools for this purpose, such as the Profiler, which gives you detailed information about your application’s performance. Code profiling is available on all targets except Android.</p>



<h3 class="wp-block-heading">Steps to Profiling in Xojo:</h3>



<ol class="wp-block-list">
<li>Activating the Profiler: Go to the menu item Project &gt; Profile Code to enable or disable the profiler.</li>



<li>Manual Profiling with <a href="https://documentation.xojo.com/api/compiler_directives/startprofiling.html">StartProfiling</a> and <a href="https://documentation.xojo.com/api/compiler_directives/stopprofiling.html">StopProfiling</a>: Use the StartProfiling and StopProfiling methods in your code to analyze specific sections.</li>



<li>Analyzing the Profiler Results: After running, you will receive a report showing which methods and functions take the most time.</li>
</ol>



<figure class="wp-block-image size-large is-style-default"><img loading="lazy" decoding="async" width="1024" height="515" src="https://blog.xojo.com/wp-content/uploads/2024/07/min-overhead-3-1024x515.png" alt="" class="wp-image-13298" srcset="https://blog.xojo.com/wp-content/uploads/2024/07/min-overhead-3-1024x515.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/07/min-overhead-3-300x151.png 300w, https://blog.xojo.com/wp-content/uploads/2024/07/min-overhead-3-768x387.png 768w, https://blog.xojo.com/wp-content/uploads/2024/07/min-overhead-3.png 1196w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-large is-style-default"><img loading="lazy" decoding="async" width="1024" height="678" src="https://blog.xojo.com/wp-content/uploads/2024/07/min-overhead-2-1024x678.png" alt="" class="wp-image-13296" srcset="https://blog.xojo.com/wp-content/uploads/2024/07/min-overhead-2-1024x678.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/07/min-overhead-2-300x199.png 300w, https://blog.xojo.com/wp-content/uploads/2024/07/min-overhead-2-768x508.png 768w, https://blog.xojo.com/wp-content/uploads/2024/07/min-overhead-2-1536x1016.png 1536w, https://blog.xojo.com/wp-content/uploads/2024/07/min-overhead-2-2048x1355.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>For more information on the Code Profiler, see the <a href="https://documentation.xojo.com/getting_started/debugging/code_profiler.html">Xojo Documentation</a>.</p>



<h2 class="wp-block-heading">Example of Manual Profiling</h2>



<p>With StartProfiling and StopProfiling, you can target specific parts of your code for profiling. Here’s a simple example:</p>



<pre class="wp-block-code"><code>Var total As Integer = 0

// Start profiling
System.DebugLog("Profiling started")
StartProfiling

For i As Integer = 0 To 1000000
  total = total + i
Next

// Stop profiling
StopProfiling
System.DebugLog("Profiling stopped")</code></pre>



<p>In this example, the profiler is activated only for the loop to analyze its performance precisely.</p>



<h2 class="wp-block-heading">Techniques to Minimize Overhead</h2>



<p>Once you have identified the areas with optimization potential, you can apply various techniques to reduce overhead:</p>



<h4 class="wp-block-heading">1. Algorithmic Optimizations:</h4>



<p>– &nbsp;Use more efficient algorithms. An O(n) solution is better than an O(n^2) solution.</p>



<p>– &nbsp;Avoid recursive algorithms when iterative solutions are available to avoid stack overhead. </p>



<h4 class="wp-block-heading">2. Memory Management:</h4>



<p>– &nbsp;Minimize unnecessary memory allocations and deallocations.</p>



<p>– &nbsp;Use local variables as much as possible and avoid global variables to reduce memory consumption. </p>



<h4 class="wp-block-heading">3. Data Structures:</h4>



<p>– &nbsp;Choose the right data structures for your requirements. For example, arrays are often faster than other structures for sequential data access.</p>



<p>– &nbsp;Use dictionaries for fast lookups as they manage key-value pairs efficiently.</p>



<h4 class="wp-block-heading">4. Asynchrony and Parallelism:</h4>



<p>– Use asynchronous programming and multithreading to perform tasks in parallel and improve the responsiveness of the user interface.</p>



<h4 class="wp-block-heading">5. Code Simplicity:</h4>



<p>– &nbsp;Write clear and simple code. Complex structures and nested loops increase overhead.</p>



<p>– &nbsp;Use Xojo’s pre-built functions and libraries, which are often more optimized than custom implementations. </p>



<h2 class="wp-block-heading">Tips and Tricks for Optimization</h2>



<h4 class="wp-block-heading">1. Lazy Loading:</h4>



<p>Load resources only when they are needed instead of loading everything at the start of the application.</p>



<h4 class="wp-block-heading">2. Caching:</h4>



<p>Implement caching mechanisms to avoid repeated computations and database queries. </p>



<h4 class="wp-block-heading">3. Avoiding Polymorphism:</h4>



<p>Polymorphic calls are often more expensive than direct function calls. Use them only when necessary. Polymorphism is a concept in object-oriented programming that allows objects of different classes to be treated through a common interface. In Xojo, this means you can define methods in a base class and override them in derived classes. However, this can add overhead as the exact method call must be resolved at runtime.</p>



<h4 class="wp-block-heading">4. Using Breakpoints and Inspectors:</h4>



<p>Set breakpoints and use the debugger inspector to check runtime data and identify inefficient parts of the code.</p>



<h2 class="wp-block-heading">Example: Optimizing a Loop</h2>



<p>Here is an example of how to optimize a loop:</p>



<pre class="wp-block-code"><code>// Unoptimized code
Var total As Integer = 0
For i As Integer = 0 To dataArray.LastIndex
  total = total + dataArray(i)
Next

// Optimized code
Var total As Integer = 0
Var lastIndex As Integer = dataArray.LastIndex
For i As Integer = 0 To lastIndex
  total = total + dataArray(i)
Next</code></pre>



<p>In this example, we moved the LastIndex method call out of the loop since repeatedly calling it creates unnecessary overhead.</p>



<p>Minimizing overhead in Xojo applications requires careful analysis and optimization of your code. By using code profiling, you can identify the areas that consume the most runtime and take targeted actions to optimize them. The techniques, tips, and tricks presented here can significantly improve the efficiency of your applications and ensure a better user experience.</p>



<p>Leverage Xojo’s powerful tools to keep your applications lean and fast, and benefit from improved performance.</p>



<p>Happy coding!</p>



<p><em>Martin T. is a Xojo MVP and has been very involved in testing Android support.</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>Clean Coding in Xojo: Best Practices for Writing Maintainable Code</title>
		<link>https://blog.xojo.com/2024/07/08/clean-coding-in-xojo-best-practices-for-writing-maintainable-code/</link>
		
		<dc:creator><![CDATA[Martin T.]]></dc:creator>
		<pubDate>Mon, 08 Jul 2024 15:00:00 +0000</pubDate>
				<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Beginner Tips]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13301</guid>

					<description><![CDATA[Clean coding is a vital aspect of software development that ensures code readability, maintainability, and scalability. In the context of Xojo, adhering to clean coding principles can significantly enhance the quality and longevity of your projects. In this blog post, we’ll explore key practices for clean coding in Xojo, including the advantages and disadvantages of these approaches, with detailed examples and explanations.]]></description>
										<content:encoded><![CDATA[
<p>Clean coding is a vital aspect of software development that ensures code readability, maintainability, and scalability. In the context of Xojo, adhering to clean coding principles can significantly enhance the quality and longevity of your projects. In this blog post, we’ll explore key practices for clean coding in Xojo, including the advantages and disadvantages of these approaches, with detailed examples and explanations.</p>



<h2 class="wp-block-heading">Why Clean Coding Matters</h2>



<p>Before diving into the specific practices, it’s important to understand why clean coding matters:</p>



<p>1. <strong>Readability</strong>: Clean code is easier to read and understand, which is crucial when multiple developers are involved or when you revisit your code after some time. This reduces the cognitive load on developers, making it easier to grasp the code’s functionality quickly.</p>



<p>2. <strong>Maintainability</strong>: Code that follows clean coding principles is easier to maintain and update, reducing the risk of introducing bugs. Maintainable code allows for efficient troubleshooting and quick implementation of changes or new features.</p>



<p>3. <strong>Scalability</strong>: Clean code can be more easily extended with new features, facilitating the growth of your application. Well-structured code makes it easier to see where and how new functionality can be added without disrupting existing features.</p>



<h2 class="wp-block-heading">Key Practices for Clean Coding in Xojo</h2>



<h3 class="wp-block-heading">1. Use Meaningful Names</h3>



<p>Using meaningful and descriptive names for variables, methods, and classes is one of the simplest yet most powerful practices in clean coding. Avoid abbreviations and opt for clear, self-explanatory names. This practice helps other developers understand your code without needing extensive documentation.</p>



<h4 class="wp-block-heading">Example:</h4>



<pre id="xojo" class="wp-block-code"><code>// Bad
Var n As Integer</code></pre>



<pre id="xojo" class="wp-block-code"><code>// Good
Var userCount As Integer</code></pre>



<p>In the good example, userCount clearly indicates the purpose of the variable, making the code easier to understand at a glance.</p>



<h3 class="wp-block-heading">2. Follow Consistent Coding and Naming Conventions</h3>



<p>Consistent naming conventions make your codebase uniform and easier to navigate. Establish and follow conventions for variables, methods, properties, and classes.</p>



<p>Read more detailed about Coding and Naming Conventions in the <a href="https://documentation.xojo.com/topics/code_management/coding_guidelines.html#topics-code-management-coding-guidelines-naming" target="_blank" rel="noreferrer noopener">Xojo Documentation</a></p>



<h3 class="wp-block-heading">3. Keep Methods Short and Focused</h3>



<p>Each method should perform a single, well-defined task. If a method is too long or performs multiple tasks, consider refactoring it into smaller, more focused methods. This makes the code more modular and easier to test and maintain.</p>



<h4 class="wp-block-heading">Example:</h4>



<pre class="wp-block-code"><code>// Bad
Sub ProcessUserData()
  ' Code to validate user input
  ' Code to save user data to the database
  ' Code to send a confirmation email
End Sub</code></pre>



<pre class="wp-block-code"><code>// Good
Sub ProcessUserData()
  ValidateUserInput
  SaveUserData
  SendConfirmationEmail
End Sub

Sub ValidateUserInput()
  ' Validation logic
End Sub

Sub SaveUserData()
  ' Database saving logic
End Sub

Sub SendConfirmationEmail()
  ' Email sending logic
End Sub</code></pre>



<p>By breaking down ProcessUserData into smaller methods, each method has a single responsibility, which makes the code easier to understand and maintain.</p>



<h3 class="wp-block-heading">4. Comment Wisely</h3>



<p>Comments should explain <em>why </em>something is done, not <em>what </em>is done. The code itself should be self-explanatory whenever possible. Over-commenting can clutter the code, while under-commenting can make it difficult to understand the rationale behind certain decisions.</p>



<h4 class="wp-block-heading">Example:</h4>



<pre class="wp-block-code"><code>// Bad
// Increment the user count by 1
userCount = userCount + 1</code></pre>



<pre class="wp-block-code"><code>// Good
// Increment the user count to keep track of active users
userCount = userCount + 1</code></pre>



<p>In the good example, the comment provides context for why the increment is necessary, which might not be immediately obvious from the code alone.</p>



<h3 class="wp-block-heading">5. Use Constants and Enumerations</h3>



<p>Avoid using magic numbers and strings. Instead, define constants and enumerations for values that have specific meanings. This makes your code more readable and easier to update.</p>



<h4 class="wp-block-heading">Example:</h4>



<pre class="wp-block-code"><code>// Bad
If statusCode = 200 Then
  ' Success logic
End If</code></pre>



<pre class="wp-block-code"><code>// Good
Const kHTTP_SUCCESS As Integer = 200
If statusCode = kHTTP_SUCCESS Then
  ' Success logic
End If</code></pre>



<p>Using kHTTP_SUCCESS instead of 200 makes the code more readable and the purpose of the value clearer.</p>



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



<p>Enumerations (enums) are a powerful way to represent a set of related constants. They make your code more readable and maintainable by grouping related values under a single type. This can be particularly useful for handling states, options, or categories in your application.</p>



<h4 class="wp-block-heading">Example:</h4>



<pre class="wp-block-code"><code>// Define an enumeration for user roles
Enum UserRole
  Admin
  Editor
  Viewer
End Enum

// Use the enumeration
Var currentUserRole As UserRole = UserRole.Admin

Select Case currentUserRole
Case UserRole.Admin
  ' Admin-specific logic
Case UserRole.Editor
  ' Editor-specific logic
Case UserRole.Viewer
  ' Viewer-specific logic
End Select</code></pre>



<p>In this example, the UserRole enum defines three possible roles: Admin, Editor, and Viewer. Using an enum makes the code more readable and ensures that only valid roles are assigned to currentUserRole.</p>



<h3 class="wp-block-heading">6. Handle Errors Gracefully</h3>



<p>Implement proper error handling to ensure your application can gracefully recover from unexpected conditions. Use Try&#8230;Catch blocks and meaningful error messages. This practice improves the robustness and user experience of your application.</p>



<h4 class="wp-block-heading">Example:</h4>



<pre class="wp-block-code"><code>Try
  ' Code that might throw an exception
Catch e As OutOfBoundsException
  // Log the error and inform the user
  System.DebugLog("Error: " + e.Message)
  MessageBox("An unexpected error occurred.")
End Try</code></pre>



<p>By catching exceptions and providing informative error messages, you help users understand what went wrong and how to proceed, while also aiding in debugging and logging.</p>



<h3 class="wp-block-heading">7. Refactor Regularly</h3>



<p>Refactoring is the process of improving the structure of your code without changing its functionality. Regular refactoring helps keep your code clean and manageable. It involves restructuring your code to improve its internal structure while maintaining its external behavior.</p>



<h4 class="wp-block-heading">Example:</h4>



<p>Before refactoring:</p>



<pre class="wp-block-code"><code>Sub DoEverything()
  ' Lots of code here
End Sub</code></pre>



<p>After refactoring:</p>



<pre class="wp-block-code"><code>Sub DoEverything()
  PerformTaskA
  PerformTaskB
  PerformTaskC
End Sub

Sub PerformTaskA()
  ' Task A code
End Sub

Sub PerformTaskB()
  ' Task B code
End Sub

Sub PerformTaskC()
  ' Task C code
End Sub</code></pre>



<p>By breaking down DoEverything into smaller tasks, the code becomes more modular and easier to maintain.</p>



<h2 class="wp-block-heading">Advantages and Disadvantages of Clean Coding </h2>



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



<ol class="wp-block-list">
<li><strong>Improved Readability:</strong> Clean code is easier for other developers and yourself to read and understand, which is crucial for effective collaboration and maintenance.</li>



<li><strong>Easier Maintenance:</strong> Maintenance tasks are simplified with well- structured and well-documented code, reducing the time and effort required to update and debug the code.</li>



<li><strong>Fewer Bugs:</strong> Following clean coding principles reduces the risk of bugs by promoting clarity and simplicity in the code.</li>



<li><strong>Better Collaboration:</strong> Teams can work more efficiently together when the code is understandable and consistent, reducing misunderstandings and errors.</li>



<li><strong>Scalability:</strong> It’s easier to integrate new features when the code is well- structured, as the modular design allows for more straightforward extensions.</li>
</ol>



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



<ol class="wp-block-list">
<li><strong>Time Investment:</strong> Clean coding requires more time and effort, especially in naming, documentation, and refactoring. This can slow down initial development but pays off in the long run.</li>



<li><strong>Initial Learning Curve:</strong> Developers unfamiliar with clean coding principles need time to learn and apply them, which can temporarily decrease productivity.</li>



<li><strong>Over-Perfection:</strong> There’s a risk of spending too much time perfecting the code, which can impact overall productivity and delay project timelines.</li>
</ol>



<p>Clean coding is not just a set of guidelines but a mindset that can significantly improve the quality of your software. By adopting clean coding practices in Xojo, you ensure that your codebase remains readable, maintainable, and scalable. Whether you are working on a small project or a large application, these principles will help you write better code and build more robust software.</p>



<p>Incorporating clean coding practices into your development workflow might require an initial investment of time and effort, but the benefits far outweigh the costs. Clean code leads to fewer bugs, easier maintenance, and a codebase that can grow and evolve with your project’s needs.</p>



<p>Happy coding!</p>



<p><em>Martin T. is a Xojo MVP and has been very involved in testing Android support.</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>Android Design Extensions 2.6 for Xojo 2024r2+</title>
		<link>https://blog.xojo.com/2024/07/02/android-design-extensions-2-6-for-xojo-2024r2/</link>
		
		<dc:creator><![CDATA[Martin T.]]></dc:creator>
		<pubDate>Tue, 02 Jul 2024 17:39:59 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[2024r2]]></category>
		<category><![CDATA[Android Design Extensions]]></category>
		<category><![CDATA[Mobile]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13292</guid>

					<description><![CDATA[Xojo 2024r2 has just been released and it’s time to update the Android Design Extension which is now available in version 2.6.]]></description>
										<content:encoded><![CDATA[
<p>Xojo 2024r2 has just been released and it’s time to update the Android Design Extension which is now available in version 2.6.</p>



<p>This small update runs exclusively for all Xojo 2024r2+ versions and now offers methods to access a few more system details, such as specific folders (MobileApplication.GetCacheDirXC, GetDataDirXC, GetFilesDirXC, etc.) or methods for checking screen properties like MobileApplication.IsScreenHdrXC, IsScreenRoundXC, ScreenHeightDpXC, or ScreenWidthDpXC.</p>



<figure class="wp-block-image size-large is-style-default"><img loading="lazy" decoding="async" width="996" height="1024" src="https://blog.xojo.com/wp-content/uploads/2024/07/7092BD62-5376-40EE-B3D8-3671D92BFA6F-996x1024.jpg" alt="" class="wp-image-13293" srcset="https://blog.xojo.com/wp-content/uploads/2024/07/7092BD62-5376-40EE-B3D8-3671D92BFA6F-996x1024.jpg 996w, https://blog.xojo.com/wp-content/uploads/2024/07/7092BD62-5376-40EE-B3D8-3671D92BFA6F-292x300.jpg 292w, https://blog.xojo.com/wp-content/uploads/2024/07/7092BD62-5376-40EE-B3D8-3671D92BFA6F-768x789.jpg 768w, https://blog.xojo.com/wp-content/uploads/2024/07/7092BD62-5376-40EE-B3D8-3671D92BFA6F-1494x1536.jpg 1494w, https://blog.xojo.com/wp-content/uploads/2024/07/7092BD62-5376-40EE-B3D8-3671D92BFA6F.jpg 1512w" sizes="auto, (max-width: 996px) 100vw, 996px" /></figure>



<p>Feel free to take a look at the developer repository, create feature requests, and provide feedback on extending this extension library.</p>



<p>I’m happy to receive any voluntary financial support for the work I’ve done so far, which you are welcome to <a href="https://www.paypal.com/paypalme/MTrippensee">share</a> here. You can download the project with many examples at <a href="https://github.com/XojoGermany/AndroidDesignExtensions">https://github.com/XojoGermany/AndroidDesignExtensions</a>.</p>



<p>Happy coding.</p>



<p><em>Martin T. is a Xojo MVP and has been very involved in testing Android support.</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>
	</channel>
</rss>
