<?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>Greg O&#8217;Lone &#8211; Xojo Programming Blog</title>
	<atom:link href="https://blog.xojo.com/author/greg/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, 15 Mar 2023 14:28:50 +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>On-Device iOS Debugging in Xojo</title>
		<link>https://blog.xojo.com/2022/04/05/on-device-ios-debugging-in-xojo/</link>
		
		<dc:creator><![CDATA[Greg O'Lone]]></dc:creator>
		<pubDate>Tue, 05 Apr 2022 13:30:00 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=10008</guid>

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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



<p>Don&#8217;t allow your device to go to sleep while waiting for the app to build and transfer or the app won&#8217;t be able to launch. You can increase the amount of time on the device by going to Settings &gt; Display &amp; Brightness and selecting a new Auto-Lock timeout. The options are 2, 5, 10 or 15 Minutes or Never.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The Crazy Exercise that is the Apple Signing Process</title>
		<link>https://blog.xojo.com/2021/10/26/the-crazy-exercise-that-is-the-apple-signing-process/</link>
		
		<dc:creator><![CDATA[Greg O'Lone]]></dc:creator>
		<pubDate>Tue, 26 Oct 2021 20:31:46 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[App Store]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Development]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=9512</guid>

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



<h2 class="wp-block-heading">It&#8217;s All About Operational Security</h2>



<p>Just so we&#8217;re all clear about why this process seems so complicated in the first place. What Apple is <em>trying</em> to do is to provide operational security, that is, separation of responsibilities so that on a big team, a single developer can&#8217;t just create and push out an app without anyone&#8217;s approval. While it adds a bit of complication for individual developers, it also means that as your product (and more importantly your team) grows, you&#8217;ll be able to deal with the changes gracefully.</p>



<h2 class="wp-block-heading">Seemingly Disparate Pieces</h2>



<p>There are six different parts that need to come together to successfully sign and deploy on iOS and macOS using the App Store (or Enterprise) which need to be configured properly for all this to work. If you&#8217;re just starting out, we suggest doing them in the order specified below to avoid having to go back and regenerate things later.</p>



<ol class="wp-block-list"><li><strong>The Application Identifier</strong> – This is the identifier which Apple requires be unique for every application installed on an Apple device. Typically in the form: <code>com.yourcompany.app-name</code> You will have the best luck with this process if you decide what this is going to be up front because it affects nearly everything going forward. You will define any capabilities which require entitlements in this section. Enabling things in this section may mean that you need to check a corresponding capability in your Xojo project. <em>Changing these capabilities will invalidate the Profiles below.</em></li><li><strong>Testing Devices</strong> – This is a list of devices which are <em>allowed</em> to be used for testing. They are specified using the Apple Developer portal using the device UDID. For an iOS device, this can be found either in Finder or in iTunes when the device is connected. I suggest using a meaningful name for the device if you have a lot of them.</li><li><strong>Certificates</strong> – Development and Distribution certificates are based on a public-private key-pair (like SSH) and are used for signing applications for testing and distribution respectively. See the Troubleshooting section below for more information.<ol><li><strong>Development Certificate</strong> – Each person who is writing code for you on your projects and needs to be able to build for a testing device will need one of these which was created in <em>your account</em>. This means that if you have a contractor working for you, you&#8217;ll need to add them to your account, set their Role to <strong>Developer</strong> and specify the apps that this developer is allowed to work on. One certificate per developer, and these need to be renewed each year.</li><li><strong>Distribution Certificate</strong> – The person, group or machine that is responsible for building for the App Store (or Enterprise) has a separate key-pair certificate. One certificate per <em>account</em>, and they need to be renewed each year.</li></ol></li><li><strong>Profiles</strong><ol><li><strong>Development Profile</strong> –&nbsp;This file is used to link up the who, what and where of developing an iOS or macOS app. When creating a development profile, give it a name appropriate to the group you are creating. It&#8217;s important to understand that because these profiles rely on the testing devices and on the individual developers that changes to those groups will require regenerating this profile. If your developers and/or testing devices change often, I suggest creating individual profiles for each developer. If not, you&#8217;ll have better luck with just one profile that contains all of your developers and devices. These need to be regenerated at least once per year.<ol><li>The Application Identifier &#8211; Select the Application Identifier for the app to which this profile applies.</li><li>Certificates – Select each of the developers that should be able to test this app on the selected devices.</li><li>Devices &#8211; Select each of the devices that the developers should be able to use in their testing.</li></ol></li><li><strong>Distribution Profile</strong> – This file links together the Application Identifier and the Distribution Certificate. Remember, there is typically one Distribution Certificate per account, so this allows you to grant or revoke the ability to distribute an app. These need to be regenerated at least once per year.</li></ol></li></ol>



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



<p>I&#8217;ve touched on this in places above, but I want this to be perfectly clear to anyone that is having trouble with certificates or profiles. The Development and Distribution profiles are highly dependent on the integrity of the Application Identifiers, Devices and Certificates. Any change to those items will mean that either or both of the profiles will need to be regenerated. Luckily (for the profiles anyway), it&#8217;s just a matter of editing the profile, adding or updating the data (if any) and clicking Save. Once that&#8217;s done, you can download the new profile, give it to anyone on your team that needs it (anyone whose certificates are contained therein) and just by double-clicking on the new file, it will be installed on your system by Xcode.</p>



<p>The table below shows the dependencies of the Development and Distribution profiles. <em>Any</em> changes to the indicated items (including expiration of a certificate) will render the profile Invalid and require that it be regenerated.</p>



<figure class="wp-block-table aligncenter is-style-regular"><table><thead><tr><td class="has-text-align-center" data-align="center"><strong>Profile Type</strong></td><td class="has-text-align-center" data-align="center"><strong>Application Identifier</strong></td><td class="has-text-align-center" data-align="center"><strong>Devices</strong></td><td class="has-text-align-center" data-align="center"><strong>Development Certificates</strong></td><td class="has-text-align-center" data-align="center"><strong>Distribution Certificate</strong></td></tr></thead><tbody><tr><td class="has-text-align-center" data-align="center">Development</td><td class="has-text-align-center" data-align="center">X</td><td class="has-text-align-center" data-align="center">X</td><td class="has-text-align-center" data-align="center">X</td><td class="has-text-align-center" data-align="center"></td></tr><tr><td class="has-text-align-center" data-align="center">Distribution</td><td class="has-text-align-center" data-align="center">X</td><td class="has-text-align-center" data-align="center"></td><td class="has-text-align-center" data-align="center"></td><td class="has-text-align-center" data-align="center">X</td></tr></tbody></table></figure>



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



<h3 class="wp-block-heading"><strong>Overall</strong></h3>



<p>If you&#8217;re getting errors during the build process, there&#8217;s usually some information about whether it is a Profile or a Certificate that is causing the trouble. The first thing you should do is go to your Apple Developer portal and under Certificates, Identifiers &amp; Profiles check to make sure that none of your Certificates have expired and that all of your Profiles for the current project are still Valid and have also not expired.</p>



<h3 class="wp-block-heading"><strong>Certificates</strong></h3>



<p>If for any reason you do not have both parts of the certificate you are trying to use, whether it&#8217;s the user&#8217;s Development certificate when building for your test devices or the Distribution certificate when trying to build for the App Store (or Enterprise), you&#8217;re not going to be successful. Both the public and the private key must be present on your machine for them to work.</p>



<p>It&#8217;s important to remember that these certificates can only be downloaded from Apple&#8217;s Developer portal <strong>once</strong>, after which downloading will only give you the public key. If you need to transfer a development certificate from one account to another (like if you replace your computer mid-year), you should find the certificate in your keychain, right-click on it and select <strong>Export</strong>. When the save dialog appears, make sure the file format is set to <strong>Personal Information Exchange (.p12)</strong>, and set a password for the key after you click <strong>Save</strong>. When you take the exported key to your new account/machine and double-click on it, the system will ask you for the password and you should be all set.</p>



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



<p>If you are a Xojo developer using an Enterprise developer account to distribute iOS applications within your own company without going through the App Store, we highly suggest checking out 2021r3 or later as some important changes have been made to make your builds more successful. </p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Remote Notifications in iOS</title>
		<link>https://blog.xojo.com/2021/07/22/remote-notifications-in-ios/</link>
		
		<dc:creator><![CDATA[Greg O'Lone]]></dc:creator>
		<pubDate>Thu, 22 Jul 2021 11:48:00 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Push Notifications]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=8803</guid>

					<description><![CDATA[Starting in Xojo 2021r2, users with a Xojo Cloud server can deploy web apps which can hook into the Apple Push Notification service directly with a user friendly Xojo API.]]></description>
										<content:encoded><![CDATA[
<p>Last fall with the release of Xojo 2020r2, we added the MobileNotifications framework for sending and handling local user notifications to your iOS apps based on time and/or location. This release also included the ability to receive and process <em>remote</em> notifications sent through the Apple Push Notification service (APNs), but as many as you have found, setting up and implementing the infrastructure to send remote notifications is often not a simple thing to do &#8230; until now.</p>



<p>Starting in Xojo 2021r2, users with a Xojo Cloud server can deploy web apps which can hook into the Apple Push Notification service directly with a user friendly Xojo API.</p>



<h2 class="wp-block-heading">Things You Will Need</h2>



<ol class="wp-block-list"><li>An iOS App that is set up to accept remote notifications.</li><li>An Apple Push Notification Certificate. You can get this from your Apple Developer control panel at <a rel="noreferrer noopener" href="https://developer.apple.com/account" target="_blank">https://developer.apple.com/account</a>, under Certificates, Identifiers &amp; Profiles. When doing so, you&#8217;ll want to make note of your Apple account identifier (in the upper right corner of the window) and the certificate Key ID located in the Key details. Both of these are 10 character alphanumeric codes at this time.</li><li>A <a href="https://www.xojo.com/cloud/">Xojo Cloud</a> server. Depending on your needs, even a small server will likely do.</li></ol>



<h2 class="wp-block-heading">Sending a Basic Remote Notification</h2>



<p>The first thing you&#8217;ll need to do is to add your APNs certificate to your Xojo Cloud server. This can be done by logging into the <a rel="noreferrer noopener" href="https://xccp.xojo.com" target="_blank">Xojo Cloud Control Panel</a> and clicking the Options Tab. There you will find a link that says <strong>Manage APNs Certificates</strong>. Clicking that will take you to a dialog which allows you to add and remove APNs certificates for a machine.</p>



<p>Sending remote notifications is a relatively simple process, but there&#8217;s a little infrastructure you&#8217;ll need. Typically the process goes something like this:</p>



<p>In your iOS application which will be receiving the remote notifications, you&#8217;ll need to request permission to show notifications (if the notifications will be visible to the user) and then <strong>register</strong> for remote notifications. When you do this, you&#8217;ll be provided with a hex-encoded globally unique token that identifies this device for your app. This identifier should be sent to your notification server along with any information that you may need to determine what type of user this is. This identifier may change from time to time so you should request it whenever your app is launched and send the new one to your server whenever it changes.</p>



<p>In your Xojo Cloud app, sending one or more notifications is relatively easy. You&#8217;ll need to create two objects:</p>



<ol class="wp-block-list"><li>An instance of XojoCloud.RemoteNotifications.DeliveryOptions which is where you&#8217;ll put the Application Identifier of the iOS application to which you are sending, the Apple account identifier and the certificate Key ID. This class also defines when the messages you are sending will expire, their priority and their type.</li><li>For each message being sent, you&#8217;ll need an instance of XojoCloud.RemoteNotifications.Message which defines the content of the message.</li></ol>



<p>Your code might look something like this:</p>



<pre class="wp-block-preformatted">// Set up Delivery Options
Var deliveryOpts As New XojoCloud.RemoteNotifications.DeliveryOptions(kAppID, kAPNSKeyID, kAppleTeamID)

// Set up a message
Var message As New XojoCloud.RemoteNotifications.Message
message.alertTitle = "Bethany's Bagels – Sale Today!"
message.alertBody = "Today Only – Buy one bagel, get one 50% off!"
message.badge = 1
message.soundName = "default"

// Assuming this RowSet contains all of the device tokens that you are sending to:
Var rs as RowSet = db.SelectSQL(kQueryToGetDeviceTokens)
While Not rs.AfterLastRow
  XojoCloud.RemoteNotifications.SendAppleNotification(message, deliveryOpts, rs.Column("token").StringValue)
  rs.MoveToNextRow
Wend
rs.close</pre>



<h2 class="wp-block-heading">Sending Notifications With APNs Feedback</h2>



<p>The second signature for SendAppleNotification allows you to get feedback from Apple&#8217;s Push Notification service, including situations like when a device token is no longer valid which can happen if the user turns off notifications or deletes your app from their device. Because sending messages is asynchronous, you will need to define a callback method and include a pointer to that method when calling SendAppleNotification, like this:</p>



<pre class="wp-block-preformatted">// Signature for the callback method
Sub CallbackMethod(MessageID as String, error as RuntimeException)</pre>



<p>When you pass the address of the callback method, SendAppleNotification will return a unique message identifier so that if the callback is called, you can identify <em>which</em> notification failed.</p>



<pre class="wp-block-preformatted">Var messageID as String
messageID = XojoCloud.RemoteNotifications.SendAppleNotification(message, deliveryOpts, rs.Column("token").StringValue, AddressOf CallbackMethod)</pre>



<p>The possible response codes are defined <a rel="noreferrer noopener" href="https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/handling_notification_responses_from_apns?language=objc" target="_blank">here</a>.</p>



<h2 class="wp-block-heading">Advanced Usage</h2>



<p>The Xojo Framework covers a large portion of the capabilities of the Apple Push Notification service, but Apple is adding new features all the time. In addition to the two methods described above, there are two methods which take a JSONItem instead of a XojoCloud.RemoteNotifications.Message object. Using this method you can define the message payload which uses features which have not yet been added to the Xojo framework.</p>



<p>Documentation of the JSON payload can be found in the Apple Developer documentation <a rel="noreferrer noopener" href="https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/generating_a_remote_notification?language=objc" target="_blank">here</a>.</p>



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



<p>Here&#8217;s a short video showing a remote notification being sent from a Xojo Cloud server in the datacenter in New York City to an iPhone at my house in North Carolina.</p>



<figure class="wp-block-video"><video controls src="https://blog.xojo.com/wp-content/uploads/2021/07/notification-test-project.mp4"></video></figure>
]]></content:encoded>
					
		
		<enclosure url="https://blog.xojo.com/wp-content/uploads/2021/07/notification-test-project.mp4" length="4989969" type="video/mp4" />

			</item>
		<item>
		<title>Enumeration Enhancements</title>
		<link>https://blog.xojo.com/2021/07/22/enumeration-enhancements/</link>
		
		<dc:creator><![CDATA[Greg O'Lone]]></dc:creator>
		<pubDate>Thu, 22 Jul 2021 11:48:00 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Binary]]></category>
		<category><![CDATA[Enumeration]]></category>
		<category><![CDATA[IDE]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=8855</guid>

					<description><![CDATA[Xojo 2021r2 introduces a couple of enhancements to Enumerations in Xojo. The enumeration editor now shows a preview of what the value will be so there's no more guessing or counting. In addition, we've added a new Binary option which allows you to automatically create sets that aren't mutually exclusive. ]]></description>
										<content:encoded><![CDATA[
<p>Xojo 2021r2 introduces a couple of enhancements to <a href="https://documentation.xojo.com/getting_started/using_the_xojo_language/enumerations.html">enumerations</a> in Xojo. The enumeration editor now shows a preview of what the value will be so there&#8217;s no more guessing or counting.</p>



<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><img decoding="async" src="https://blog.xojo.com/wp-content/uploads/2021/07/image-1.png" alt="" class="wp-image-8857" width="156" height="240" srcset="https://blog.xojo.com/wp-content/uploads/2021/07/image-1.png 276w, https://blog.xojo.com/wp-content/uploads/2021/07/image-1-195x300.png 195w" sizes="(max-width: 156px) 100vw, 156px" /><figcaption>Example of Enumeration with default values showing</figcaption></figure></div>



<p>In addition, we&#8217;ve added a new Binary option which allows you to automatically create sets that aren&#8217;t mutually exclusive. That is, the values of the elements are automatically powers of two and can have binary operations applied to them:</p>



<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><img decoding="async" src="https://blog.xojo.com/wp-content/uploads/2021/07/image-3.png" alt="" class="wp-image-8859" width="162" height="236" srcset="https://blog.xojo.com/wp-content/uploads/2021/07/image-3.png 284w, https://blog.xojo.com/wp-content/uploads/2021/07/image-3-206x300.png 206w" sizes="(max-width: 162px) 100vw, 162px" /><figcaption>Example of Binary Enumeration default values</figcaption></figure></div>



<p>This new feature comes with the requirement that they be placed inside a Module because they&#8217;re rendered into your project as a Class. The reason for this is that these classes automatically have some helper methods on them to make working with the binary data easier.</p>



<ul class="wp-block-list"><li>An Operator_Convert which takes an Integer:<br><code>Var x as MyEnum = 3 // MyEnum.George, MyEnum.John</code><br></li><li>&#8230;as well as one that returns an integer:<br><code>Var y as Integer = MyEnum.George // y = 2</code><br></li><li>Automatic conversion to and from Integer:<br><code>Var x as Integer = MyEnum.Ringo // x = 4</code><br></li><li>Binary operations And, Or and Xor:<br><code>Var x as MyEnum = MyEnum.Paul Or MyEnum.Mary // x has a value of 40</code><br></li><li>Equality operations so you can compare the internal value of one instance to another:<br><code>Var x as MyEnum = MyEnum.Paul<br>Var y as MyEnum = MyEnum.Ringo<br>If x = y Then</code><br></li><li>Contains helper method:<br><code>If x.Contains(MyEnum.Peter) Then</code><br></li><li>A Read-Only Value property so you can see the internal value in the debugger</li></ul>



<p>Just like regular Enumerations, the editor also allows you to explicitly specify the value of an element:</p>



<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><img loading="lazy" decoding="async" src="https://blog.xojo.com/wp-content/uploads/2021/07/image-5.png" alt="" class="wp-image-8862" width="157" height="226" srcset="https://blog.xojo.com/wp-content/uploads/2021/07/image-5.png 338w, https://blog.xojo.com/wp-content/uploads/2021/07/image-5-209x300.png 209w" sizes="auto, (max-width: 157px) 100vw, 157px" /></figure></div>



<p>This is so instead of having to write: <br><code>Var x as MyEnum = MyEnum.George Or MyEnum.John Or MyEnum.Ringo Or MyEnum.Paul</code><br><br>You can simply write:<br><code>Var x as MyEnum = MyEnum.TheBeatles</code><br><br>We hope that you&#8217;ll enjoy this feature as much as we do!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Auto-Deleting Temporary Files</title>
		<link>https://blog.xojo.com/2021/03/11/auto-deleting-temporary-files/</link>
		
		<dc:creator><![CDATA[Greg O'Lone]]></dc:creator>
		<pubDate>Thu, 11 Mar 2021 10:00:00 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[FolderItem]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=7212</guid>

					<description><![CDATA[Did you know that you can make temporary FolderItems that automatically delete when they go out of scope? This technique makes it fairly easy. ]]></description>
										<content:encoded><![CDATA[
<p>Did you know that you can make temporary FolderItems that automatically delete when they go out of scope? This technique makes it fairly easy. So let&#8217;s get to it.</p>



<ol class="wp-block-list"><li>Add a class to your project and name it <strong>TempFolderItem</strong>.</li><li>Add a <strong>Private</strong> property to the class named <strong>mFolderItem</strong> with a type of <strong>FolderItem</strong>.</li><li>Add a Method to the class named <strong>Constructor</strong>.</li><li>In the method, add the following code:<br><code>mFolderItem = FolderItem.TemporaryFile()</code></li><li>Add a Method to the class named <strong>Destructor</strong>.</li><li>In the method, add the following code:<br><code>mFolderItem.Delete</code></li><li>Add a new Method to the class named <strong>Operator_Convert</strong> with a return type of <strong>FolderItem</strong>.</li><li>In the method, add the following code:<br><code>Return mFolderItem</code></li></ol>



<p>That&#8217;s it! Now when you need a temporary file, create one of these objects like this:</p>



<p><code>Var myTempFile as New TempFolderItem</code></p>



<p>The Operator_Convert method makes it so you can use this object in any place where a FolderItem is expected and as soon as myTempFile goes out of scope, *POOF* the file disappears (assuming of course that no other process has locked the file).</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Backwards SQLite Backups</title>
		<link>https://blog.xojo.com/2021/03/09/backwards-sqlite-backups/</link>
		
		<dc:creator><![CDATA[Greg O'Lone]]></dc:creator>
		<pubDate>Tue, 09 Mar 2021 16:54:16 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Backups]]></category>
		<category><![CDATA[SQLite]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=8121</guid>

					<description><![CDATA[If you use SQLite databases in your apps you may or may not be aware of the Backup method which allows you to quickly and asynchronously create a backup of an existing connected database. This is especially great if you have an in-memory database and you want to store that data on disk for later reference. ]]></description>
										<content:encoded><![CDATA[
<p>If you use SQLite databases in your apps you may or may not be aware of the Backup method which allows you to quickly and asynchronously create a backup of an existing connected database. This is especially great if you have an in-memory database and you want to store that data on disk for later reference. I am using the simpler synchronous calls for this example:</p>



<p><code>memoryDB.Backup(fileDB, Nil, -1)&nbsp;</code></p>



<p>Something that&#8217;s often overlooked is that you can use the Backup method to go the other way&#8230; that is, it can be used to load a disk-based database <em>back into memory</em> by simply swapping the parameters:</p>



<pre class="wp-block-preformatted">// Connect to the database file on disk
Var fileDB as New SQLiteDatabase
fileDB.DatabaseFile = SpecialFolder.Resources.Child("template.db")
fileDB.Connect

// Create the database in memory
Var memoryDB as New SQLiteDatabase
memoryDB.Connect

// "Backup" the file database into memory
fileDB.Backup(memoryDB, Nil, -1)

// Close the file database
fileDB.Close</pre>



<p>And voila! You&#8217;ve restored the database back into memory!</p>



<p>For more information about this command, please see <a rel="noreferrer noopener" href="https://documentation.xojo.com/api/databases/sqlitedatabase.html#sqlitedatabase-backup" target="_blank">SQLiteDatabase.Backup on https://documentation.xojo.com</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Best Practices for Working with a Xojo Cloud Server</title>
		<link>https://blog.xojo.com/2020/06/29/best-practices-for-working-with-a-xojo-cloud-server/</link>
		
		<dc:creator><![CDATA[Greg O'Lone]]></dc:creator>
		<pubDate>Mon, 29 Jun 2020 19:52:26 +0000</pubDate>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=6062</guid>

					<description><![CDATA[Since I&#8217;ve been asked about this by new and current Xojo Cloud users, let&#8217;s cover some basic best practices for everyone. Don&#8217;t ping or port&#8230;]]></description>
										<content:encoded><![CDATA[<p>Since I&#8217;ve been asked about this by new and current Xojo Cloud users, let&#8217;s cover some basic best practices for everyone.</p>
<ol>
<li><strong>Don&#8217;t ping or port scan the server. </strong>Our adaptive firewall is designed to look for behavior which looks like the type of traffic that comes just before an attack. Pings and Port Scans will get you blocked from your own server for a period of time. If your server isn&#8217;t accessible, head on over to https://downforeveryoneorjustme.com and type in your server&#8217;s IP address. That will help us understand if the problem is on your end or ours. Restarting or Deploying to your server will clear this up for you.</li>
<li><strong>Stats only work after you have deployed. </strong>Displaying stats in the IDE can be processor intensive for your Xojo Cloud server, especially if there is more than one user requesting them. To prevent this, statistics are only available to users who have been specifically whitelisted on the firewall and the easiest way to do that is to deploy, even if it&#8217;s a simple empty app.</li>
<li><strong>Databases require memory and processor cores.</strong> When adding a database to your Xojo Cloud server, it&#8217;s important to remember that they do require memory and CPU processor cores to run. For the best experience, we recommend that users upgrade to a Xojo Cloud server with at least 4 vCPUs.</li>
</ol>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Improved Layout Position Locking</title>
		<link>https://blog.xojo.com/2019/10/09/improved-layout-position-locking/</link>
		
		<dc:creator><![CDATA[Greg O'Lone]]></dc:creator>
		<pubDate>Wed, 09 Oct 2019 11:30:56 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[2019r2]]></category>
		<category><![CDATA[Layout Editor]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=6051</guid>

					<description><![CDATA[Among the many IDE improvements in 2019r2 we've made some improvements in how the Control Layout Locks work so even if a control is locked, it'll still obey the left/top/right/bottom alignment locks. We are taking some hints from the way many graphic design programs approach this and we think it'll be a big improvement to the way controls are organized on Windows and Containers. ]]></description>
										<content:encoded><![CDATA[<p>Among the many IDE improvements in 2019r2 we&#8217;ve made some improvements in how the Control Layout Locks work so even if a control is locked, it&#8217;ll still obey the left/top/right/bottom alignment locks. We are taking some hints from the way many graphic design programs approach this and we think it&#8217;ll be a big improvement to the way controls are organized on Windows and Containers.&nbsp;</p>
<h3>Positioning</h3>
<p>First of all, the primary function of Position Locking in the IDE is to prevent accidentally moving controls that you&#8217;ve already placed on a Window or Container. For users with very complex layouts and layers of overlapping controls, this feature is a must.</p>
<p>In previous versions of the IDE when you lock a control&#8217;s layout position, it stays in that position no matter what, and while that <em>sounds</em> like the desired result, it does have some not-so-desirable side effects, the least of which is that the control no longer obeys runtime control locking. If you follow these steps in 2019r1.1, you get a very strange result:</p>
<ol>
<li>Create a new Desktop Project.</li>
<li>In Window1, drag a Canvas control to the lower-right corner of the window.</li>
<li>Set the control locking in the inspector so that only the right and bottom sides are locked.</li>
<li>Right-click the control and select &#8220;Lock Position&#8221;</li>
<li>Resize the Window by dragging the lower-right handle</li>
</ol>
<p>In 2019r1.1 and below, the Canvas acts like it&#8217;s locked on the top-left corner and stays at the same x and y position as when you locked it. If you do these same steps in 2019r2, the control now follows it&#8217;s runtime locking rules and stays with the lower-right corner of the Window.&nbsp;</p>
<h3>Alignment</h3>
<p>The second issue we had was that Position Locking did not affect the alignment tools. Previously, if you selected one or more controls whose positions were locked, the alignment toolbar buttons were always enabled, but clicking them didn&#8217;t affect all locked controls. Instead, the IDE would figure out the outer bounds of all selected controls and move the unlocked controls to align with this boundary. This leads to unexpected results if one or more locked controls are selected because they don&#8217;t move.&nbsp;</p>
<p>Starting in 2019r2, the rules for alignment have changed somewhat.</p>
<ul>
<li>The alignment controls are now only enabled if you have <em>at most</em> one locked control selected.&nbsp;</li>
<li>If no locked controls are selected, the IDE will align controls using the outer boundary of all selected controls as a guide, just like it did before.</li>
<li>If a locked control <em>is</em> selected, the controls will be aligned <em>to that control</em>.</li>
</ul>


<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Xojo IDE Improvements: Speed, Tab Management, Menus &#038; More</title>
		<link>https://blog.xojo.com/2019/10/09/xojo-ide-improvements-speed-tab-management-menus-more/</link>
		
		<dc:creator><![CDATA[Greg O'Lone]]></dc:creator>
		<pubDate>Wed, 09 Oct 2019 10:25:41 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[2019r2]]></category>
		<category><![CDATA[DarkMode]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo IDE]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=5837</guid>

					<description><![CDATA[Keeping the IDE simple to use for new users is one of our core tenets, but that doesn't mean that we can't add some much needed capabilities for our long-term users. ]]></description>
										<content:encoded><![CDATA[
<p>Keeping the IDE simple to use for new users is one of our core tenets, but that doesn&#8217;t mean that we can&#8217;t add some much needed capabilities for our long-term users. This cycle we&#8217;ve added some new exciting capabilities for managing medium to large-size projects and made some overall improvements that make the Xojo IDE a lot more satisfying to use. To be honest, the more of these things we added the less I wanted to go back to using older versions of the IDE.</p>



<p><strong>Improved Overall Speed</strong><br>One of the most obvious areas that hurt people with large projects is the speed of the IDE itself. We worked on a number of pain points to improve the overall IDE experience.  Specifically, we were looking for things which by themselves were not too bad, but in a cumulative effect they could take large chunks out of your day.</p>



<p>One such area was in saving text projects. Now you wouldn&#8217;t think that there was much room for improvement here, since it&#8217;s just File I/O right? We found an optimization point in the way we save Bookmarks and Breakpoints, which in the IDE project represents a huge savings when making lots of changes. In our case, we went from 30 seconds down to 1, and for someone who insists on saving before every run, it makes a huge difference.</p>



<p>We also optimized drawing in the Navigator, and that change resulted in huge overall speed increases in many parts of the IDE, from selecting large number of items in the Navigator itself, making changes to multiple items, to even just typing code in the code editor.</p>



<p><strong>Improved Tab Management</strong><br>Tabs have been broken in one way or another for a long time. They finally got some TLC this cycle and we think you&#8217;re going to be much happier with the way they work now. We&#8217;ve rewritten the logic surrounding how tabs are chosen when you take an action which results in a new location request and made the behavior consistent, no matter where that request comes from. Whether that&#8217;s a Go To Location request or a search or clicking on an error result. The rules are applied in the following order:</p>



<ol class="wp-block-list"><li>If there is at least one <em>locked</em> <em>tab</em> which matches the Go To target, the first one will be used (left to right).</li><li>If there is at least one <em>unlocked</em> <em>tab</em> which matches the Go To target, the first one will be replaced.</li><li>If the <em>current</em> tab is unlocked, it will be replaced with the new location.</li><li>If there are <em>any</em> unlocked tabs, the first one will be replaced.</li><li>If none of the above conditions are met, a new tab will be created for the target location.</li></ol>



<p class="has-text-color has-regular-font-size has-vivid-red-color">NOTE: Debugger Tabs are <em>never</em> eligible as a Go To target. This may seem obvious, but it wasn&#8217;t always true before. Now it is. Debugger tabs are also locked by default and cannot be unlocked.</p>



<p>The only exceptions to these rules are the Open In New Tab rules. That is, if you right-click on an item and select Open In New Tab or you double-click on an item with the &#8220;Double-click opens item in new tab&#8221; preference set, they will always open a new tab for you.</p>



<p>Once you start using the new logic, I think you&#8217;ll agree that it&#8217;s much more intuitive and you won&#8217;t feel like the IDE is constantly switching contexts on you. Personally I find that I&#8217;m using <em>fewer</em> tabs than in previous versions because I&#8217;m more confident that the objects I opened will still be there when I get back.</p>



<p><strong>MacOS Dark Mode Layout Editor Toggling</strong><br>On macOS 10.14 and above we&#8217;ve added a new toolbar button which allows you to quickly switch the Window you are editing between light and dark mode. No more switching your entire OS just to see how your app will look in the other mode.</p>



<p><strong>Navigator Contextual Menu</strong><br>We&#8217;ve done some cleanup work here to make it more obvious what you can and can&#8217;t do with objects in the Navigator. Gone are all of the disabled items that were not &#8220;in-context&#8221; for the currently selected item because, well duh, they&#8217;re not &#8220;in-context&#8221;. We&#8217;ve also enhanced the Edit Superclass and Edit Subclass menus. Edit Superclass now shows the entire superclass hierarchy, including things that you can&#8217;t edit (disabled of course) so you can track down common parentage. The Edit Subclass menu has been alphabetized so you don&#8217;t have to read the entire list just to find all of the items that begin with &#8220;c&#8221;.</p>



<p><strong>Code Editor Contextual Menu</strong><br>This menu has also gotten some love and attention. First of all, the menu has been reorganized so that the menu groups are based on the context of the thing that you&#8217;ve clicked on and the object where the code itself lives.</p>



<p>Group 1: Just like previous versions of the IDE, Cut, Copy, Paste, Delete and Select All are still at the top of the menu. They&#8217;re a common thing for mouse oriented users and we don&#8217;t want to hurt that functionality.</p>



<p>Group 2: The next group is for things that are for accessing or modifying the object that you&#8217;re currently editing. This is where you&#8217;ll find the Switch To menu for directly accessing the other code items within the current item. </p>



<p>We&#8217;ve also added two new submenus to this section that are specifically for copying the event and delegate signatures of <em>the thing you&#8217;ve clicked</em> <em>on</em>. For example if your code refers to a <strong>URLConnection</strong> object, you can now right-click on URLConnection and select <strong>Add Method</strong> &gt; <strong>From Event</strong> &gt; <strong>ContentReceived</strong> and the IDE will automatically add a method to the current object with the same signature including the object itself for use with AddHandler! In this case, you&#8217;d end up with a method that looks like this:</p>



<p><br><code>URLConnection_ContentReceived(obj As URLConnection, URL As String, HTTPStatus As Integer, content As String)</code></p>



<p>Then you could type something like:</p>



<p><br><code>AddHandler h.ContentReceived, AddressOf URLConnection_ContentReceived</code></p>



<p>Delegates work the same way, albeit without including the object reference in the method signature. No more flipping back and forth between your current code and the target object or Language Reference to copy the signatures!</p>



<p>Group 3: If it exists, this group is for things that are specific to the object or instance of the object that you clicked on in the code editor. This is where you&#8217;ll see the &#8220;Find&#8221; and &#8220;Go To&#8221; menu items for finding other uses of or going to the definition of an item, respectively. </p>



<p>Group 4: This group is for selection and code-specific tools including the <strong>Insert Color</strong> command, <strong>Standardize Format</strong> and the <strong>Wrap In</strong> menus for wrapping the current selection if an #If #EndIf or While/Wend block. This section also sports the menu for converting the current selection to a Constant or a Method.</p>



<p>Group 5: From here you can toggle Breakpoints and Bookmarks</p>



<p>Group 6: Help and Language Reference access.</p>



<p>For more information about the changes in 2019r2, read the full <a href="http://documentation.xojo.com/Resources:2019r2_Release_Notes">Release Notes</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Custom Folder Icons with macOS Uniform Type Identifiers</title>
		<link>https://blog.xojo.com/2019/07/30/custom-folder-icons-with-macos-uniform-type-identifiers/</link>
		
		<dc:creator><![CDATA[Greg O'Lone]]></dc:creator>
		<pubDate>Tue, 30 Jul 2019 10:00:18 +0000</pubDate>
				<category><![CDATA[Learning]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[macOS]]></category>
		<category><![CDATA[UTI]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=5893</guid>

					<description><![CDATA[Did you know that you have a custom icon on folders created from your Xojo app? Read on to learn more!

Uniform Type Identifiers (UTIs) are one of the many often misunderstood parts of building native macOS apps. While they're not just for specifying file types, that's what I'm going to focus on today.]]></description>
										<content:encoded><![CDATA[<p>Did you know that you have a custom icon on folders created from your Xojo app? Read on to learn more!</p>
<p>Uniform Type Identifiers (UTIs) are one of the many often misunderstood parts of building native macOS apps. While they&#8217;re not just for specifying file types, that&#8217;s what I&#8217;m going to focus on today. First, a little background:</p>
<p>Uniform Type Identifiers are the successor to Apple&#8217;s Creator and Type codes that were used in MacOS Classic 15+ years ago. Back then, every mac application had a creator code (Four characters) which had to be unique and therefore registered with Apple for use in an app. Then, each file type that you wanted to create <em>also</em> needed a unique code. Common types were TEXT for text files, APPL for applications and RTFd for RTF documents. This was their attempt to keep from having file extensions and while it &#8220;worked&#8221; there were some severe limitations.</p>
<p>When MacOS X appeared on the scene, file extensions became a necessity again what with their BSD Unix underpinnings and when 10.6 was released, Apple revisited their position on exposing users to extensions again. (Don&#8217;t get me wrong, macOS does an excellent job of hiding extensions from users that don&#8217;t need to see them and exposing them to users who do. As an old-school user, I&#8217;m grateful for that.) This meant that they had an opportunity to update their antiquated system for application and file type association. </p>
<p>At first glance, wrapping your head around UTIs may seem a little daunting, but let&#8217;s break it down for you:</p>
<ol>
<li>First, your application needs a valid Bundle Identifier. This setting is found in the macOS build target settings and its value is in reverse domain name format. While it&#8217;s not required, I suggest you use your personal or company domain name to form this identifier. If your domain was example.com, the bundle identifier would look like com.example.myappname.</li>
<li>Next, you&#8217;ll need to add a special kind of File Type to your app. Add a &#8220;File Type Set&#8221; to your project and add a new type by clicking the + button at the top of the editor.
<ol>
<li>Give your type a name like &#8220;FolderWithIcon&#8221;.</li>
<li>Assign a UTI Identifier. This must start with the same reverse name that you used for your bundle identifier when making file types for something that your app creates. For example: com.example.myfolder. This value must be unique within your app.</li>
<li>Add &#8220;public.folder&#8221; to the Conforms To field. This value represents the other type(s) of files that your type is associated with. For more information see <a href="https://developer.apple.com/library/archive/documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html">Apple&#8217;s list of public identifiers</a>.</li>
<li>Set the Extensions field to &#8220;.myfolder&#8221;. This value must be unique within your app.</li>
<li>Set UTI Type to Exported</li>
<li>Add a unique folder icon to your file type.</li>
</ol>
</li>
<li>In places where you want to have these custom folders all you have to do now is add the extension and then hide the extension from the user:
<pre>Dim f As FolderItem = SpecialFolder.Desktop.Child("Test.myfolder")<br />f.CreateAsFolder<br />f.ExtensionVisible = False</pre>
</li>
<li><em>Build</em> your app (running won&#8217;t always work). Note: macOS reads these specs right from the latest version of your app and caches them, so if you need to update your icon you&#8217;ll need to at least increase your app&#8217;s non-release version number.</li>
</ol>
<p>That&#8217;s all there is to it! From now on, when you create a folder in your app, it&#8217;ll get your snazzy new icon!</p>


<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Using IDE and System Version Specific Code</title>
		<link>https://blog.xojo.com/2019/07/29/using-ide-and-system-version-specific-code/</link>
		
		<dc:creator><![CDATA[Greg O'Lone]]></dc:creator>
		<pubDate>Mon, 29 Jul 2019 06:06:20 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[Xojo IDE]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=5940</guid>

					<description><![CDATA[Ever wonder how to conditionally implement newer features in your code while keeping the ability to use older versions of Xojo at the same time?&#8230;]]></description>
										<content:encoded><![CDATA[<p>Ever wonder how to conditionally implement newer features in your code while keeping the ability to use older versions of Xojo at the same time? It&#8217;s really easy to do, I&#8217;ll show you how.</p>


<p>There&#8217;s an advanced feature in Xojo called Compiler Directives which allows you to direct the compiler to conditionally compile a block of code based on a boolean comparison. For instance, if you wanted to temporarily disable a block of code (as opposed to commenting it out) you could wrap your code like this:</p>



<pre class="wp-block-preformatted">#If False
  // Code that you don't want to compile
#EndIf</pre>



<p>You can also use constants with the #if directive, so if you created a module called &#8220;Switches&#8221; and it contained a Public or Protected constant named &#8220;EnableDeepLearning&#8221; with a value of True or False you could write code like this:</p>



<pre class="wp-block-preformatted">#If Switches.EnableDeepLearning
  // Code for your deep learning feature goes here
  // This code will only be <em>included</em> in your app if EnableNewFeature is set to True
#EndIf</pre>



<p>There are also some built-in constants for you to use. For instance, there are two constants that tell you which version of the IDE is running, one is a Double, the other is a String. Here&#8217;s an example which allows you to use the new Dark Mode capability depending on whether you&#8217;re running 2018r3 or something earlier:</p>



<pre class="wp-block-preformatted">#If XojoVersion &lt; 2018.03
  Var myTextColor As Color = &amp;c000000
#Else
  Var myTextColor As Color = &amp;c1C1C1C
  If IsDarkMode Then
    myTextColor = &amp;cFEFEFE
  End If
#EndIf</pre>



<p>There are also build-in constants per platform and processor type:</p>



<pre class="wp-block-preformatted">#If TargetMacOS
  // macOS Specific Code
#ElseIf TargetWindows
  // Windows Specific Code
#ElseIf TargetLinux
  // Linux Specific Code
#ElseIf TargetIOS
  // iOS Specific Code
#EndIf

#If Target32Bit
  // Code for 32-Bit Processors
#ElseIf Target64Bit
  // Code for 64-Bit Processors
#ElseIf TargetARM
  // Code for ARM Processors
#EndIf</pre>



<p>For more information on Compiler Directives, see <a href="https://documentation.xojo.com/%23If…%23Endif">https://documentation.xojo.com/＃If…＃Endif</a></p>



<p>In addition to code for specific platforms, sometimes you need to know the specific version of the OS that the user is running. In 2019r3 we added the System.Version method specifically for this purpose:</p>



<pre class="wp-block-preformatted">#If TargetMacOS
  If System.Version = "10.15" Then
    // Code that works exclusively on 10.15
  ElseIf System.Version &gt;= "10.15.1"
    // Code that only works on 10.15.1 and above
  End If
#EndIf</pre>



<p>If you&#8217;re working with Windows, keep in mind that System.Version returns NT System Versions, so you&#8217;ll need to compare to these values instead:</p>



<ul class="wp-block-list"><li>Windows 10 = NT 10</li><li>Windows 8.1 = NT 6.3</li><li>Windows 8 = NT 6.2</li><li>Windows 7 = NT 6.1</li><li>Windows Vista = NT 6.0</li></ul>



<p>For more information about System.Version, See <a href="http://documentation.xojo.com/api/os/system.html#system-version" target="_blank" rel="noreferrer noopener">http://documentation.xojo.com/api/os/system.html#system-version</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Automating Application Loader for iOS</title>
		<link>https://blog.xojo.com/2019/03/29/automating-application-loader-for-ios/</link>
		
		<dc:creator><![CDATA[Greg O'Lone]]></dc:creator>
		<pubDate>Fri, 29 Mar 2019 10:00:41 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=5595</guid>

					<description><![CDATA[Did you know that Apple provides a command-line interface for the Application Loader? With a Post-Build IDE build script, you can automatically submit your iOS apps to the iTunesConnect for processing!]]></description>
										<content:encoded><![CDATA[<p>Did you know that Apple provides a command-line interface for the Application Loader? With a Post-Build IDE build script, you can automatically submit your iOS apps to the iTunesConnect for processing!</p>
<p><span id="more-5595"></span></p>
<p>The command is:</p>
<p><code>xcrun altool -u [username] -p [password] -f [path to bundle] -t ios</code></p>
<p>In a Xojo build script you can even show a prompt asking if you want to submit it. Just make a post-build script and paste in this code.</p>
<pre>dim btn As String = ShowDialog("Do you want to upload this build to Apple?", "", "Yes", "No", "")
if btn = "No" Then
  Return
end if

// Find the path to the .ipa file that was just built
Dim result as String = DoShellCommand("cd " + CurrentBuildLocation + " &amp;&amp; ls -1 *.ipa")
Dim IPAPath As String = CurrentBuildLocation + "/" + ReplaceAll(trim(result), " ", "\ ")

// Make the command
Dim username as string = "Your iTunesConnect Username"
dim password as string = "Your iTunesConnect Password"
Dim cmd As String = "xcrun altool -u -p -f -t ios"
cmd = Replace(cmd, "", IPAPath)
cmd = Replace(cmd, "", username)
cmd = Replace(cmd, "", password)

// Validate the package (with a 2 minute timeout)
// If an error occurs, show the error and abort
Dim errorcode As Integer
result = DoShellCommand(cmd + " -v", 120, errorcode)
If errorcode &lt;&gt; 0 Then
  print result
  Return
End If

// Upload the package (with a 15 minute timeout)
// If an error occurs, show the error and abort
result = DoShellCommand(cmd + " --upload-app", 900, errorcode)
If errorcode &lt;&gt; 0 Then
  print result
  Return
End If

Print "Upload Complete."</pre>
<p>For more information about this powerful command-line tool, open a Terminal and type:</p>
<p><code>xcrun altool -h</code></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Loading 3rd Party Frameworks in Xojo iOS</title>
		<link>https://blog.xojo.com/2019/01/17/loading-3rd-party-frameworks-in-xojo-ios/</link>
		
		<dc:creator><![CDATA[Greg O'Lone]]></dc:creator>
		<pubDate>Thu, 17 Jan 2019 10:00:57 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Declares]]></category>
		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Third Party]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=5319</guid>

					<description><![CDATA[If you're familiar with Declares in iOS, loading a 3rd Party framework requires just a couple of extra lines of code in Xojo and a CopyFilesStep. In this example build and run SimulatorStatusMagic in the Simulator in order to always show a default date and time values when you do a debug run. ]]></description>
										<content:encoded><![CDATA[<p>Did you know that it&#8217;s possible to load and use 3rd Party Frameworks in your Xojo iOS projects? There&#8217;s quite a number of good projects out there, many of which are on sites like <a href="https://github.com">GitHub</a> and freely available for use in your projects. If you&#8217;re familiar with Declares in iOS, loading a 3rd Party framework requires just a couple of extra lines of code and a CopyFilesStep.</p>
<p>Last year at XDC 2018, <a href="https://github.com/jkleroy">Jérémie Leroy</a> talked about making sure your screenshots mimicked the Apple method so that the date was always Jun 9th, the time was always 9:41 AM, the battery always shows as full and the WiFi strength always shows full. It got me thinking that it might be handy to be able to make the simulator <em>always</em> show those values when you do a debug run so that you don&#8217;t need to think about it when you are ready to start taking screenshots and movies of your app. One way to do that is to build &amp; run project like <a href="https://github.com/shinydevelopment/SimulatorStatusMagic">SimulatorStatusMagic</a> on the simulator before running your project, but it would be more useful if it was <em>automatic</em>.</p>
<p><span id="more-5319"></span></p>
<h3>Build the Framework</h3>
<p>First of all, go to the SimulatorStatusMagic Github page and clone or download the project. Just like Xojo iOS development, you&#8217;ll need <a href="https://developer.apple.com/xcode/">Xcode</a> for this step. After you&#8217;ve downloaded the project, double-click on the SimulatorStatusMagic.xcodeproj file to open it in Xcode. When the project opens, change the target to SimulatorStatusMagiciOS and build it by either pressing CMD-B or pressing the Play button. Once the build is complete, go to the project navigator, scroll down to the bottom and open the Products group to reveal the built parts of this project. The only item we&#8217;re concerned with here is the file named SimulatorStatusMagiciOS.framework. Right-click on it and select Show in Finder.</p>
<h3>Build the Project</h3>
<p>Let&#8217;s start off by making sure the framework will be available to your project at runtime.</p>
<ol>
<li>Create a folder on your drive named SimulatorStatusMagic and copy the framework file that you just built into it.</li>
<li>Launch Xojo and create a new iOS project. Save the project into that folder as well.</li>
<li>To make sure the framework will be available to your project when debugging, go to the iOS target in the Xojo navigator, right-click and select Build Step &gt; Copy Files. Make sure the step is between the Build step and the Sign step.</li>
<li>Drag the SimulatorStatusMagiciOS.framework file from the Finder into the Copy Files Step.</li>
<li>In the Xojo inspector, set Applies To to &#8220;Debug&#8221; and Destination to &#8220;App Parent Folder&#8221;.</li>
</ol>
<p>Now let&#8217;s make it so you can access the framework! We&#8217;re going to add this code in the App.Open event so that the status bar gets set up before you do anything else.</p>
<p>Getting the framework to load is fairly straightforward:</p>
<pre>#If DebugBuild
  Declare Function dlopen Lib "/usr/lib/libSystem.dylib" (name As CString, flags As Int32) As Ptr
  Call dlopen("@executable_path/SimulatorStatusMagiciOS.framework/SimulatorStatusMagiciOS", 1 Or 8)
#EndIf</pre>
<p>That magic string &#8220;@executable_path&#8221; gets translated into &#8220;wherever the current application currently is&#8221; at runtime. Now this just loads the framework. We still need to hook up the methods and properties. <em>Note: If you&#8217;re working with a framework that &#8220;activates itself&#8221; like the one that comes with <a href="https://revealapp.com">Reveal</a> (an excellent tool for tracking down iOS layout issues), this is as far as you would need to go.</em></p>
<p>To figure out what we need to do next, we need to look at the documentation and header files that come with SimulatorStatusMagic. Go back to Xcode and look at the navigator. What we&#8217;re looking for is a header file (with a .h extension) which has the definitions of each of the methods and properties which are available in this framework. The only file that meets this criteria (and the one that all the others seem to point to) is named SDStatusBarManager.h. There&#8217;s a bit of functionality available here, but the framework is set up to use the Apple recommended settings by default, so all we&#8217;re going to do here is call the enableOverrides method to activate it.</p>
<p>Go back to Xojo and update App.Open event:</p>
<pre>#If DebugBuild
  Declare Function dlopen Lib "/usr/lib/libSystem.dylib" (name As CString, flags As Int32) As Ptr
  Call dlopen("@executable_path/SimulatorStatusMagiciOS.framework/SimulatorStatusMagiciOS", 1 Or 8)

  // Start by creating a pointer to the SDStatusBarManager class itself
  Declare Function NSClassFromString Lib "Foundation" (clsName As CFStringRef) As Ptr
  Dim smclass As Ptr = NSClassFromString("SDStatusBarManager")

  // Next, we need a pointer to the shared instance of the SDStatusBarManager class
  Declare Function sharedInstance Lib "Foundation" Selector "sharedInstance" (clsref As Ptr) As Ptr
  Dim smclassShared as Ptr = sharedInstance(smclass)

  // Last, turn on the overrides
  // NOTE: We're specifically NOT using the actual lib name here. 
  // This is just to satisfy the Xojo linker. The correct framework will be used at runtime.
  Declare Sub enableOverrides Lib "Foundation" Selector "enableOverrides" (obj As Ptr)
  enableOverrides(smclassShared)
#EndIf</pre>
<p>Now if you run the project, when it opens the status bar automatically changes to the recommended defaults!</p>
<p>Please Note: These changes persist until the simulator device that you are running on is completely erased. If you need to disable it, you can do that with the disableOverrides method.</p>
<p>After posting this article, it was brought to my attention that I&#8217;d forgotten to show you how to sign the frameworks so you can build for the app store. To do that, you&#8217;ll need to add a script build step to your project, just after the Copy Files step you added above. The step can probably be set to Applies To: Release. The code should look like this:</p>
<pre>// Replace the text in the signingIdentity property with your own
Dim signingIdentity As String = "iPhone Distribution: Your Company (XXXXXXXXXX)"
Dim code As Integer
Dim cmd As String
Dim result As String
Dim builtApp As String

builtApp = CurrentBuildLocation + "/" + ReplaceAll(CurrentBuildAppName, " ", "\ ")

// Get a list of all frameworks, one per line
cmd = "ls -d1 " + builtApp + "/*.framework"
result = Trim(DoShellCommand(cmd, 30, code))

// If there was no error (like none being there), sign each one
If code = 0 Then
  Dim frameworks() As String = split(result, chr(13))
  For i As Integer = 0 To UBound(frameworks)
    frameworks(i) = ReplaceAll(frameworks(i), " ", "\ ")
    cmd = "/usr/bin/codesign -fs """ + signingIdentity + """ " + frameworks(i)

    Result = DoShellCommand(cmd, 30, code)

    // If the sign fails, print the error and stop the build
    If code &lt;&gt; 0 Then
      print Result
      cancelBuild
    End If
  Next i
End If</pre>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Xojo&#8217;s Newest iOSTable Features</title>
		<link>https://blog.xojo.com/2018/11/26/xojos-newest-iostable-features/</link>
		
		<dc:creator><![CDATA[Greg O'Lone]]></dc:creator>
		<pubDate>Mon, 26 Nov 2018 10:00:49 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[XDC]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=4153</guid>

					<description><![CDATA[While at the Xojo Developer Conference in Denver last spring*, we got a lot of great feedback about the features that people needed most from&#8230;]]></description>
										<content:encoded><![CDATA[<p>While at the Xojo Developer Conference in Denver last spring*, we got a lot of great feedback about the features that people needed most from the iOS framework. We managed to sneak a few into recent releases of Xojo; here are three of my favorites!</p>
<p><span id="more-4153"></span></p>
<h3>Variable Height iOSTable Rows</h3>
<p>When laying out lists of data in iOS, often there&#8217;s more than one way to get to where you need to be. The Bedtime, Stopwatch or Timer modes in the iOS Clock app are a great example of this. Instead of using a scrollable view, they use an TableView with variable height rows and starting in 2018r2 we&#8217;ve made this really simple to do too.</p>
<p>To make variable height rows, you&#8217;ll need to use a datasource with your iOSTable and create a subclass of iOSCustomTableCell just like you did previously and set the UseDynamicHeight property to True in the inspector. Then just make sure that you have a continuous string of constraints from the top of the cell to the bottom to tell the layout system how tall the cell needs to be. So if you have a layout that looks like this:</p>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-4411 " src="https://blog.xojo.com/wp-content/uploads/2018/06/iOSTable2018r2_1@2x.png" alt="" width="320" height="109" /></p>
<p>You would need to make sure that you have constraints like this:</p>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-5188 " src="https://blog.xojo.com/wp-content/uploads/2018/11/iOSTable2018r2_2@2x.png" alt="" width="322" height="144" /></p>
<ol>
<li>A constraint from the top of the cell to the top of the Username Label</li>
<li>A constraint defining the height of the Username Label</li>
<li>A constraint from the bottom of the Username Label to the Top of the Username TextField</li>
<li>A constraint defining the height of the Username TextField</li>
<li>A constraint from the bottom of the Username TextField to the bottom of the cell.</li>
</ol>
<p>Making this change also gets us a little bit of built-in magic such that any Label controls without a height constraint will automatically resize themselves to match the height of the text they contain, making your cells adapt better to localization or variable text. This also makes it possible to put a DatePicker in a cell and use it as the editor for the previous row by inserting it on-the-fly.</p>
<p><em>For an example of how to do this, see the CustomCellDynamicHeight project in the Example Projects/iOS/Controls/Table/ folder.</em></p>
<h3>Pull-To-Refresh</h3>
<p>Another feature that we got several requests for was the ability to use the iOS TableView&#8217;s built-in pull-to-refresh capability. An example of this can be seen in the Mail application when you are looking at the Mailbox list. Just drag downward until you see a progress wheel. That&#8217;s pull-to-refresh.</p>
<p>In Xojo it&#8217;s as simple as setting the new <strong>AllowRefresh</strong> property to True, implementing the <strong>Refreshed</strong> event and then call <strong>EndRefresh</strong> when you&#8217;ve received and updated the table to make the progress wheel disappear.</p>
<p><em>For an example of how to do this, see the TableDataSourceDatabase project in the Example Projects/iOS/Controls/Table/TableDataSourceDatabase folder.</em></p>
<h3>Row Add/Remove Animations</h3>
<p>Ever notice that when you add or remove a row on an iOSTable at runtime that they just kind of *POP* into existence? We&#8217;ve made it so that adding or removing a visible row is now animated, just like other apps on the device. This looks especially good when inserting a DatePicker control to edit a date!</p>
<p><em>For an example of how to do this, see the TableEditing project in the Example Projects/iOS/Controls/Table folder.</em></p>
<p>*Want to talk to Xojo engineers about what you want to see? Come to <a href="https://www.xojo.com/xdc/">XDC 2019 in Miami, Florida</a>!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>IDE changes in Xojo 2018r3 and more</title>
		<link>https://blog.xojo.com/2018/10/23/following-the-dark-path/</link>
		
		<dc:creator><![CDATA[Greg O'Lone]]></dc:creator>
		<pubDate>Tue, 23 Oct 2018 10:00:43 +0000</pubDate>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[DarkMode]]></category>
		<category><![CDATA[HiDPi]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[Lingua]]></category>
		<category><![CDATA[macOS]]></category>
		<category><![CDATA[Remote Debugging]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Xojo Feedback]]></category>
		<category><![CDATA[Xojo IDE]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=5075</guid>

					<description><![CDATA[About three years ago, we added HiDPI/Retina support to our framework which was released to users as part of Xojo 2016r1 when we also shipped&#8230;]]></description>
										<content:encoded><![CDATA[<p>About three years ago, we added HiDPI/Retina support to our framework which was released to users as part of Xojo 2016r1 when we also shipped our first HiDPI IDE.</p>
<p>With Apple’s announcements at WWDC 2018 and the introduction of dark mode it was time to revisit our graphics and the overall appearance of the IDE again. Here are some things which contribute to the changes that have been made and ones that you will see in the coming months.</p>
<p><span id="more-5075"></span></p>
<h3><b>Dropping macOS 10.9</b></h3>
<p>Xojo 2018r3 drops support for macOS 10.9 and as the last version which had the skeuomorphic design elements all of our supported OS’s now have the flatter modern design. It’s not that this has held anything up per se, but it’s a good reminder that “it’s time”.<span class="Apple-converted-space"> </span></p>
<p>To that end, we have taken that opportunity to remove some of the graphics that make the IDE look out of place and doing so subtly lowers the memory footprint and accelerates drawing of the IDE itself across all platforms. We&#8217;re also using a variation of Apple&#8217;s image templates which has somewhat reduced the on-disk footprint of the IDE itself.</p>
<h3><b>macOS Dark Mode</b></h3>
<p>Apple’s addition of a darker variant of the visual “Aqua” theme in macOS means that we needed to do an audit and update of several of our base framework controls so that <i>your</i> apps would render correctly as well as ours.<span class="Apple-converted-space"> </span></p>
<h4>Events</h4>
<p>While it probably won’t be used very often (how often does one change themes while running a piece of software, besides the novelty of seeing it happen), we added an event to the App class named AppearanceChanged to notify you when the user changes from light to dark or changes their accent color. This is a good place to clear any graphic or color caches which contain theme specific UI graphics.<span class="Apple-converted-space"> </span></p>
<h4>Methods</h4>
<p>There is also a new global method called IsDarkMode(Boolean) which will return True if your app is running with the Dark Mode theme on macOS 10.14 or higher.<span class="Apple-converted-space"> If your app is running on 10.13 or lower or in light mode on 10.14, IsDarkMode will return False.</span></p>
<h4>Build Settings</h4>
<p>Enabling Dark Mode in your apps is as easy as flipping a switch in the Shared Build Settings. Unfortunately, because Apple made the assumption that most apps would “just work” versions of your apps compiled with older versions of Xojo will either need to be recompiled with Xojo 2018r3 or you’ll need to push out a new version with a plist entry to prevent macOS 10.14 from showing your app dark in Dark Mode.<span class="Apple-converted-space"> </span></p>
<h4>Testing</h4>
<p>When testing apps for use with Mojave&#8217;s dark mode, I seriously suggest that you test on a system that allows you to see the translucency effects of dark mode. Virtual Machines are usually really handy for testing, but in this case, Parallels Desktop 14, VirtualBox 5.2 and VMWare Fusion 11 do not show the subtleties of dark mode.</p>
<h4>Colors</h4>
<p>One of our goals at Xojo is to remove some of the headaches involved with the minutiae of each OS that you deploy for and to that end, we wanted to make drawing custom controls easier too. What this means is that the built-in global colors are largely theme aware now and will change depending on whether your app is running in light or dark mode on macOS. This affects things like TextColor, FillColor, FrameColor, HighlightColor, etc, so if you use those methods when drawing in pictures and canvases, you will want to audit that code. If you want a specific color, you should use a color constant. For instance, use &amp;c000000 if you want black because TextColor will now return white in Dark Mode.<span class="Apple-converted-space"> </span></p>
<p>In terms of the framework controls themselves, we are taking this opportunity to make some changes to make your apps appear better in the macOS 10.10+ ecosystem. Ever notice that a Label control and the text portion of a CheckBox or RadioButton control are not exactly the same color? Going forward, the default colors of controls which <i>should</i> automatically change between Light and Dark modes <i>will</i> do that. So if you have a Label using the default color of &amp;c00000000 (Black with Transparency = 0), the color that is actually used is what Apple calls labelColor. It’s still black, but is a tiny bit translucent. TextFields and TextAreas will automatically change text, placeholder, selection and background colors to match the Apple prescribed colors for automatic Light/Dark compatibly. We think you’ll find that building your apps with 2018r3 will largely make them just behave and appear the way you expected them to.</p>
<p>IMPORTANT NOTE: These color and framework changes affect how your apps draw on <i>all</i> versions of macOS, so make sure you try them out on your 10.10 through 10.14 VMs before shipping!</p>
<h4>Eating our own dog food</h4>
<p>One thing we hear from users every so often is the desire for Xojo to use our own products for building apps. As most of you know the IDE itself is written in Xojo, but we also have several other apps (big and small) that are written in Xojo.</p>
<ul>
<li>Feedback &#8211; Our bug reporting system</li>
<li>Xorders &#8211; Our internal order system</li>
<li>Lingua &#8211; The Xojo localization app</li>
<li>Remote Debugger &#8211; The remote debugger stubs for desktop and console</li>
</ul>
<p>While the 2018r3 cycle was in progress, all four of these projects got updated for Mojave&#8217;s Dark Mode and definitely helped us find framework rendering bugs early on in the pre-release process.</p>
<h4><b>What about Windows and Linux?</b></h4>
<p>The TL;DR version is that we’re still looking into it.<span class="Apple-converted-space"> </span></p>
<p>Currently there are several different ways to change Windows 7, 8 and 10 to use a dark interface, not all of which are compatible with the Xojo Framework controls and the Windows 10 2018 Fall Update promised yet another way but that ended up only being for UWP. We are looking into which method gets you the most “bang for the buck” so to speak.<span class="Apple-converted-space"> </span></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Using Subversion Externals with Xojo Text Projects</title>
		<link>https://blog.xojo.com/2018/04/06/using-subversion-externalswith-xojo-text-projects/</link>
		
		<dc:creator><![CDATA[Greg O'Lone]]></dc:creator>
		<pubDate>Fri, 06 Apr 2018 10:00:59 +0000</pubDate>
				<category><![CDATA[Source Control]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[SVN]]></category>
		<category><![CDATA[VCP]]></category>
		<category><![CDATA[Version Control]]></category>
		<guid isPermaLink="false">http://blog.xojo.com/?p=2160</guid>

					<description><![CDATA[How to share code among several projects with more than one developer? There can be issues with exporting classes and modules to a shared folder and have everyone include those in their projects use them, especially when using shared services like DropBox. The folks at who are maintaining Subversion at the Apache Software Foundation made it super easy to create shared code repositories using a feature called Externals.]]></description>
										<content:encoded><![CDATA[<p>A topic that comes up every once in a while on the forums is how to share code among several projects with more than one developer. Quite often what users try to do is to export classes and modules to a shared folder and have everyone include those in their projects. There can be issues with this technique, especially when using shared services like DropBox.</p>
<p>Because of the latency involved, external items shared in a shared folder on a server or a file sharing service are never truly in-sync with one another. While this technique works with a single developer across two or three projects, it gets more and more complicated as you add more projects and even more-so if you try to add more developers.</p>
<p>One of the largest issues with this type of system is that everything <em>must</em> be kept in sync all the time. Making one little change to a shared file or method which works fine in the current project could completely break a project that you haven&#8217;t worked on in a year. When you do get around to working on it again, there&#8217;s three possibilities:</p>
<ol>
<li>The project compiles and everything works just like it did before.</li>
<li>The project doesn&#8217;t compile.</li>
<li>The project compiles and doesn&#8217;t work like it did before.</li>
</ol>
<p>With careful planning, you&#8217;ll probably hit #1 75% of the time, but the other two are wrought with problems. If the project compiles but doesn&#8217;t work correctly, <em>you may not find out until you&#8217;ve given it to your users,</em> with the worst case being unrecoverable data corruption. If it doesn&#8217;t compile, then what? The shared code is now required to be different in two different projects and you may have no history as to what was changed.</p>
<p>Thankfully the folks at who are maintaining <a href="https://subversion.apache.org">Subversion at the Apache Software Foundation</a> made it super easy to create shared code repositories using a feature called Externals. (For those of you that are using Git, I suggest looking into Submodules. Of the two techniques I&#8217;ve encountered, Submodules seem to require the least individual overhead.)</p>
<p><span id="more-2160"></span></p>
<h3>SVN Externals</h3>
<p>SVN Externals are exposed as a property (svn:externals) on the containing folder and is set up using the <strong>svn propset</strong> or <strong>svn propedit</strong> commands, but most SVN visual clients have an interface for creating an SVN External to make the process easier. Once it&#8217;s set on a versioned directory, everyone who checks out or updates the working copy also gets the external definition.</p>
<p>It&#8217;s worth keeping in mind that because an SVN External definition points to a specific place within another repository, that this other location is also versioned. That is, you can (and probably should) point an external definition at a <em>particular revision</em> within that repository unless there&#8217;s a very good reason to always be pointing at the latest/greatest version. This helps alleviate the problems with shared library changes. Once you have it working for a particular version, you can lock-in to a particular date/time until you&#8217;re ready to check with a newer version.</p>
<h3>Externals in Xojo</h3>
<p>Setting up externals for use with a Xojo Text Project is fairly simple to do. As an example, let&#8217;s say you have two projects &#8230; ProjectX and ProjectY. ProjectX contains some items that you&#8217;d like to share with ProjectY.</p>
<ol>
<li>Within Xojo, Open ProjectX and make a folder named &#8220;Shared_Items&#8221; and move any items you wish to share into this folder.</li>
<li>Save ProjectX and close it.</li>
<li>Quit the IDE.</li>
<li>Depending on whether you&#8217;re using a visual SVN client or the SVN command line the steps are similar:
<ol>
<li>Go to the directory above where the &#8220;Shared_Items&#8221; folder is located in ProjectY</li>
<li>Remove the empty &#8220;Shared_Items&#8221; folder.</li>
<li>Add an SVN external with the name &#8220;Shared_Items&#8221; which points to the Shared_Items in the other repository (or branch or wherever it is).
<ol>
<li>If you&#8217;re doing this using the command line, the command is:<br />
<code>svn propset svn:externals "Shared_Items https://path/to/other/Shared_Items" .</code><br />
If you want to lock the project to a particular revision, you&#8217;ll need to tell SVN which revision to use:<br />
<code>svn propset svn:externals "Shared_Items -r12345 https://path/to/other/Shared_Items" .</code><br />
Each of these commands are basically saying: Create a new external named &#8220;Shared_Items&#8221; using the https://path/to/other/Shared_Items source in the local directory (.), with the second one specifying that you want to use revision 12345.</li>
<li>If you&#8217;re using a GUI client you usually select the parent folder and then add an external definition from there. There are usually fields for specifying the Local Path (Shared_Items), URL (https://path/to/other/Shared_Items) and Revision (either HEAD or a specific revision number)</li>
</ol>
</li>
<li>Now you need to update the contents of the folder.<br />
<code>svn update Shared_Items</code></li>
</ol>
</li>
<li>Open ProjectY.</li>
<li>Drag the &#8220;Shared_Items&#8221; folder from the project folder directly into your project. DO NOT SAVE YET. Any modules which contained other items will be represented by a Module in the project and an identically named Folder which contains the items that should be put inside the module.</li>
<li>Referring back to Project X, drag each of the items in Shared_Items to its corresponding location in ProjectY. It&#8217;s very important that the on-disk representation in both projects be identical, so make sure you&#8217;re using the same version of Xojo in both projects. For example, if after dragging in the Shared_Items folder, you might have:
<pre>Shared_Items
  Module1 (Module)
  Module1 (Folder)
    Class1
    Module2 (Module)
    Module2 (Folder)
      Class2</pre>
</li>
<li>If you have multiple levels of nested modules, I suggest working from the bottom up, that is from the lowest directories up to the highest ones to avoid confusion. Once you&#8217;ve emptied a folder, delete it. Using the example above:
<ol>
<li>Drag Class2 from the Module2 <em>folder</em> directly into the Module2 <em>module.</em></li>
<li>Delete the Module2 <em>folder</em>.</li>
<li>Drag Class1 from the Module1 <em>folder</em> directly into the Module1 <em>module</em>.</li>
<li>Drag Module2 <em>module</em> into the Module1 <em>module</em>.</li>
<li>Delete the Module1 <em>folder</em>.</li>
</ol>
</li>
<li>Once the structure looks the same between the two projects, Save ProjectY. You&#8217;ll notice that <em>on disk</em> the folders are still there. That&#8217;s exactly what you should see. Check your SVN client, there should be no changes to be checked in. If there are, make sure they&#8217;re not file additions and/or deletions.</li>
</ol>
<p>From now on (if you&#8217;re using a non-revision specific external), whenever you make a change to one of the items in this Shared_Items folder and check them in, they&#8217;ll be available to any other projects that use them, whether it&#8217;s the original items or any project where this folder is defined as an external.</p>
<p>While this looks really complicated to set up, once it&#8217;s done using the external will work and feel just like any other folder in your project.</p>
<p>A few things to remember:</p>
<ol>
<li>Make sure you&#8217;ve named the shared items container so that it&#8217;s obvious that the items are shared between projects, so things don&#8217;t get inadvertently dragged into the folder if they&#8217;re not needed anywhere else and not dragged out of the folder if they are.</li>
<li>Make sure everyone on your team understands that this code is shared among projects.</li>
<li>Write Unit Tests for your shared items so when making changes you can verify that you&#8217;re not breaking other projects or inadvertently changing their behavior.</li>
</ol>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>IDECommunicator Protocol v2</title>
		<link>https://blog.xojo.com/2017/06/30/idecommunicator-protocol-v2/</link>
		
		<dc:creator><![CDATA[Greg O'Lone]]></dc:creator>
		<pubDate>Fri, 30 Jun 2017 15:00:43 +0000</pubDate>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[Automated Builds]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[IDECommunicator]]></category>
		<guid isPermaLink="false">http://blog.xojo.com/?p=3064</guid>

					<description><![CDATA[About two years ago, at XDC 2015 in Austin, Philippe Casgrain from LightSpeed did a bonus presentation on the benefits of Continuous Integration when building&#8230;]]></description>
										<content:encoded><![CDATA[<p>About two years ago, at XDC 2015 in Austin, Philippe Casgrain from LightSpeed did a bonus presentation on the benefits of Continuous Integration when building projects with Xojo. Coincidentally, we at Xojo had decided just days before that we needed to move away from manual builds and automate as much of our build process as possible to keep up with the increasing complexity and number of our frameworks (later that summer we would be going from 3 to 8). After the presentation, we heard from several developers asking when the limitations of automated builds would be addressed and because we were working on our own process, it gave us an excellent place to try out new things while ironing out the wrinkles.</p>
<p><span id="more-3064"></span></p>
<h3>Challenges</h3>
<p>The foremost issue that we had to fix was that the original protocol was designed so that it required you to close the IPCSocket to get your command to run. That meant there was no longer a connection on which the IDE could send any kind of response. It also meant that dealing with issues required making multiple connections.</p>
<p>The second was that there were many things that raised dialogs when something went wrong, which meant that an unattended IDE could get &#8220;stuck&#8221; waiting for user input which would never come. We&#8217;d heard that developers would have their systems take a screenshot if an hour had passed with no activity so they could figure out what had gone wrong, but that can be a huge waste of time if you&#8217;re waiting on a build.</p>
<h3>Solutions</h3>
<p>The new protocol (which was beta in 2016r4 and officially released in 2017r1) addresses both of these problems. The new protocol uses JSON for the command format and the IDE can send back all kinds of information including (but not limited to):</p>
<p>* Script syntax errors<br />
* Script runtime errors<br />
* IDE version conflicts<br />
* Missing assets<br />
* Compile errors</p>
<p>All of these things are returned to your calling script so you can take appropriate action. Because this is truly a two-way protocol now, you can also send data back to your script, like if you wanted to return the path of the built app back to your build system.</p>
<p>We&#8217;ve also been working to make anything that would normally show a dialog to the user gets sent back to the app communicating with the Xojo IDE. As far was we know, all but one was caught, and a fix for it has been submitted for 2017r2.</p>
<p>If you&#8217;d like to see the new IDECommunicator protocol in action, look in the Examples folder next to the IDE: Examples &gt; Advanced &gt; IDE Scripting &gt; IDECommunicator &gt; v2 &gt; IDECommunicator-Tester.xojo_binary_project</p>
<p>For documentation and more information refer to the doc page here: <a href="http://developer.xojo.com/userguide/ide-communicator">IDE Communicator</a></p>
<p><em>Just a note for those of you who have already been using the IDECommunicator project (or something similar) for controlling your builds, when updating to the new protocol make sure you don&#8217;t include a QuitIDE command in the script you initially send to the IDE. Doing so will cause the IDE to quit before you get a response which would present as a false positive. I suggest waiting until you do get a response and then issue a separate QuitIDE command at the end.</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Using Raw HTML in Xojo 2017r1</title>
		<link>https://blog.xojo.com/2017/04/05/alyssa/</link>
		
		<dc:creator><![CDATA[Greg O'Lone]]></dc:creator>
		<pubDate>Wed, 05 Apr 2017 20:22:59 +0000</pubDate>
				<category><![CDATA[Web]]></category>
		<guid isPermaLink="false">http://blog.xojo.com/?p=2519</guid>

					<description><![CDATA[One of the most frequent requests we get about the web framework is the ability to include raw HTML code when setting text. Starting in&#8230;]]></description>
										<content:encoded><![CDATA[<p>One of the most frequent requests we get about the web framework is the ability to include raw HTML code when setting text. Starting in 2017, this is now possible&#8230; and perhaps ironically, it&#8217;s activated using an html-style tag.</p>
<p><span id="more-2519"></span></p>
<h3>QuickStart</h3>
<p>The simplest way to see this in action is to see it in a label.</p>
<ol>
<li>Create a new Web project.</li>
<li>Add a WebLabel instance to WebPage1</li>
<li>Set its text to &#8220;This is a &lt;raw&gt;&lt;strong&gt;&lt;em&gt;test&lt;/em&gt;&lt;/strong&gt;&lt;/raw&gt;.&#8221;</li>
<li>Run the project.</li>
<li>The label&#8217;s text should be &#8220;This is a <strong><em>test</em></strong>.&#8221;</li>
</ol>
<h3>Using &lt;raw&gt; tags</h3>
<p>So you&#8217;re probably wondering where you can use these &lt;raw&gt; tags. The answer is<em> just about anywhere&#8230;</em></p>
<ul>
<li>App.DisconnectMessage &#8211; You can now add a link to the message to help users get back to your app if they get disconnected.</li>
<li>App.LaunchMessage &#8211; Add some text styling to the text that appears below the app icon.</li>
<li>WebLabels</li>
<li>WebCheckboxes</li>
<li>WebLinks</li>
<li><em>WebListboxes</em>*</li>
<li>WebRadioButtons</li>
</ul>
<p>* You may have noticed that we added pictures to WebListbox in 2016r4&#8230; now you can add <em>any</em> html tags to a listbox cell if you want to!</p>
<p>Go have fun with this new feature. We&#8217;re looking forward to seeing how you use it!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Xojo.Net.HTTPSocket Speed on Windows</title>
		<link>https://blog.xojo.com/2017/03/09/xojo-net-httpsocket-speed-on-windows/</link>
		
		<dc:creator><![CDATA[Greg O'Lone]]></dc:creator>
		<pubDate>Thu, 09 Mar 2017 06:46:11 +0000</pubDate>
				<category><![CDATA[Networking]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[DNS]]></category>
		<category><![CDATA[HTTPSocket]]></category>
		<category><![CDATA[IPv6]]></category>
		<category><![CDATA[Xojo Framework]]></category>
		<guid isPermaLink="false">http://blog.xojo.com/?p=2233</guid>

					<description><![CDATA[There&#8217;s been a bit of discussion about how the new Xojo.Net.HTTPSocket is slow for some users on Windows, which we&#8217;ve been trying to isolate to&#8230;]]></description>
										<content:encoded><![CDATA[<p>There&#8217;s been a bit of discussion about how the new <a href="http://developer.xojo.com/xojo-net-httpsocket">Xojo.Net.HTTPSocket</a> is slow for some users on Windows, which we&#8217;ve been trying to isolate to get fixed.</p>
<p>After a bit of experimentation this January we were able to isolate one huge cause of this annoying behavior. Unfortunately it has to do with a misconfigured IPv6 DNS server configuration and whether or not yours is correct may be up to your service provider.</p>
<h3>Whose bug is this?</h3>
<p>According to the spec, IPv6 DNS servers are <em>supposed to</em> return immediately if they can&#8217;t fulfill the request. Unfortunately this is almost the exact opposite of what an IPv4 DNS server does, in that it <em>may</em> forward your request to the next server to see if it knows where your request should go. Unfortunately we found that only about two-thirds of the ones we tested were correctly configured.</p>
<p>On macOS and Linux, DNS requests are sent concurrently, that is, two requests are sent at the same time, one each for IPv4 and IPv6. The one that returns first is used. On Windows, the requests are unfortunately sent sequentially, IPv6 <em>and then IPv4</em>. What this means is that IPv6 requests just hang there, waiting for a response that will either never come or will wait until the underlying socket reaches its timeout. When that fails, the IPv4 request is sent and fulfilled and your socket request goes through.</p>
<h3>What To Do</h3>
<p>Here are a few things you can do to test this theory. While you can&#8217;t really ask all of your users to do this, it will tell you if this is where the problem lies.</p>
<ol>
<li>Turn off IPv6.
<ol>
<li>Click <strong>Start</strong> and then <strong>Settings.</strong></li>
<li>Search for <strong>Network Connections</strong>.</li>
<li>Click <strong>View network connections</strong>.</li>
<li>Right-click on the active connection and select <strong>Properties</strong>.</li>
<li>On the <strong>Networking</strong> tab, clear the <strong>Internet Protocol Version 6 (TCP/IPv6)</strong> check box, and then click <strong>OK</strong>.</li>
</ol>
</li>
<li>Change the DNS entries for IPv6 from the defaults to point to <a href="https://developers.google.com/speed/public-dns/">Google Public DNS</a> or <a href="http://opendns.com">OpenDNS</a>.</li>
<li>Make a Hosts file entry. If your installer runs as an administrator, you can make an entry in the hosts file to force the computer to use IPv4. <em><em><em>This is not a long term solution as the world moves to IPv6.</em></em></em>The hosts file on Windows 7/8/10 is located at:
<pre>C:\Windows\System32\drivers\etc</pre>
<p>and you should add an entry which looks like this:</p>
<pre>Server IP Address&lt;TAB&gt;domain name</pre>
</li>
<li>If it&#8217;s a domain that you control, make sure you only use IPv4 DNS entries and that your server is only listening on the IPv4 interface.</li>
</ol>
<p>All in all, it&#8217;s a frustrating problem. While there&#8217;s no easy solution, the good news is that because there are no IPv4 addresses left to be distributed, the world <em>is</em> moving to IPv6. The more demand there is, the more likely that the incorrect DNS servers will get fixed because they&#8217;ll cause problems for other sites as well.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>IDE Scripts for Text Insertion</title>
		<link>https://blog.xojo.com/2017/01/03/ide-scripts-for-text-insertion/</link>
		
		<dc:creator><![CDATA[Greg O'Lone]]></dc:creator>
		<pubDate>Tue, 03 Jan 2017 23:35:12 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Beginner Tips]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<guid isPermaLink="false">http://blog.xojo.com/?p=2105</guid>

					<description><![CDATA[IDE Scripts to the rescue! With a simple script (less than 10 lines), whenever you have quoted text to paste into the IDE, just select your script from the File > IDE Scripts menu instead.]]></description>
										<content:encoded><![CDATA[<p>Working on the Xojo family of products, I spend a lot of time copying and pasting text into of the code editor and I <em>really hate</em> wasting time. One particularly challenging thing is bringing text into the code editor that contains quotes because they all need to be doubled up to work. For example for text that looks like this:</p>
<pre>CREATE TABLE "Servers" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" TEXT, "ip" TEXT)</pre>
<p>If you wanted to use that in a string, you need to double up each of those quotes to make them work:</p>
<pre>dim sql as string = "CREATE TABLE ""PendingControllers"" (""id"" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, ""name"" TEXT, ""ip"" TEXT)"</pre>
<p>One line isn&#8217;t bad, but if you have a bunch to do, it can become quite tedious.</p>
<p>IDE Scripts to the rescue! With a simple script (less than 10 lines) you can have the IDE do this for you automatically.</p>
<ol>
<li>In the Xojo IDE, select <strong>File &gt; IDE Scripts &gt; New IDE Script</strong></li>
<li>In the script editor place the following code:
<pre>// Get the text from the clipboard
Dim c As String = Clipboard

// Double up all of the quotes
c = c.ReplaceAll("""","""""")

// Insert the text into the code editor
SelText = c</pre>
</li>
<li>Select <strong>File &gt; Save As</strong> and save the script to the &#8220;Scripts&#8221; folder next to the IDE.</li>
</ol>
<p>Now whenever you have quoted text to paste into the IDE, just select your script from the File &gt; IDE Scripts menu instead!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Web Framework Changes in 2016r2</title>
		<link>https://blog.xojo.com/2016/07/20/web-framework-changes-in-2016r2/</link>
		
		<dc:creator><![CDATA[Greg O'Lone]]></dc:creator>
		<pubDate>Wed, 20 Jul 2016 07:03:46 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[HiDPi]]></category>
		<category><![CDATA[Retina]]></category>
		<category><![CDATA[Xojo Framework]]></category>
		<guid isPermaLink="false">http://blog.xojo.com/?p=1085</guid>

					<description><![CDATA[The web framework got some love in Xojo 2016r2&#8230; General Changes First, the Web Framework now has support for Retina/HiDPI in supported browsers. All controls&#8230;]]></description>
										<content:encoded><![CDATA[<p>The web framework got some love in Xojo 2016r2&#8230;</p>
<h2>General Changes</h2>
<p>First, the Web Framework now has support for Retina/HiDPI in supported browsers. All controls have been updated with new graphics to allow your Web Apps to look great on any screen. All you have to do is just flip the &#8220;Supports Retina/HiDPI&#8221; switch and start using Image objects instead of Pictures and you&#8217;re off and running!</p>
<p><em>NOTE: Regardless of whether you check the &#8220;Supports Retina/HiDPI&#8221; switch, the web framework now stores all of your image assets in the Resources directory next to your app and they are only loaded momentarily when a browser requests one. This means that your app should use a lot less memory overall.</em></p>
<p><strong>Controls</strong></p>
<p>WebCanvas: HiDPI/Retina drawing out of the box! No code change required!</p>
<p>WebPicture: Just start using Images instead of Pictures and flip the Retina/HiDPI switch and the web framework will automatically send the correct resolution image to the browser.</p>
<p>WebImageView: Because it&#8217;s backed with a WebPicture, it just works!</p>
<p>WebToolbar: Toolbar icons now support Images as well.</p>
<p><strong>Events</strong></p>
<p>WebSession.ScaleFactorChanged: Fires whenever the ScaleFactor of the current session&#8217;s browser changes.</p>
<p><strong>Properties</strong></p>
<p>WebSession.ScaleFactor (Read-Only): Reflects the current ScaleFactor of the browser.</p>
<h2>WebSDK</h2>
<p>The WebSDK has been given a ScaleFactorChanged event so your control is notified when a change occurs instead of your control needing to periodically check the ScaleFactor property on the Session object.</p>
<p>WebControlWrapper.ScaleFactorChanged: Fires whenever the ScaleFactor of the current session&#8217;s browser changes.</p>
<p>Also for WebSDK, we are now enforcing unique Javascript Namespaces throughout a project at compile time. This means you&#8217;ll be able to tell ahead of time if your controls are missing a namespace or if you&#8217;ve inadvertently used the same exact namespace more than once!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Xojo Retina/HiDPI: The journey of a thousand pixels&#8230;</title>
		<link>https://blog.xojo.com/2016/04/05/xojo-retinahidpi-the-journey-of-a-thousand-pixels/</link>
					<comments>https://blog.xojo.com/2016/04/05/xojo-retinahidpi-the-journey-of-a-thousand-pixels/#comments</comments>
		
		<dc:creator><![CDATA[Greg O'Lone]]></dc:creator>
		<pubDate>Tue, 05 Apr 2016 00:00:00 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[HiDPi]]></category>
		<category><![CDATA[Retina]]></category>
		<guid isPermaLink="false">http://blogtemp.xojo.com/2016/04/05/xojo-retinahidpi-the-journey-of-a-thousand-pixels/</guid>

					<description><![CDATA[Tips, Tricks and Code to help you build your first Retina / HiDPI apps with Xojo 2016r1.]]></description>
										<content:encoded><![CDATA[<p>&#8220;Retina&#8221; is the name for high resolution screens on Mac and iOS devices while &#8220;HiDPI&#8221; is the Windows equivalent. For simplicity, I&#8217;ll use HiDPI (which really is the universal technical term) for the rest of this blog post. Now that we have HiDPI support in Xojo, if you app doesn&#8217;t use any pictures, you can simply open your project, click on Shared under Build Settings and turn on the &#8220;Supports Retina/HiDPI&#8221; option. That&#8217;s all you need to do to have a HiDPI version of your app!</p>
<p>Having said that, if you are creating or using pictures in your project, there may be a few adjustments you&#8217;ll need to make to your code. A little over a year ago the process of making sure we had all of the necessary graphics together to build a Retina/HiDPI IDE was added to my to-do list. While 95% of the icons created for the Xojo IDE in 2013 already existed, most of the graphics that made up the IDE itself did not, and the IDE itself needed a bit of an overhaul to get it ready for the big change, both in graphics and in code&#8230;</p>
<p><span id="more-230"></span><span style="font-size: 18px;"><strong>Graphics</strong></span></p>
<p>Since the Xojo framework didn&#8217;t have any HiDPI support yet, everything done last year was done brute force, that is, 2x images were loaded, scaled down by 50% and drawn where they belonged, just to make sure things would mostly line up correctly. While doing this did reveal the amount of work that we were in for, it also hid some issues that we ran into when the HiDPI-enabled frameworks started coming available this spring.</p>
<p>To give you an idea of the size of the task, there are a little over 1000 distinct icons and images used in the IDE today, of which ~370 we did not have a HiDPI version. Now while I like using programs like PhotoshopÂ® or FireworksÂ® for doing work like this, I wanted to transition our graphics to a vector drawing tool so that if/when a higher resolution screen is available, we&#8217;ll be able to go back to the originals and start from resolution-independent source-material. That said, we settled on using Bohemian Coding&#8217;s <a href="http://www.sketchapp.com" target="_blank" rel="nofollow">Sketch</a> for the majority of the new graphics work. Total time to generate the missing images was about two man-months.</p>
<p><span style="font-size: 18px;"><strong>Code</strong></span></p>
<p>Once the HiDPI-enabled frameworks started coming together, every place where a picture was being drawn needed to be audited (see why in the next section). This work took us from mid-December all the way through mid-March. I won&#8217;t tell you that it took two of us three full months of 60 hour weeks to accomplish, <em>but it sure felt like it</em>.</p>
<p>A couple of legacy coding issues came to light which would have to be resolved for everything to work right and I wanted to go over them just in case your projects don&#8217;t render correctly right off the bat. Let&#8217;s look at what&#8217;s changed.</p>
<p><strong>Points vs. Pixels</strong></p>
<p>This is by far the most common issue you&#8217;ll probably run into. Before Xojo had HiDPI support, a single element of color on a Picture and a single element of color on a Graphics object were exactly the same thing, pixel for pixel.. If your code looked like this:</p>
<pre style="background-color: #ffffcc; padding: 10px;">Dim p As New Picture(100, 100)
Dim g as Graphics = p.Graphics
Dim widthPic as Integer = p.Width
Dim widthGraphics as Integer = g.Width</pre>
<p>both widthPic and widthGraphics would have values of 100.</p>
<p>Now with HiDPI turned on, Picture coordinates and Graphics coordinates <em>can be</em> different from one another if the scale factor of the screen is greater than one. If you were to change the code above to:</p>
<div style="background-color: #ffffcc; padding: 10px;">
<pre>Dim p As TrueWindow.BitmapForCaching(100, 100)
Dim g as Graphics = p.Graphics
Dim widthPic as Integer = p.Width
Dim widthGraphics as Integer = g.Width</pre>
<p><em><span style="font-size: 12px;">Note: The BitmapForCaching method creates an image that has the right number of pixels and the right scale factor so you can just draw to it the way you always have and have everything still work exactly the same.</span></em></p>
</div>
<p>The value of widthPic will differ depending on whether your application is running on a HiDPI screen or not:</p>
<table style="height: 80px; border: 1px solid black; margin-left: auto; margin-right: auto;" border="0" width="395">
<tbody>
<tr>
<td></td>
<td style="text-align: center;">widthPic</td>
<td style="text-align: center;">widthGraphics</td>
</tr>
<tr>
<td style="text-align: right;">Normal</td>
<td style="text-align: center;">100</td>
<td style="text-align: center;">100</td>
</tr>
<tr>
<td style="text-align: right;">HiDPI</td>
<td style="text-align: center;"><strong>200</strong></td>
<td style="text-align: center;">100</td>
</tr>
</tbody>
</table>
<p>&#8230;and this is where the trouble begins because the number of physical pixels has actually doubled (in both directions, by the way) while the width and height of the Graphics object still reflect the original dimensions. The difference between these values is the scale factor of the screen you are drawing to.</p>
<p>Now, if you consider that Picture.Width and Graphics.Width have been interchangeable until now, you can see that this can cause a bit of a problem. When drawing to the Graphics object, you need to be working in Graphics pixels, not Picture pixels:</p>
<pre style="background-color: #ffffcc; padding: 10px;">Dim p As TrueWindow.BitmapForCaching(100, 100)
Dim g as Graphics = p.Graphics
Dim widthPic as Integer = p.Width
Dim widthGraphics as Integer = g.Width
g.ForeColor = &amp;cFF0000
g.DrawOval(0, 0, g.Width, g.Height) // Correct
g.DrawOval(0, 0, p.Width, p.Height) // This will draw too large</pre>
<p>To wrap up this already long story, make sure all of your drawing routines are using coordinates relative to the Graphics object.</p>
<div style="background-color: #eee; padding: 10px;">If right about now you&#8217;re wondering what we were smoking when this decision was made, rest assured that it was discussed for a long time and the overwhelming driving force was to maintain backward compatibility. With things set up this way you can still draw it onto a Graphics object created with the HiDPI framework and it should just work!</div>
<p><strong>Immutable Pictures</strong></p>
<p>Another hurdle you&#8217;ll undoubtedly encounter is the fact that multiresolution images are not inherently editable. This allows the framework to be more intelligent about loading and unloading images at runtime. This affects Image objects created in the IDE as well as ones created in code using the new Picture Constructor API. The most obvious effect is that you can&#8217;t draw directly to these images any more and the Graphics and RGBSurface properties will be Nil. If you need the ability to draw onto a picture via its Graphics property, draw the image onto a Picture created in code and work from that &#8211; don&#8217;t forget to copy the scale properties!</p>
<p><strong>Nested Drawing</strong></p>
<p>If your application creates pictures, and draws other pictures and clips into it using several levels of nesting, make sure you start from the top level when refactoring your code. You&#8217;ll find any compounded scaling errors much earlier this way, but you&#8217;ll also run a much smaller risk of creating issues that will only manifest when you go back and fix the top level drawing routines.</p>
<p><strong>Drawing Without Context</strong></p>
<p>For most of you, your drawing code will be directly in the Paint event of a Canvas and the Graphics object passed to the event already has all of the information that you need to succeed. In addition, you can always get a mutable picture that is all set up for the current screen by calling the new Window.BitmapForCaching method. This method is available from any RectControl, Window or ContainerControl subclass using TrueWindow.BitmapForCaching.</p>
<p>If (for some reason) you don&#8217;t have access to a window from your code, you <em>can</em> create a HiDPI image from a Graphics context by using the new ScaleX and ScaleY properties to set things up. For consistency, we created an extends method in a module like this:</p>
<pre style="background-color: #ffffcc; padding: 10px;">Function BitmapForCaching(Extends g as Graphics, Width as Integer,  Height as Integer) As Picture
  Dim p as New Picture(Width * g.ScaleX, Height * g.ScaleY)
  // Set the appropriate resolution
  p.HorizontalResolution = 72 * g.ScaleX
  p.VerticalResolution = 72 * g.ScaleY

  // Set the scale factor so drawing to it will be correct
  p.Graphics.ScaleX = g.ScaleX
  p.Graphics.ScaleY = g.ScaleY

  // Very important to remember the mask!
  p.Mask.Graphics.ScaleX = g.ScaleX
  p.Mask.Graphics.ScaleY = g.ScaleY

  // Return the new picture
  Return p
End Function</pre>
<p>If neither a Window nor a Graphics context is available, you can always create a multi-representation picture and leave it up to the framework to choose the right one when the image is being drawn to a Window, like this:</p>
<pre style="background-color: #ffffcc; padding: 10px;">Dim pa() as Picture
Dim p1 as new Picture(100, 100)
p1.Graphics.DrawOval(0, 0, 100, 100)
pa.append p1

Dim p2 as New Picture(200, 200)
p2.Graphics.DrawOval(0, 0, 200, 200)
pa.append p2

Dim RetinaPicture as New Picture(100, 100, pa)</pre>
<p>You&#8217;ll have to draw everything twice, so I suggest caching these images so you don&#8217;t need to do this more than once, especially if your drawing code is complicated. You can use a similar technique to load images from disk:</p>
<pre style="background-color: #ffffcc; padding: 10px;">Dim pa() as Picture
Dim f as Folderitem = GetFolderItem("Test.png")
Dim pic as Picture = Picture.Open(f)
pa.append pic

f = GetFolderItem("Test@2x.png")
pic = Picture.Open(f)
pa.append pic

Dim RetinaPicture as New Picture(100, 100, pa)</pre>
<p>Just remember that the images passed into this form of the Picture.Constructor must all have exactly the same aspect ratio or the framework will throw an InvalidArgumentException!</p>
<p><span style="font-size: 18px;"><strong>Conclusion</strong></span></p>
<p>We&#8217;re looking forward to seeing all of your apps become HiDPI-aware and hearing about your experiences. I hope that our experience and suggestions make your transition just a little bit easier!<span id="hs-cta-wrapper-aeb03183-a469-4f96-9547-7dd75111c681" class="hs-cta-wrapper"><span id="hs-cta-aeb03183-a469-4f96-9547-7dd75111c681" class="hs-cta-node hs-cta-aeb03183-a469-4f96-9547-7dd75111c681"><a href="http://cta-redirect.hubspot.com/cta/redirect/608515/aeb03183-a469-4f96-9547-7dd75111c681" target="_blank"><br />
</a> </span><script src="https://js.hscta.net/cta/current.js" charset="utf-8">// <![CDATA[
<script type="text/javascript"><![CDATA[ hbspt.cta.load(608515, 'aeb03183-a469-4f96-9547-7dd75111c681', {}); // ]]&gt;</script></span></p>
<p>Read more: <a href="http://blog.xojo.com/2016/04/07/advanced-retinahidpi-bitmapforcaching-and-scalefactorchanged/">Advanced Retina/HiDPI: BitmapForCatching and ScaleFactorChanged</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.xojo.com/2016/04/05/xojo-retinahidpi-the-journey-of-a-thousand-pixels/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Generating Xojo Code From Paw</title>
		<link>https://blog.xojo.com/2016/01/06/generating-xojo-code-from-paw/</link>
		
		<dc:creator><![CDATA[Greg O'Lone]]></dc:creator>
		<pubDate>Wed, 06 Jan 2016 00:00:00 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[PAW]]></category>
		<category><![CDATA[REST]]></category>
		<guid isPermaLink="false">http://blogtemp.xojo.com/2016/01/06/generating-xojo-code-from-paw/</guid>

					<description><![CDATA[Easy HTTP RESTful requests in Xojo and Paw]]></description>
										<content:encoded><![CDATA[<p>At Xojo, we work with a lot of HTTP REST APIs. So many in fact that I&#8217;ve spent time creating custom test harnesses to make sure that whatever I was currently coding would be compatible as well as being a test suite just in case the API changed in some subtle way (whether it be a bug fix or an API refactor gone awry). The problem with the custom test harnesses is that they&#8217;re not very portable and you end up having to create a new one for each API that you interface with.</p>
<p><span id="more-274"></span></p>
<p>When we created the iOS app for XDC 2015 last spring, I decided to take a different route and try out a few of the commercial REST API clients to see if any of them would make my life easier. The one I settled on was <a href="https://luckymarmot.com/paw" target="_blank" rel="nofollow noopener">Paw from LuckyMarmot</a>, primarily for its support of extensions written in JavaScript.</p>
<p><img loading="lazy" decoding="async" style="display: block; margin-left: auto; margin-right: auto;" title="PAW.png" src="https://blog.xojo.com/wp-content/uploads/2016/01/PAW.pngt1466486449161ampwidth253ampheight268" sizes="auto, (max-width: 253px) 100vw, 253px" alt="PAW.png" width="253" height="268" /></p>
<p>There is a <a href="https://luckymarmot.com/paw/extensions/" target="_blank" rel="nofollow noopener">small library</a> of extensions available on the Paw website, most of which are for code examples and that got me thinking&#8230; why not have examples of the request in Xojo code, both old and new framework so that I don&#8217;t need to do that by hand every time.</p>
<p><strong>Examples</strong></p>
<p>For the sake of this example, let&#8217;s say that we&#8217;re making a request to login to a fictitious API. The URL of this request is https://www.example.com/api/login, it expects that you will pass the username (name) and password (1234) as URL parameters and that a preshared key is to be included in the body of the request as JSON.</p>
<p>Paw comes with an extension for creating cURL requests and the output of that extension looks like this:</p>
<pre>curl -X "GET" "https://www.example.com/api/login?username=name&amp;password=1234" 
 -H "Content-Type: application/json" 
 -d "{"preshared-key":"QU^k9h36zdF8nx7Y"}"</pre>
<p>Using our Paw extensions, the Old Framework Xojo extension generates code that looks like this:</p>
<pre>// Login (Old Framework)

// Set up the socket
dim h as new HTTPSecureSocket
h.Secure = True
h.ConnectionType = h.TLSv12
h.setRequestHeader("Content-Type","application/json")

// JSON
Dim js As New JSONItem
js.Value("preshared-key") = "QU^k9h36zdF8nx7Y"

// Convert Dictionary to JSON Text
Dim data As String = js.toString()

// Assign to the Request's Content
h.SetRequestContent(data,"application/json")

// Set the URL
dim url as string = "https://www.example.com/api/login?username=name&amp;password=1234"

// Send Synchronous Request
dim s as string = h.SendRequest("GET",url,30)</pre>
<p>If you&#8217;re using the new framework extension, it generates code that looks like this:</p>
<pre>// Login (New Framework)

// Set up the socket
// "mySocket" should be a property stored elsewhere so it will not go out of scope
mySocket = new Xojo.Net.HTTPSocket
mySocket.RequestHeader("Content-Type") = "application/json"

// JSON
Dim d As New Dictionary
d.Value("preshared-key") = "QU^k9h36zdF8nx7Y"

// Convert Dictionary to JSON Text
Dim json As Text = Xojo.Data.GenerateJSON(d)

// Convert Text to Memoryblock
Dim data As Xojo.Core.MemoryBlock = Xojo.Core.TextEncoding.UTF8.ConvertTextToData(json)

// Assign to the Request's Content
mySocket.SetRequestContent(data,"application/json")

// Set the URL
dim url as Text = "https://www.example.com/api/login?username=name&amp;password=1234"

// Send Asynchronous Request
mySocket.Send("GET",url)</pre>
<p>These extensions are available for download using the link below. Once downloaded, extract the folders into the Paw Extensions folder which you can reach by going to the Paw menu and selecting Extensions-&gt;Open Extensions Directory. Once they&#8217;re in there, you can make them available by selecting Extensions-&gt;Reload All Extensions.</p>
<p>Versions for the Classic Framework and Xojo Framework are available on GitHub:</p>
<ul>
<li><a href="https://github.com/xojo/Paw-XojoClassicGenerator">Paw Extension for HTTPSocket</a></li>
<li><a href="https://github.com/xojo/Paw-XojoiOSGenerator">Paw Extension for Xojo.Net.HTTPSocket</a></li>
<li><a href="https://github.com/xojo/Paw-XojoURLConnectionGenerator">Paw Extension for URLConnection</a></li>
</ul>
<p><strong>CONCLUSION:</strong></p>
<p>Paw is an excellent tool for storing and managing API configurations and examples, plus adding the ability to copy and paste Xojo HTTP socket code makes it an even better part of your library if you work with a lot of HTTP RESTful APIs.<!-- end HubSpot Call-to-Action Code --></p>
<hr />
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>HTMLViewer Engines on Windows</title>
		<link>https://blog.xojo.com/2015/10/12/htmlviewer-engines-on-windows/</link>
		
		<dc:creator><![CDATA[Greg O'Lone]]></dc:creator>
		<pubDate>Mon, 12 Oct 2015 00:00:00 +0000</pubDate>
				<category><![CDATA[Windows]]></category>
		<category><![CDATA[HTMLViewer]]></category>
		<guid isPermaLink="false">http://blogtemp.xojo.com/2015/10/12/htmlviewer-engines-on-windows/</guid>

					<description><![CDATA[HTMLViewer on the desktop has two engines that you can select from, Native and Webkit. ]]></description>
										<content:encoded><![CDATA[<p>HTMLViewer on the desktop has two engines that you can select from, Native and Webkit. Native uses the built-in browser engine on each platform &#8211; Webkit on OS X, Internet Explorer on Windows, and Webkit on Linux, if it&#8217;s installed. If you select &#8220;Webkit&#8221;, the Chrome Embedded Browser libraries are included with your built app and HTMLViewer will use that instead. There are pros and cons to each, but usually the reason people choose WebKit over Native on Windows is because choosing Native gets you whatever the minimum version of Internet Explorer is for a particular OS. This means:</p>
<p><span id="more-246"></span></p>
<table style="margin-left: auto; margin-right: auto;" border="0" width="300" cellspacing="0" cellpadding="4">
<tbody>
<tr>
<td width="99"></td>
<td style="text-align: center;" width="90">Installed</td>
<td style="text-align: center;" width="89">Latest</td>
</tr>
<tr>
<td style="text-align: right;">XP</td>
<td style="text-align: center;">6</td>
<td style="text-align: center;">8</td>
</tr>
<tr>
<td style="text-align: right;">Vista</td>
<td style="text-align: center;">7</td>
<td style="text-align: center;">9</td>
</tr>
<tr>
<td style="text-align: right;">Windows 7</td>
<td style="text-align: center;">8</td>
<td style="text-align: center;">11</td>
</tr>
<tr>
<td style="text-align: right;">Windows 8</td>
<td style="text-align: center;">10</td>
<td style="text-align: center;">11</td>
</tr>
<tr>
<td style="text-align: right;">Windows 8.1</td>
<td style="text-align: center;">11</td>
<td style="text-align: center;">11</td>
</tr>
<tr>
<td style="text-align: right;">Windows 10</td>
<td style="text-align: center;">Edge</td>
<td style="text-align: center;">Edge</td>
</tr>
</tbody>
</table>
<p>Unfortunately this means that you&#8217;re often working with an engine that&#8217;s <em>way</em> out of date and it makes using the HTMLViewer as a control a real pain if you want to use any relatively new technologies.</p>
<p>There have been a few ideas to fix this over the years, but the most reliable solution I&#8217;ve seen has been to modify the registry and tell Windows what version of IE you want to use. Problems include: you can&#8217;t really expect an end user to do something like that; it can be risky to edit the registry if you don&#8217;t know what you&#8217;re doing; and most corporate users are locked out of the registry for that reason anyway.</p>
<p><strong>Now for a better way</strong></p>
<p>If you have control over the content being displayed, that is, you have the ability to modify the HTML being displayed, there is a way for you to get Windows to use a newer engine. You&#8217;ll need to add a very specific tag to your html within the &lt;head&gt; section of the page. You can do this one of two ways:</p>
<pre>&lt;meta http-equiv="X-UA-Compatible" content="IE=edge" /&gt;</pre>
<p>This version will tell Windows to use the latest engine it has available. If IE11 is installed, you&#8217;ll get the IE11 engine.</p>
<pre>&lt;meta http-equiv="X-UA-Compatible" content="IE=8" /&gt;</pre>
<p>This version tells Windows to use a very specific version of the engine. If you have IE11 installed, it will still use the IE8 engine. Looking for more tips for Xojo on Windows?</p>
<p><span id="hs-cta-wrapper-ee3c17a9-e8c9-4b5d-92ea-421a48777319" class="hs-cta-wrapper"><span id="hs-cta-ee3c17a9-e8c9-4b5d-92ea-421a48777319" class="hs-cta-node hs-cta-ee3c17a9-e8c9-4b5d-92ea-421a48777319"> <!-- [if lte IE 8]>


<div id="hs-cta-ie-element"></div>


<![endif]--> <a href="http://blog.xojo.com/2014/06/12/creating-installers-for-windows-apps/" target="_blank" rel="noopener"><img loading="lazy" decoding="async" id="hs-cta-img-ee3c17a9-e8c9-4b5d-92ea-421a48777319" class="hs-cta-img aligncenter" style="border-width: 0px; margin: 0 auto; display: block; margin-top: 20px; margin-bottom: 20px;" src="https://blog.xojo.com/wp-content/uploads/2015/02/ee3c17a9-e8c9-4b5d-92ea-421a48777319.png" alt="Xojo Windows" width="611" height="108" align="middle" /></a></span></span> <!-- end HubSpot Call-to-Action Code --></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Xojo Cloud Databases: Add, Connect &#038; Manage</title>
		<link>https://blog.xojo.com/2015/03/19/xojo-cloud-databases-add-connect-manage/</link>
		
		<dc:creator><![CDATA[Greg O'Lone]]></dc:creator>
		<pubDate>Thu, 19 Mar 2015 00:00:00 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">http://blogtemp.xojo.com/2015/03/19/xojo-cloud-databases-add-connect-manage/</guid>

					<description><![CDATA[Xojo Cloud Databases: Add, Connect &#038; Manage]]></description>
										<content:encoded><![CDATA[<p>One of the most popular Xojo Cloud feature requests was to add database support. On Tuesday Feb 10th, we added MySQL and Postgres databases for Xojo Cloud. In addition to having a database server right on your Xojo Cloud server, we have also enabled the creation of <a title="Link to Wikipedia" href="http://en.wikipedia.org/wiki/Tunneling_protocol" target="_blank" rel="noopener noreferrer">SSH Tunnels</a> so you can connect directly to the databases using a 3rd party management tool.</p>
<p><span id="more-195"></span></p>
<h3>Adding a Database</h3>
<p>Adding a database server to your Xojo Cloud server is easy! Just go to your Xojo Cloud control panel and click &#8220;Enable MySQL&#8221; or &#8220;Enable PgSQL.&#8221; In a moment, you will be presented with a username and password. That&#8217;s it!</p>
<h3>Connecting to a Database from a Xojo Cloud app:</h3>
<p>Connecting to the database server is just as easy:</p>
<pre>Dim db as new PostgreSQLDatabase // (or MySQLDatabase)
db.username = "username"
db.password = "password"
db.host = "localhost" // Use "127.0.0.1" for MySQLDatabase
db.port = 5432 // 3306 for MySQL
db.databasename = "your database name"
if db.connect then
  // You're connected!
end if</pre>
<p>Note the entry for Host. Your database is <em>only</em> accessible from the server itself. Even if you open a port in the firewall, neither of the database engines (MySQL or PostgreSQL) are listening on the addresses for the server&#8217;s IP addresses.</p>
<h3>Connecting to a Database from Somewhere Else</h3>
<p>Up to now, everything&#8217;s been very straightforward, but what happens if you need to access the database from your local machine for testing? What if you want to use a database management tool like pgAdmin, MySQL Workbench or any of the many commercial management tools out there? This is where the power of SSH tunnels come into play.</p>
<p>Before I show you how to make an SSH tunnel, lets talk a little about what they are. An SSH tunnel is a secure connection, between your computer and another (in this case your Xojo Cloud server) which is used for transmitting data on a particular port. In essence, it allows us to create a private connection through the internet which allows you to see into your server on the other end and connect to a particular service there.</p>
<p>To create a tunnel between your computer and your Xojo Cloud server, you first need to turn on the tunnel capability on your server. Go to your control panel and click the &#8220;Enable Tunnel&#8221; button. You will be presented with a username and a password which you will use later for establishing the connection.</p>
<h3>Connecting a Database Management Tool</h3>
<p>Most of the database server management tools have the capability to connect using an SSH tunnel. In the dialog used to set up the connection, look for something that says SSH or SSH Tunnel. In most cases, you will need to fill out four fields:</p>
<ul>
<li>Host Name or IP Address &#8211; Enter the IP address for your Xojo Cloud server</li>
<li>Port &#8211; Enter 22. This is the SSH port number.</li>
<li>User Name &#8211; Enter the user name that was provided to you in the Xojo Cloud control panel when setting up the tunnel.</li>
<li>Password &#8211; Enter the password that was provided to you in the Xojo Cloud control panel when setting up the tunnel.</li>
</ul>
<p>Now, as far as setting up the connection to the database itself, you will have another set of fields to fill out:</p>
<ul>
<li>Host Name or IP Address &#8211; Enter &#8220;localhost&#8221;*</li>
<li>Port &#8211; 5432 for PostgreSQL, 3306 for MySQL</li>
<li>Database &#8211; Enter the user name that was provided to you in the Xojo Cloud control panel when setting up the database server.</li>
<li>User Name &#8211; Enter the user name that was provided to you in the Xojo Cloud control panel when setting up the database server.</li>
<li>Password &#8211; Enter the password that was provided to you in the Xojo Cloud control panel when setting up the database server.</li>
</ul>
<p>* The reason you enter localhost for the server name is that you want to connect to your side of the tunnel. SSH will do the job of hooking things up on the other end for you.</p>
<p>Voila! You can now connect to your database server to create and edit users, databases, tables, etc.</p>
<h3>Manually Creating a Tunnel</h3>
<p>Sometimes you need to create a tunnel outside of a management app. This is a great way of testing your app locally while still having it connected to the actual database server. If you are using OS X or Linux, you can just open a Terminal window:</p>
<p>On OS X and Linux the command is quite simple:</p>
<pre>ssh -L 5432:localhost:5432 dbadmin@ipaddress -N</pre>
<p>If you want to see more information about the tunnel and when it is in use, add <strong>-v</strong> at the end of that command to use it in verbose mode.</p>
<p>If you are using Windows, I suggest using a program like <a title="PuTTY" href="http://www.chiark.greenend.org.uk/~sgtatham/putty/" target="_blank" rel="noopener noreferrer">PuTTY</a>. There are a number of tutorials available on the internet, just put <strong>putty ssh tunnel</strong> into your favorite search engine. [<a href="https://blog.xojo.com/2020/10/29/setting-up-putty-to-create-a-ssh-tunnel-from-windows-to-xojo-cloud/">Xojo Blog Post</a>: Setting up puTTY to create a SSH tunnel from Windows to Xojo Cloud]</p>
<p>That&#8217;s it! Connecting a web app to a database server has never been easier and we hope this will encourage you to build bigger and better web apps!</p>
<p>For more information, you can also refer to the <a href="https://documentation.xojo.com/topics/xojo_cloud/introduction_to_xojo_cloud.html_Control_Panel#PostgreSQL_and_MySQL_Usage">Xojo Cloud Databases topic in the docs</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
