<?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>Xojo Cloud &#8211; Xojo Programming Blog</title>
	<atom:link href="https://blog.xojo.com/category/cross-platform/xojo-cloud/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.xojo.com</link>
	<description>Blog about the Xojo programming language and IDE</description>
	<lastBuildDate>Mon, 18 Aug 2025 20:40:26 +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>Xojo Cloud: More Than Web App Hosting</title>
		<link>https://blog.xojo.com/2024/08/15/xojo-cloud-more-than-web-app-hosting/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Thu, 15 Aug 2024 22:59:40 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[App Hosting]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[Push Notifications]]></category>
		<category><![CDATA[SFTP]]></category>
		<category><![CDATA[SSH]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Web Service]]></category>
		<category><![CDATA[webdev]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13449</guid>

					<description><![CDATA[What better way to celebrate 10 years of Xojo Cloud than bragging about all the things it can do! When you think of Xojo Cloud,&#8230;]]></description>
										<content:encoded><![CDATA[
<p>What better way to celebrate 10 years of Xojo Cloud than bragging about all the things it can do! When you think of Xojo Cloud, you might think that it is for hosting Xojo web apps. And that&#8217;s true, Xojo Cloud continues to be the best and easiest way to host your Xojo web apps, but Xojo Cloud also offers several useful services for other types of apps.</p>



<h2 class="wp-block-heading">iOS Notifications</h2>



<p>Xojo Cloud can function as an <a href="https://developer.apple.com/documentation/usernotifications/sending-notification-requests-to-apns">Apple Push Notification system</a> (APNs) for handling iOS push notifications. This works with Xojo and non-Xojo iOS apps. All Xojo Cloud servers are pre-configured to <a href="https://documentation.xojo.com/topics/ios/sending_and_receiving_mobile_notifications.html#topics-ios-creating-notifications-on-the-user-s-mobile-device-using-xojo-cloud-to-send-remote-notifications">send remote notifications</a>. Unlike many other cloud hosts, there is no extra charge for this feature nor is there any limit as to how many notifications you can send.</p>



<p>To send remote notifications from your iOS app you&#8217;ll need to go to the Apple Developer website to do these tasks:</p>



<ol class="wp-block-list">
<li>Add the Push Notifications feature to the App ID.</li>



<li>Generate an Apple Push Services certificate.</li>
</ol>



<p>In Xojo you need to enable the Remote Notifications entitlement for your app in the Capabilities section of the iOS Build Settings Advanced tab.</p>



<p>The final step is to upload your Push Services certificate using the Xojo Cloud control panel.</p>



<p>With super-easy access and no limits for notifications, Xojo Cloud can serve as a great APNs for handling your iOS notification needs.</p>



<h2 class="wp-block-heading">Database Servers</h2>



<p>Most desktop apps use a database of some kind and many are client/server database apps that talk directly to the database server. With Xojo Cloud you can host PostgreSQL or MariaDB/MySQL database servers and connect to them using an SSH tunnel for security purposes.</p>



<p>Setting up a database server on your Xojo Cloud is as easy as checking a box in the control panel.</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="630" src="https://blog.xojo.com/wp-content/uploads/2024/08/image-1024x630.png" alt="" class="wp-image-13451" srcset="https://blog.xojo.com/wp-content/uploads/2024/08/image-1024x630.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/08/image-300x185.png 300w, https://blog.xojo.com/wp-content/uploads/2024/08/image-768x472.png 768w, https://blog.xojo.com/wp-content/uploads/2024/08/image.png 1398w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>You can turn on PostgreSQL or MySQL/MariaDB. If your Xojo Cloud server is large enough you could even do both.</p>



<p>If you want to access a database on Xojo Cloud from a desktop app, you will have to enable the SSH Tunnel and then connect to the tunnel from the computer. 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 specific port. In essence, it creates 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 a computer and your Xojo Cloud server, you first need to turn on the tunnel capability on your Xojo Cloud server. Go to your control panel and click the &#8220;SSH Tunnel&#8221; checkbox. You will be presented with a generated username and a password which you will use later for establishing the connection.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="694" height="302" src="https://blog.xojo.com/wp-content/uploads/2024/08/image-1.png" alt="" class="wp-image-13453" srcset="https://blog.xojo.com/wp-content/uploads/2024/08/image-1.png 694w, https://blog.xojo.com/wp-content/uploads/2024/08/image-1-300x131.png 300w" sizes="(max-width: 694px) 100vw, 694px" /></figure>



<p>On macOS and Linux, you can use a terminal command to access the tunnel (replace username and ipaddress as appropriate; you&#8217;ll be prompted for the password).</p>



<p>Use this command to tunnel to PostgreSQL:</p>



<pre class="wp-block-code"><code>ssh -L 5432:localhost:5432 username@ipaddress -N</code></pre>



<p>Use this command to tunnel to MySQL:</p>



<pre class="wp-block-code"><code>ssh -L 3306:localhost:3306 username@ipaddress -N</code></pre>



<p>If you are using Windows, you will need to use an external app such as PuTTY. There are a number of tutorials available on the internet, just put “putty ssh tunnel” into your favorite search engine.</p>



<p>With the tunnel in place you connect to the database as if it were local to the computer. This works with anything, not just Xojo apps.</p>



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



<p>Xojo Cloud offers SFTP (Secure File Transfer Protocol) for file transfer. SFTP is a secure variant of FTP which transmits files over the internet using strong encryption. That way you don&#8217;t have to worry about anyone intercepting your username and password or your files as they&#8217;re sent to or from your server.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>When choosing a client, keep in mind that SFTP is different than FTPS or FTP w/ SSL. They are not interchangeable with one another.</p>
</blockquote>



<p>Once you enable SFTP in the Control Panel, you&#8217;ll be presented with a dialog showing a generated username and password.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="447" src="https://blog.xojo.com/wp-content/uploads/2024/08/image-2-1024x447.png" alt="" class="wp-image-13454" srcset="https://blog.xojo.com/wp-content/uploads/2024/08/image-2-1024x447.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/08/image-2-300x131.png 300w, https://blog.xojo.com/wp-content/uploads/2024/08/image-2-768x335.png 768w, https://blog.xojo.com/wp-content/uploads/2024/08/image-2.png 1186w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>You can now connect using your favorite SFTP client. If you don&#8217;t have one, there are a number of free and paid options available including:</p>



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



<li>Transmit</li>



<li>FileZilla</li>



<li>CyberDuck</li>
</ul>



<p>Having a place to store files online is always handy and can be useful when needing to share files with others without having to rely on services such as DropBox.</p>



<h2 class="wp-block-heading">Web Services</h2>



<p>OK, a web service is technically a Xojo web app but it is really an API that is meant to be used by other apps, often desktop or mobile apps. Since a web service doesn’t have any actual UI, you don’t really need to learn how to use the majority of the Xojo Web framework.</p>



<p>Instead you basically add code to the <a href="https://documentation.xojo.com/api/web/webapplication.html#webapplication-handleurl">App.HandleURL</a> event to route web service API calls to do specific tasks and then return the results, usually as JSON for the client app to handle.</p>



<p>A web service can be a great way to consolidate code that will be used by desktop and mobile apps, for example.</p>



<p>For example, you could create a Web Service that talks to a database server (such as one of the ones available in Xojo Cloud itself). Your Desktop and Mobile apps can use the same web service to work with the database. All your database-specific code lives in the web service and the client apps make requests and display results.</p>



<p>This is a very common design pattern these days and is a necessary one if you want a mobile app to talk to a database server.</p>



<p>If you want to learn more about web services, here&#8217;s a fun webinar to check out:</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Using Xojo and the Star Wars API" width="500" height="281" src="https://www.youtube.com/embed/hwhkZtP6fA8?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<p>Learn more about <a href="https://xojo.com/cloud/">Xojo Cloud</a> today. Xojo Cloud servers start at $49/month, custom servers with more RAM, storage, and virtual CPUs are available. The best way to host your Xojo web apps is so much more than just hosting web apps!</p>



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



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

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

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

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

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The One Person Framework for the Rest of Us</title>
		<link>https://blog.xojo.com/2024/05/02/the-one-person-framework-for-the-rest-of-us/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Thu, 02 May 2024 14:00:00 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Development Tools]]></category>
		<category><![CDATA[Enterprise Software]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Object-Oriented]]></category>
		<category><![CDATA[One-Person Framework]]></category>
		<category><![CDATA[OOP]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Small Business]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=12882</guid>

					<description><![CDATA[The technology and development world is always changing. First released in 1998, Xojo&#8217;s longevity is a testament to its ability and willingness to adapt from&#8230;]]></description>
										<content:encoded><![CDATA[
<p>The technology and development world is always changing. First released in 1998, Xojo&#8217;s longevity is a testament to its ability and willingness to adapt from the early days of desktop apps, to web apps and on to mobile apps.</p>



<p>Throughout that time, software development has generally become more difficult with developers having to learn a wide variety of tools and programming languages, many of which are the hot thing for a short while and then disappear afterwards for the next hot new thing as the cycle repeats.</p>



<p>Up until recently this was not as big a deal for tech companies because they could just hire their way out of the problem. Teams got big and bloated, often because the tools being used were large, complex, rapidly changing and difficult to learn. So the solution, in opposition of the <a href="https://en.wikipedia.org/wiki/The_Mythical_Man-Month">Mythical Man Month</a>, was to throw more people at it. This was feasible because of 0% interest rates and the relative ease of raising capital.</p>



<figure class="wp-block-image"><a href="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4c4ae90-9d8d-4b2a-8301-2ee4be611df7_1152x640.jpeg" target="_blank" rel="noreferrer noopener"><img decoding="async" src="https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff4c4ae90-9d8d-4b2a-8301-2ee4be611df7_1152x640.jpeg" alt=""/></a></figure>



<p>But that era is over. Interest rates are no longer historically low and raising capital for companies is now much harder and less desirable than it once was. This means technology companies are reducing staff and hiring more judiciously. Fewer people now have to do more with less.</p>



<p>The idea of a “one person framework” is that there should be a way for a single developer to create software using just one development framework. This is not a new idea, but it is being talked about again because of these recent changes with how technology companies work. In many ways, Xojo is the original one person framework. From its inception, with inspiration from Visual Basic, Xojo let you make complete apps more efficiently without having to also learn other tools, languages or frameworks.</p>



<p>So what can Xojo, as a one person framework, do for you? Xojo lets you build most of the apps your company is likely to need, using only Xojo itself and its easy-to learn object-oriented programming language (which is similar to Visual Basic and Python, languages that many people already are familiar with). Xojo is a cross-platform, integrated development environment (IDE) that combines an object-oriented programming language, visual designer, code editor, debugger and more into one tool and one framework.</p>



<p>With Xojo you can make apps for most of the commonly used platforms that your business is likely to need.</p>



<p><strong>Desktop Apps</strong></p>



<p>Xojo has been a great way to make desktop apps since its inception in 1998. Unlike Java, Electron or other frameworks you’ve seen throughout the years, Xojo makes native apps and can do so for the major desktop platforms: Windows, macOS and Linux. Yes, that includes native ARM and x86 apps as well.</p>



<p>With a single project, you can click one button to have Xojo build separate native apps for each of those platforms. To further drive that point home, the Xojo IDE itself is a desktop app made with Xojo that runs on Windows, macOS and Linux.</p>



<p>With Xojo you have access to many commonly-used controls and the Xojo framework with support for databases, JSON, XML, RegEx, Zip/Unzip, networking and so much more.</p>



<p><strong>Web Apps</strong></p>



<p>Since 2010, Xojo has been able to make web apps. Xojo uses a somewhat unique approach to web apps by running compiled code on the web server. This code communicates to the app running on the web browser using an internal JavaScript framework and Bootstrap for the UI, which you don’t really need to worry about. It’s all handled automatically.</p>



<p>This approach is great for business purposes as it lets you make web apps using a development pattern that is very similar to what is used to make desktop apps.</p>



<p>If you don&#8217;t want to deal with the hassle of managing your own web app server, Xojo even offers Xojo Cloud as a fully managed web hosting service with 1-click deployment of your Xojo web apps.</p>



<p><strong>Mobile Apps</strong></p>



<p>Mobile support first appeared for iOS in 2013 and Android support was recently added in 2023. Using Xojo to make native mobile apps that can be deployed in their respective app stores is yet another way Xojo can help one person make more apps.</p>



<p>A developer that already knows how to use Xojo can jump right into mobile development without having to learn yet another IDE and programming language.</p>



<p><strong>Console Apps</strong></p>



<p>Console apps are text apps that run from the command line. These app are great for automating internal processes or other command-line tools. You can even build Console apps that communicate with other console apps to build a chain of tools for processing or converting data, for example.</p>



<h4 class="wp-block-heading">Xojo Framework</h4>



<p>A single person can create all of the above types of apps because Xojo uses the same programming language for all of them. And as mentioned above, the Xojo framework has many built-in features and is broadly compatible across all the different project types. There are differences, of course, but we strive for consistency and compatibility.</p>



<p>For just a few of its many capabilities, all platforms have the same framework classes and methods for things such as Dictionary, Set, URLConnection, files, SQLite, and most graphics. And speaking of examples, Xojo includes over 400 example projects from which to learn.</p>



<figure class="wp-block-image is-resized"><a href="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62cdb62a-4fe8-4d7a-ac61-cf301408c2dc_1152x640.jpeg" target="_blank" rel="noreferrer noopener"><img decoding="async" src="https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62cdb62a-4fe8-4d7a-ac61-cf301408c2dc_1152x640.jpeg" alt="" style="width:915px;height:auto"/></a></figure>



<h2 class="wp-block-heading">Could Xojo Work For You?</h2>



<p>As you should now realize, a single developer using Xojo could reasonably create a desktop app (for Windows, macOS and Linux), a web app, and mobile apps for iOS and Android. If you previously had multiple teams of multiple people creating that many apps, then Xojo could really save you a lot of money and time.</p>



<p>Will you use Xojo to make the next Photoshop, FaceBook, Excel or Google Docs clone? Perhaps not, but most companies don&#8217;t create those types of apps. Xojo does a lot, but it does not and cannot do everything. There is a limit to what any single framework can do, otherwise it becomes too large for its own good, collapsing under its own weight.</p>



<p>Instead, most businesses have much different needs and often require specially created software. For business apps, especially bespoke small-business apps, Xojo can often be an ideal solution by allowing apps to be created faster, more easily and at less cost than can be done with other tools. This saves you money and time, both of which are in short supply these days.</p>



<p><a href="https://www.xojo.com/download/">Xojo is free</a> for learning, development and testing! Give it a spin to see what it can do for you.</p>



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



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

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

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

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

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Popovers for Xojo Desktop, Web and iOS</title>
		<link>https://blog.xojo.com/2024/03/26/popovers-for-xojo-desktop-web-and-ios/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Tue, 26 Mar 2024 15:27:47 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[2024r1]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Popovers]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[User Interface]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=12707</guid>

					<description><![CDATA[Starting with Xojo 2024r1 there's a new Window type in Xojo's UI/UX bag: Popovers. Popovers are kind of a Modal window with a more transient behavior and associated with a Parent control. A Popover will display the chosen content or layout, the same as when you design the user interface of a window or a Container control that will be included as part of another more complex design or displayed at runtime.]]></description>
										<content:encoded><![CDATA[
<p>Starting with Xojo 2024r1 there&#8217;s a new Window type in Xojo&#8217;s UI/UX bag: Popovers. Popovers are kind of a Modal window with a more transient behavior and associated with a Parent control. A Popover will display the chosen content or layout, the same as when you design the user interface of a window or a Container control that will be included as part of another more complex design or displayed at runtime.</p>



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


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1024" height="558" src="https://blog.xojo.com/wp-content/uploads/2024/03/Popover-1024x558.png" alt="" class="wp-image-12708" srcset="https://blog.xojo.com/wp-content/uploads/2024/03/Popover-1024x558.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/03/Popover-300x164.png 300w, https://blog.xojo.com/wp-content/uploads/2024/03/Popover-768x419.png 768w, https://blog.xojo.com/wp-content/uploads/2024/03/Popover-1536x837.png 1536w, https://blog.xojo.com/wp-content/uploads/2024/03/Popover-2048x1116.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<p>And what do we mean by the transitory character of Popover windows? Well, and here comes one of the first differences from Modal windows. When a Popover is visible and the user clicks or taps on any other element of the graphical interface not contained in the Popover itself it will close, hence transitory. So, you don&#8217;t have to include the typical &#8220;Close window&#8221; button in a Popover (though you can), since it will close when the user clicks outside of it, i.e. when the Popover loses focus.</p>



<h3 class="wp-block-heading">Where are the Popover Window Contents?</h3>



<p>Where do you define the content displayed in a Popover window? While in your Web app, you can do it on any Container control added to the project. In the case of Desktop and iOS apps, you can do it on either the designs of a Container Control or any Window or Screen added to the project.</p>



<p>For example, here you can see that the content shown as a Popover in the previous screenshot is actually that of a Window (Window2) added to the project:</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1024" height="558" src="https://blog.xojo.com/wp-content/uploads/2024/03/PopoverUI-1024x558.png" alt="" class="wp-image-12709" srcset="https://blog.xojo.com/wp-content/uploads/2024/03/PopoverUI-1024x558.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/03/PopoverUI-300x163.png 300w, https://blog.xojo.com/wp-content/uploads/2024/03/PopoverUI-768x418.png 768w, https://blog.xojo.com/wp-content/uploads/2024/03/PopoverUI-1536x837.png 1536w, https://blog.xojo.com/wp-content/uploads/2024/03/PopoverUI-2048x1116.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<p>This introduces additional flexibility allowing your app&#8217;s logic to decide when to display a Window or Container instance as you have been doing until now, or display it as a Popover.</p>



<h3 class="wp-block-heading">Showing a Popover</h3>



<p>Displaying a Popover is very straightforward, whether it is created from a Container or a Window, the method is the same:</p>



<pre class="wp-block-preformatted">DesktopContainer.ShowPopover(parentControl As DesktopUIControl, facing As DesktopWindow.DisplaySides = DesktopWindow.DisplaySides.Bottom, detachable As Boolean = True)</pre>



<p>The explanation of the expected parameters is as follows:</p>



<ul class="wp-block-list">
<li><strong>ParentControl:</strong> The control that will act as the parent, or on which the Popover will be pointing to.</li>



<li><strong>Facing:</strong> The direction in which the Popover will point on the parent control; by default it will appear under the parent control, but you can use any of the values available in the DesktopWindow.DisplaySides enumerator (or the iOS equivalent).</li>



<li><strong>Detachable:</strong> This value only applies to macOS Popovers, since said operating system has the ability for the user to &#8220;detach&#8221; the Popover from the parent control as long as this value is defined as True. To detach, drag the Popover with the mouse cursor.</li>
</ul>



<p>Let&#8217;s say we have a window called Window2 and a button called MyButton. In the Pressed event of MyButton we can use the following lines of code to display Window2 as a Popover:</p>



<pre class="wp-block-preformatted">Var w As New Window2
w.ShowPopover(me)</pre>



<p>And that&#8217;s all!</p>



<figure class="wp-block-image is-style-default"><img loading="lazy" decoding="async" width="1280" height="720" src="https://blog.xojo.com/wp-content/uploads/2024/03/PopoverDettach.gif" alt="" class="wp-image-12710"/></figure>



<h3 class="wp-block-heading">Platform Differences</h3>



<p>In the previous section we already pointed out the first: macOS is the only operating system that acts on the value indicated in the Detachable parameter. But there are some other considerations to keep in mind so you don&#8217;t get caught off guard:</p>



<ul class="wp-block-list">
<li><strong>Beyond the limits.</strong> Although in Windows and macOS Popovers can exceed the limits of the window on which the parent control is located, the position of the popover in Linux is restricted to the limits of the window that contains the parent control. This is the same for iOS and for Web pages.</li>



<li><strong>iPhone and iPad.</strong> When a Popover is displayed on an iPhone, it will look like a modal window; while if the same application is run on an iPad, the appearance will be the typical one expected from Popovers: the window pointing to the parent control in the indicated direction.</li>



<li><strong>On the Web.</strong> The contents of a Popover are those defined in a Container control, while on the rest of the platforms you can use both Container controls and Windows / Screens.</li>
</ul>



<h3 class="wp-block-heading">Why the Popover doesn&#8217;t &#8220;point&#8221; in the configured direction?</h3>



<p>By default it will try to do so according to the value that has been set in the &#8220;facing&#8221; parameter, but if it does not find enough space on the margins of the screen, then it will be displayed on the next side of the parent control in which there is available space for display the Popover in its full width and height; This is true on macOS, Linux, Web and iOS.</p>



<h3 class="wp-block-heading">Can I reuse a Popover?</h3>



<p>No, You can not. Whether you use a Container control or a window as the source of the UI design to be displayed by the Popover, do not lose sight of the fact that the Popover is just another type of window; and therefore behaves as such. That is, once it is closed either because it has lost focus or because you have closed it explicitly through code invoking the Close method, all the displayed controls and the rest of the internal structures will be closed / invalidated, so that although the instance If a Popover is not Nil (because, for example, you keep a reference to the window or container instance used as the UI source), you will not be able to invoke the ShowPopover method again on said instance but you will have to create a new instance of the Container/ Window used as the source of the UI to be displayed by the Popover.</p>



<h3 class="wp-block-heading">How can I communicate with the UI elements contained in the Popover?</h3>



<p>You would do so just as you would do with any other type of window that you have been using so far in your Xojo projects.</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1280" height="720" src="https://blog.xojo.com/wp-content/uploads/2024/03/PopoverComm.gif" alt="" class="wp-image-12712"/></figure>
</div>


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



<p>Without a doubt, Popovers are a new way to improve the design of your apps&#8217; user interfaces, providing a more direct relationship between the user interface elements displayed in the Popover and the &#8220;parent&#8221; control in charge of displaying it. Furthermore, since you can use any window or container you want as the source of the UI to be displayed by the Popover, you will have greater flexibility about when you want to display them in a Popover or display them using any other of the available window types or, in the case of Containers, embedding them as part of other UI elements at runtime.</p>



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



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

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

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

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

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Simplicity and Security, Xojo Cloud is Ideal Hosting for Xojo Web Apps</title>
		<link>https://blog.xojo.com/2023/10/30/simplicity-and-security-xojo-cloud-is-ideal-hosting-for-xojo-web-apps/</link>
		
		<dc:creator><![CDATA[Xojo]]></dc:creator>
		<pubDate>Mon, 30 Oct 2023 16:00:00 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[App Hosting]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Security-Enhanced Linux]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[SSH]]></category>
		<category><![CDATA[SSL]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[webdev]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=11553</guid>

					<description><![CDATA[Xojo Cloud is the premier hosting solution for developers looking for a reliable, secure and high-performance hosting environment for Xojo web applications. Xojo Cloud is developed specifically for Xojo web applications and offers a range of benefits for you and your applications that make it worth the investment.]]></description>
										<content:encoded><![CDATA[
<p>Xojo Cloud is the premier hosting solution for developers looking for a reliable, secure and high-performance hosting environment for Xojo web applications. Xojo Cloud is developed specifically for Xojo web applications and offers a range of benefits for you and your applications that make it worth the investment.</p>



<p>Xojo Cloud is <strong>optimized for Xojo applications</strong>. It is specifically designed to provide the best possible performance and stability for Xojo web applications. We optimize Xojo Cloud for performance, so your web apps will run smoothly and seamlessly. You can even monitor server stats from within the Xojo IDE.</p>



<p>Xojo Cloud is <strong>focused on simplicity and ease of use</strong> and requires zero configuration. Designed with the Xojo developer in mind, Xojo Cloud&#8217;s Control Panel makes it easy to deploy and manage web applications. Purchase a server, open a web project in Xojo and click Deploy to upload and install to Xojo Cloud. Not just for web apps, Xojo Cloud includes Apple Push Notification server (APNs) support for your iOS apps. Set up SSL, PostrgeSQL, MySQL, SFTP and a SSH Tunnel with a click in the Xojo Cloud Control Panel (the Control Panel itself is a Xojo web app). The administration of a web server is a significant and constant task; Xojo Cloud allows you to leave that behind and focus on your projects.</p>



<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-large is-style-default"><img loading="lazy" decoding="async" width="1024" height="386" data-id="12082" src="https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Apps-Tab-1024x386.png" alt="Xojo Cloud Control Panel Apps Tab" class="wp-image-12082" srcset="https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Apps-Tab-1024x386.png 1024w, https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Apps-Tab-300x113.png 300w, https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Apps-Tab-768x289.png 768w, https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Apps-Tab-1536x579.png 1536w, https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Apps-Tab-2048x772.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-large is-style-default"><img loading="lazy" decoding="async" width="1024" height="384" data-id="12083" src="https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Options-Tab-1024x384.png" alt="Xojo Cloud Control Panel Options Tab" class="wp-image-12083" srcset="https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Options-Tab-1024x384.png 1024w, https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Options-Tab-300x112.png 300w, https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Options-Tab-768x288.png 768w, https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Options-Tab-1536x576.png 1536w, https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Options-Tab-2048x768.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</figure>



<p>We take security very seriously. Xojo Cloud <strong>offers advanced security features</strong> to protect your data from cyberthreats, including a smart firewall, intrusion and hacking detection and Security-Enhanced Linux. Unlike most hosting solutions that provide little to no security, each Xojo Cloud server is built with our state-of-the-art, industrial-strength, multi-tiered security system woven into its very core.&nbsp;</p>



<p>Additional features and benefits include daily automatic backups, load balancing and support from the Xojo team. With nine global hosting locations, you are able to host your Xojo web applications close to your users, for speed and an ideal overall experience. </p>



<div class="wp-block-columns are-vertically-aligned-top is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-vertically-aligned-top is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:100%">
<figure class="wp-block-image size-large is-style-default"><img loading="lazy" decoding="async" width="1024" height="576" src="https://blog.xojo.com/wp-content/uploads/2023/09/Add-a-heading-1024x576.png" alt="Xojo Cloud offers 3 packages offering options on RAM, storage and vCPU starting at $49/month. " class="wp-image-12078" srcset="https://blog.xojo.com/wp-content/uploads/2023/09/Add-a-heading-1024x576.png 1024w, https://blog.xojo.com/wp-content/uploads/2023/09/Add-a-heading-300x169.png 300w, https://blog.xojo.com/wp-content/uploads/2023/09/Add-a-heading-768x432.png 768w, https://blog.xojo.com/wp-content/uploads/2023/09/Add-a-heading-1536x864.png 1536w, https://blog.xojo.com/wp-content/uploads/2023/09/Add-a-heading.png 1600w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>
</div>



<p>In addition to the <a href="http://xojo.com/store/#cloud">standard options</a>, Xojo Cloud servers with more RAM, storage and Virtual CPUs are available. Contact&nbsp;<a href="mailto:hello@xojo.com">customer support</a>&nbsp;for details about personalized plans.&nbsp;</p>



<p>Whether you are a seasoned Xojo developer or just getting started, Xojo Cloud provides an intuitive and user-friendly hosting solution for Xojo web applications. Today is a good day to start using Xojo Cloud, visit our <a href="https://xojo.com/cloud/">website</a> to learn more or see the Xojo <a href="https://xojo.com/store/#cloud">Store</a> to pick your package and location.</p>



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

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

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

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

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>2022: Welcome Back!?</title>
		<link>https://blog.xojo.com/2022/12/13/2022-welcome-back/</link>
		
		<dc:creator><![CDATA[Alyssa Foley]]></dc:creator>
		<pubDate>Tue, 13 Dec 2022 11:00:00 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[XDC]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[Code Assistants]]></category>
		<category><![CDATA[Code Editor]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Framework]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=10967</guid>

					<description><![CDATA[Does anyone else feel like 2022 is the first year in many years where we have gotten back together, in-person, for big events, small get-togethers, travel and even the daily office grind? Whether that is the right thing to have done or not, it seems that is what many of us did in 2022. Though we all tried new things to stay connected over the past few years (Zoom-fatigue anyone?), there's nothing like seeing an old friend after years apart.]]></description>
										<content:encoded><![CDATA[
<p>Does anyone else feel like 2022 is the first year in many years where we have gotten back together, in-person, for big events, small get-togethers, travel and even the daily office grind? Whether that is the right thing to have done or not, it seems that is what many of us did in 2022. Though we all tried new things to stay connected over the past few years (Zoom-fatigue anyone?), there&#8217;s nothing like seeing an old friend after years apart.</p>



<p>Xojo&#8217;s team was all vaxxed-up and so happy to get together in Nashville for #XDC2022. Tennessee&#8217;s Music City was a delightful backdrop for the first in-person Xojo event since 2019. Check out the short highlights <a href="https://youtu.be/t8xpWVL5pEM">video</a> from Nashville and then join us for #XDC2023 in London, UK. You can <a href="http://xojo.com/xdc/london/index.html">register</a> here.</p>



<p>This year the Xojo team and community welcomed a new Xojo engineer, Ricardo Cruz. Ricardo has applied his expertise to advance and improve Xojo Web. To quote one of Xojo&#8217;s engineers, &#8220;Ricardo coming in has been awesome,&#8221; a sentiment echoed on the Forum and the community in Nashville. </p>



<p>Xojo Web has come so far this year. Control reliability has improved, IDE previews have improved and reconnections have really improved. The web framework can now more often reconnect back to the same web session if it still exists. This is one of the things Ricardo is really happy about, &#8220;You can switch to your email app in your mobile, copy something to the clipboard, come back to the web app and it is still there, ready to continue.&#8221; Under the hood, some dependencies received updates, like jQuery. As a user, you don&#8217;t have to do anything, just use the new Xojo version! Try to tell that to another web developer, that&#8217;s sci-fi outside of Xojo. Also, thanks to the community, the memory and CPU usage continues to be improved release after release. &#8220;Honestly from my perspective it is just fun to play with little projects in it because it has really matured,&#8221; says Xojo&#8217;s Director of Engineering, Travis Hill. </p>



<p>Speaking of technical achievements, this year we added two new targets to Xojo: Windows on ARM 64 and Linux on ARM 64. On Windows, you can natively deploy to ARM-based tablets and laptops that run Windows. On Linux, you can deploy to 64-bit Raspberry Pi which can address significantly more RAM than 32-bit versions. </p>



<p>We built the <a href="https://www.xojo.com/cloud/">Xojo Cloud</a> Control Panel with an updated version of Xojo, and thanks to some Web framework improvements the controls now stay more responsive under load. Plus we&#8217;ve added Xojo Cloud servers in Sydney, Australia for web developers in Australia and New Zealand. We also continued improving and testing our upcoming support for Android, which is now feature complete and awaiting some remaining bug fixes before we make it available to everyone.</p>



<p>In addition, we want to brag about a few technical improvements, including the numerous <a href="https://blog.xojo.com/tag/pdf/">PDF updates</a> implemented by Xojo Engineer and now PDF expert, Javier Menéndez. Also there is the option to generate&nbsp;Program Database <a href="https://blog.xojo.com/2022/07/25/what-the-pdb-is-this/">(PDB)</a>&nbsp;files on Windows and improved <a href="https://blog.xojo.com/2022/10/12/improving-multi-monitor-support-on-windows/">multi-monitor support</a> shepherded by Xojo Engineer William Yu. The list goes on: <a href="https://blog.xojo.com/2022/04/05/using-the-new-user-code-assistants-feature/">Code Assistants</a>, <a href="https://blog.xojo.com/2022/04/05/on-device-ios-debugging-in-xojo/">on-device debugging in iOS</a>, new <a href="https://documentation.xojo.com/">Xojo Documentation</a> site, adding <a href="https://blog.xojo.com/2022/01/07/desktop-adding-controls-at-runtime/">Controls at runtime</a>, loading speed faster for big projects, and the time team-Lefebvre built a <a href="https://blog.xojo.com/2022/03/03/a-web-app-to-calculate-combat-rolls-in-twilight-imperium/">web app</a> to Calculate Combat Rolls in Twilight Imperium&#8230;</p>



<p>Inside Xojo we improved a lot too. Besides welcoming Ricardo and his beard to the team, we migrated Xojo&#8217;s bug and feature reporting platform from the internally managed Feedback tool to the much loved <a href="https://tracker.xojo.com">Issues</a>. This has increased productivity, streamlined work flow, made it easier to search and find, comment, edit. The team couldn&#8217;t be happier!</p>



<p>This year also included Xojo&#8217;s first Bug Bash in a long time! During the Bug Bash, Xojo&#8217;s <a href="https://blog.xojo.com/2022/10/12/bountiful-bug-bashing/">Code Editor</a> got some much needed improvements resulting in noticeably faster updates. Plus updates to the Syntax Help Area thanks to Xojo Engineer and retro-computing expert, Paul Lefebvre. Besides the very real smashing of 100 bugs, the bash had the unintended consequence of giving the engineers an opportunity to work on things they don&#8217;t normally work on, giving engineers opportunities to collaborate and better solve things.</p>



<p>All in all, 2022 was a year of forward movement for Xojo. Which has us leaning into 2023 with a lot of excitement and expectation. Our team is committed to continuing to make Xojo the best cross-platform development tool and we thank you for being part of Xojo&#8217;s continued success!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Xojo Cloud is now in Sydney!</title>
		<link>https://blog.xojo.com/2022/12/12/xojo-cloud-is-now-in-sydney/</link>
		
		<dc:creator><![CDATA[Jason Parsley]]></dc:creator>
		<pubDate>Mon, 12 Dec 2022 23:30:21 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[App Hosting]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[webdev]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=11084</guid>

					<description><![CDATA[We're happy to add Sydney, Australia to the worldwide locations of Xojo Cloud servers. That makes nine cities that you can host your Xojo Cloud web apps in. Offering worldwide coverage for Xojo Cloud makes it easier to get your Xojo web applications close to the users that are using them, improving the speed and overall experience for your users.]]></description>
										<content:encoded><![CDATA[
<p>We&#8217;re happy to add Sydney, Australia to the worldwide locations of Xojo Cloud servers. That makes nine cities that you can host your <a rel="noreferrer noopener" href="https://www.xojo.com/cloud" target="_blank">Xojo Cloud</a> web apps in. Offering worldwide coverage for Xojo Cloud makes it easier to get your Xojo web applications close to the users that are using them, improving the speed and overall experience for your users.</p>



<p>Xojo Cloud is the easiest way to deploy a Xojo web app and you don&#8217;t have to do any maintenance on the server, we take care of that for you. It is secure, with a smart firewall, intrusion and hacking detection, and Security-Enhanced Linux to keep your apps secure. You can also set up SSL, MySQL and more with just a mouse-click. Xojo Cloud comes in a variety of packages offering options on RAM, storage and vCPU, so you can <a rel="noreferrer noopener" href="https://www.xojo.com/store/#hosting" target="_blank">purchase</a> the plan that is right for you.</p>



<p>We have more people deploying Xojo web apps to Xojo Cloud than ever before! If you have any questions about Xojo Cloud, please <a href="mailto:hello@xojo.com">reach out to us</a>. </p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="532" src="https://blog.xojo.com/wp-content/uploads/2022/12/1cloud0ECB06A7-DA67-474D-8E92-E506B3A775D5-1024x532.png" alt="" class="wp-image-11086" srcset="https://blog.xojo.com/wp-content/uploads/2022/12/1cloud0ECB06A7-DA67-474D-8E92-E506B3A775D5-1024x532.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/12/1cloud0ECB06A7-DA67-474D-8E92-E506B3A775D5-300x156.png 300w, https://blog.xojo.com/wp-content/uploads/2022/12/1cloud0ECB06A7-DA67-474D-8E92-E506B3A775D5-768x399.png 768w, https://blog.xojo.com/wp-content/uploads/2022/12/1cloud0ECB06A7-DA67-474D-8E92-E506B3A775D5.png 1250w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p><em>Jason grew up in the Oklahoma City area and has been on the Xojo team since the beginning! When he’s not working, you’ll find him spending time with his wife and son, hiking, playing tennis or just relaxing at home. He also enjoys trading stocks and watching Oklahoma Sooner football!</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The Versatility of Xojo</title>
		<link>https://blog.xojo.com/2022/12/06/the-versatility-of-xojo/</link>
		
		<dc:creator><![CDATA[Jérémie Leroy]]></dc:creator>
		<pubDate>Tue, 06 Dec 2022 16:49:04 +0000</pubDate>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[App Hosting]]></category>
		<category><![CDATA[App Localization]]></category>
		<category><![CDATA[App Store]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[GraffitiSuite]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Trello]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=11006</guid>

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



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



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



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



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



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



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



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


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


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



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



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



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



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


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


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



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



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



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



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



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



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



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



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



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



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



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



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



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



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


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


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


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


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



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



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



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



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



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



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



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



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



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



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



<p><em>Jérémie Leroy has been using Xojo since 2008, he won two Xojo Design Awards in the iOS App category and has released over 13 iOS apps made with Xojo on the App Store. He also released </em><a href="https://github.com/jkleroy/iOSDesignExtensions"><em>iOSDesignExtensions</em></a><em> on Github to help style and polish your Xojo made iOS apps.</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Adding Tables to PDFDocument</title>
		<link>https://blog.xojo.com/2022/10/12/adding-tables-to-pdfdocument/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Wed, 12 Oct 2022 13:45:45 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[PDF]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=10756</guid>

					<description><![CDATA[Starting with Xojo 2022r3 it is possible to create and add tables to PDF documents using Xojo&#8217;s PDFTable class and the PDFTableDataSource class interface. Among&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Starting with Xojo 2022r3 it is possible to create and add tables to PDF documents using Xojo&#8217;s PDFTable class and the PDFTableDataSource class interface. Among other things, your code will not need to be in charge of calculating rows sizes in order to decide if it needed to add a new page or not, or even complex calculations in order to draw the content on every cell of every row/column pair in the table.</p>



<p>You can download the example project <a href="https://www.dropbox.com/s/bkdpoem0vn3vqcx/PDFTable-Example.zip?dl=1">from this link</a>.</p>



<h3 class="wp-block-heading">Features of Tables in PDFDocument</h3>



<p>The main features available with tables in PDFDocument are:</p>



<ul class="wp-block-list"><li>PDFTable / PDFTableDataSource is compatible with Desktop, Web, Console and RaspberryPi projects</li><li>Variable height rows</li><li>Automatically add new pages to the PDF</li><li>The ability to repeat (or not) the table header at the start of every new page added</li></ul>



<p>In order to achieve this, the PDFTable class works side by side with the PDFTableDataSource class interface. This class interface declares the methods that will be called by a given PDFTable instance in order to generate the table on the fly.</p>



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



<p>Because it is a class interface, you will be able to add it to any window/web page or any class/subclass you  create, so it can work as the provider of the data in the drawing of a given PDF table.</p>



<p>The PDFTableDataSource has these five methods:</p>



<ul class="wp-block-list"><li><strong>AddNewRow(rowCount As Integer) As Boolean</strong>&#8211; The rowCount parameter contains the value of the rows already added to the table. Returning True from this method will add a new row to the table; otherwise it will end the creation of the associated table.</li><li><strong>HeaderHeight As Double</strong>&#8211; In the implementation of this method you will set the height value used in order to draw the table header.</li><li><strong>PaintCell(g As Graphics, row As Integer, column As Integer)</strong>&#8211; This is the method called by the PDFTable instance in order to draw the cell for the row/column pair stored in the associated parameters. The method receives its own graphic context in the &#8216;g&#8217; variable, so you can use any of the supported methods and properties of the Graphic class to draw the contents in the table cell.</li><li><strong>PaintHeaderContent(g As Graphics, column As Integer)</strong>&#8211; This is the method called by the PDFTable instance every time it needs to draw the header of the table. As you can see, it receives as parameters the column number and its own graphic context.</li><li><strong>RowHeight As Double</strong>&#8211; This is the method called by the PDFTable instance so your code can set the height for the current row.</li></ul>



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



<p>This is a really simple class exposing a total of four properties:</p>



<ul class="wp-block-list"><li><strong>ColumnCount As Integer</strong>&#8211; This is the property that sets the number of columns for the table to be drawn.</li><li><strong>ColumnWidths As String</strong>&#8211; This is the property that sets as a string the width of every column in the table, separated by the comma character.</li><li><strong>DataSource As PDFTableDataSource</strong>&#8211; This is the property that sets the object acting as the data source object for the table. Remember that such an object needs to implement the methods declared in the PDFTableDataSource class interface.</li><li><strong>HasRepeatingHeader As Boolean</strong>&#8211; Use this property to instruct the PDFTable instance if it needs to repeat the header on every new page that is added to the document as the table is generated.</li></ul>



<p>For example, the following fragment of code will create a table with a total of three columns that have the same size. The table will be drawn horizontally centered in the page. The object acting as the data source for the table will be the same where this snippet of code has been added, that is: &#8216;Self&#8217;:</p>



<pre class="wp-block-preformatted"><code>Var d As New PDFDocument

Var tTable As New PDFTable
tTable.ColumnCount = 3
tTable.ColumnWidths = "150,150,150"
tTable.DataSource = Self
tTable.HasRepeatingHeader = True</code></pre>



<p>The way to add a PDFTable instance to the current page of the PDF document is through the AddTable(table As PDFTable, x As Double, y As Double) method; for example:</p>



<pre class="wp-block-preformatted"><code>Var x As Double = d.PageWidth/2 - 450/2

d.addTable(tTable,x,20)</code></pre>



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



<h3 class="wp-block-heading">PDFTable in Practice</h3>



<p>In this example, you can see how to create a PDF document with a table added to it (horizontally centered on the pages). This table will have three columns equally sized and a total of 100 rows with a variable —random— height—, and giving the option to the user so they can choose to repeat the table header on every new page added to the document or not.</p>



<p>The cell contents of the table will be chosen randomly, varying between filling the cell with a random color, drawing text with the row and column numbers for the cell, rendering an image that has been added to the project, or keeping the cell empty.</p>



<p>Create a new Desktop project. With the Window1 selected in the Navigator, click on the &#8220;Choose…&#8221; button found in the associated Inspector Panel under the Interface section. This action will open a new window displaying all the available Class Interfaces. Select the PDFTableDataSource entry and confirm the selection click the Ok button.</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="927" height="1024" src="https://blog.xojo.com/wp-content/uploads/2022/10/Selector-PDFDataTableSource-927x1024.png" alt="" class="wp-image-10757" srcset="https://blog.xojo.com/wp-content/uploads/2022/10/Selector-PDFDataTableSource-927x1024.png 927w, https://blog.xojo.com/wp-content/uploads/2022/10/Selector-PDFDataTableSource-272x300.png 272w, https://blog.xojo.com/wp-content/uploads/2022/10/Selector-PDFDataTableSource-768x848.png 768w, https://blog.xojo.com/wp-content/uploads/2022/10/Selector-PDFDataTableSource.png 1012w" sizes="auto, (max-width: 927px) 100vw, 927px" /></figure>
</div>


<p>As result, the methods declared by the PDFTableDataSource are now added to the Window1 item.</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="505" height="270" src="https://blog.xojo.com/wp-content/uploads/2022/10/PDFTableDataSource-Methods.png" alt="" class="wp-image-10758" srcset="https://blog.xojo.com/wp-content/uploads/2022/10/PDFTableDataSource-Methods.png 505w, https://blog.xojo.com/wp-content/uploads/2022/10/PDFTableDataSource-Methods-300x160.png 300w" sizes="auto, (max-width: 505px) 100vw, 505px" /></figure>
</div>


<p>Grab a CheckBox control from the Library and drop it in the upper-left corner of the window in the Layout Editor. Use the associated Inspector Panel to change the following values:</p>



<ul class="wp-block-list"><li><strong>Name:</strong> RepeatHeaderCB</li><li><strong>Visual State:</strong> Checked</li></ul>



<p>In order to complete this basic user interface, drag a Button control from the Library and drop it in the upper-right corner of the window in the Layout Editor. With Button1 selected in the Navigator, choose the Add to &#8220;Button1&#8221; &gt; Event Handler…&nbsp;option from the contextual menu. Next, select the Pressed event from the resulting window and confirm the selection so it is added to the Window1 object.</p>



<p>With the Pressed event selected in the Navigator, add the following fragment of code in the associated Code Editor:</p>



<pre class="wp-block-preformatted"><code>Var d As New PDFDocument

Var tTable As New PDFTable
tTable.ColumnCount = 3
tTable.ColumnWidths = "150,150,150"
tTable.DataSource = Self
tTable.HasRepeatingHeader = RepeatHeaderCB.Value

Var x As Double = d.PageWidth/2 - 450/2

d.addTable(tTable,x,20)

d.Save(SpecialFolder.Desktop.Child("Table.pdf"))</code></pre>



<p>Drop any image you want to use from your computer drive into the Xojo&#8217;s IDE Navigator. Our example uses an image named &#8220;XojoLogo100&#8221;. When adding your own image, you can opt to rename it to the name name used in the code of this example, or changing all the references where &#8220;XojoLogo100&#8221; is referenced to the name of your image.</p>



<p>Now it is time to implement the code in every one of the five methods required by the PDFTableDataSource class interface.</p>



<p>In the AddNewRow method:</p>



<pre class="wp-block-preformatted"><code>Return rowCount &lt; 100 // Our example table has a total of 100 rows.</code></pre>



<p>In the HeaderHeight method:</p>



<pre class="wp-block-preformatted"><code>Return 30 // This is the height for the cells of the header in the table.</code></pre>



<p>In the PaintCell method:</p>



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

Var option As Integer = rd.InRange(1,4)

Select Case option

Case 1

  Var s As String = "row: " + row.ToString + " column: " + Column.ToString
  Var h As Double = g.Height/2 + g.TextHeight/2
  g.DrawText s,5,h

Case 2

  g.DrawPicture(XojoLogo100,0,0)

Case 3

  g.DrawingColor = Color.RGB(rd.InRange(0,255), rd.InRange(0,255), rd.InRange(0,55))
  g.FillRectangle(2,2,g.Width-4,g.Height-4)

Case 4

 // Empty cell
End Select

g.DrawingColor = Color.Black
g.DrawRectangle 0,0, g.Width,g.Height</code></pre>



<p>And this is the code we will use in order to draw the content of the table Header cells in the PaintHeaderContent:</p>



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

Var c As Color

Select Case Column
Case 0
  c = color.Red
Case 1
  c = Color.Green
Case 2
  c = Color.Blue
End Select

g.DrawingColor = c
g.FillRectangle 0,0,g.Width,g.Height

Var s As String = "Column: " + Column.ToString

Var x, y As Double
x = (g.Width/2) - (g.TextWidth(s)/2)
y = (g.Height/2) + (g.TextHeight/2)

g.DrawingColor = color.Black
g.DrawText s,x, y</code></pre>



<p>Now add the code responsible for setting the height of every new row added to the table in the RowHeight method. As you can see, this value is a random value between 25 and 100 points:</p>



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

return rd.InRange(25,100)</code></pre>



<h3 class="wp-block-heading">Running the App</h3>



<p>Run the app, click on the button and you will see how a new PDF document named &#8220;Table.pdf&#8221; is created in your computer desktop. The number of pages of the PDF document may vary because the height of the table rows vary on every iteration.</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1018" height="1024" src="https://blog.xojo.com/wp-content/uploads/2022/10/Table-PDF-1018x1024.png" alt="" class="wp-image-10759" srcset="https://blog.xojo.com/wp-content/uploads/2022/10/Table-PDF-1018x1024.png 1018w, https://blog.xojo.com/wp-content/uploads/2022/10/Table-PDF-298x300.png 298w, https://blog.xojo.com/wp-content/uploads/2022/10/Table-PDF-150x150.png 150w, https://blog.xojo.com/wp-content/uploads/2022/10/Table-PDF-768x772.png 768w, https://blog.xojo.com/wp-content/uploads/2022/10/Table-PDF-1527x1536.png 1527w, https://blog.xojo.com/wp-content/uploads/2022/10/Table-PDF-2036x2048.png 2036w" sizes="auto, (max-width: 1018px) 100vw, 1018px" /></figure>
</div>


<p>This time, unselect the checkbox and click the button to create the PDF document again. Now, the table header is only rendered in the first page of the document.</p>



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



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

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

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

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

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>PDFDocument Improvements</title>
		<link>https://blog.xojo.com/2022/10/12/pdfdocument-improvements/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Wed, 12 Oct 2022 13:45:29 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[PDF]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=10810</guid>

					<description><![CDATA[While PDFTable and PDFDataTableSource ease the way to render tables in your PDF documents on Desktop, Web, Raspberry Pi and Console projects (iOS to come!) are the big new features for PDFDocument in Xojo 2022r3, that's not all that improved. There are additional features added to PDFDocument you might find helpful such as more control while using PDFForm and improvements to dealing with TOC indexes. Learn more about how to get advantage of these additions!]]></description>
										<content:encoded><![CDATA[
<p>While <a href="https://blog.xojo.com/2022/10/12/adding-tables-to-pdfdocument/">PDFTable</a> and PDFDataTableSource ease the way to render tables in your PDF documents on Desktop, Web, Raspberry Pi and Console projects (iOS to come!) and are the big new features for PDFDocument in Xojo 2022r3, that&#8217;s not all that improved. There are additional features added to PDFDocument you might find helpful such as more control while using PDFForm and improvements to dealing with TOC indexes. Learn more about how to get advantage of these additions!</p>



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



<h3 class="wp-block-heading">More Control with PDFForm Controls</h3>



<p>It is possible to add forms to your PDF documents using controls as text fields, text areas, list boxes, radio buttons, check boxes, popup menus, combo boxes, etc. Starting with Xojo 2022r3 you&#8217;ll be able to set if the items of PDFComboBox, PDFListBox and PDFPopupMenu are displayed sorted or as they were added using the Boolean IsSorted property.</p>



<p>As for the PDFTextArea and PDFTextField controls, there is a new property AllowSpellChecking so you can set if these will enable spell check or not. And in the case of the PDFTextField, it is also possible to set the HasPassword property so the text typed by the user is substituted in the PDF document with the usual replacement character, hiding what the user is typing from prying eyes!</p>



<h3 class="wp-block-heading">Dealing with TOC Indexes</h3>



<p>Lastly, there are also improvements to dealing with TOC creation in your PDF documents. For example, you can get now the Parent instance from a PDFToc entry through the Parent property; and there are new methods to get all the child items hanging from a PDFTOCEntry —Entries() As PDFTOCEntry()— and to remove existing entries from a PDFTOCEntry instance: PDFTOCEntry.RemoveEntry(ParamArray entries As PDFTOCEntry) and PDFTOCEntry.RemoveEntry(entries() as PDFTOCEntry).</p>



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



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

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

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

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

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>PDFDocument: How To Encrypt PDFs</title>
		<link>https://blog.xojo.com/2022/07/25/pdfdocument-how-to-encrypt-pdfs/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Mon, 25 Jul 2022 13:54:00 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[2022r2]]></category>
		<category><![CDATA[Encryption]]></category>
		<category><![CDATA[PDF]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=10486</guid>

					<description><![CDATA[One of the PDFDocument features added in Xojo 2022r2 is the ability to encrypt PDF files created with Xojo. Continue reading and I will show&#8230;]]></description>
										<content:encoded><![CDATA[
<p>One of the PDFDocument features added in Xojo 2022r2 is the ability to encrypt PDF files created with Xojo. Continue reading and I will show you how.</p>



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



<p>Encrypting PDF files with PDFDocument is based in the use of the PDFPermissions class. You&#8217;ll need to create a new instance of the class passing along the &#8220;Owner&#8221; and &#8220;User&#8221; passwords. For example:</p>



<pre class="wp-block-code"><code>Var d As New PDFDocument
Var g As Graphics = d.Graphics

Var p As New PDFPermissions("OwnerPassword","UserPassword")</code></pre>



<p>In addition, you can set other properties for the PDFPermissions instance; all of them are read/write and will be applied by the PDF viewer app for when the document is opened using the &#8220;user&#8221; password.</p>



<ul class="wp-block-list"><li><strong>AllowCopyingContents</strong> is set to <code>False</code> by default. When set to <code>True</code> it will allow copying contents from the PDF, as for example the selected text or image.</li><li><strong>AllowModifyingContents</strong> is set to <code>False</code> by default. When set to <code>True</code> it will all to modify the contents of the protected PDF document.</li><li><strong>AllowPrinting</strong> is se to <code>False</code> by default. When it is set to <code>True</code> it will be possible to print the PDF.</li></ul>



<p>Once the PDFPermissions instance has been created and the desired properties had been set, all you need to do is to assign such instance to the Permissions property for the PDFDocument instance you want to encrypt:</p>



<pre class="wp-block-code"><code>d.Permissions = p</code></pre>



<p>Then, when it&#8217;s saving the document to a file, PDFDocument will encrypt all the streams of data containing sensitive information, as it can be the text or Images rendered on every one of the PDF pages plus the metadata information itself. The used encryption algorithm is AES 128 bits.</p>



<p>That&#8217;s all! You can distinguish an encrypted PDF file from an unencrypted one because, usually, the first one will be displayed with the image of a Lock in the icon. When you open an encrypted PDF in the viewer app you&#8217;ll be asked to type a password. If you enter the passord set to the &#8220;Owner&#8221; user, you&#8217;ll be able to do all the kind of operations allowed by the viewer app, while if you enter the &#8220;User&#8221; password, then the kind of options available will be determined by those set using the PDFPermissions properties.</p>



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



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

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

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

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

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>PDFDocument: New Annotations Types</title>
		<link>https://blog.xojo.com/2022/07/25/pdfdocument-new-annotations-types/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Mon, 25 Jul 2022 13:53:00 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[2022r2]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[PDF]]></category>
		<category><![CDATA[Rapid Application 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=10488</guid>

					<description><![CDATA[The annotations feature on PDFDocument has been significantly extended in the release of Xojo 2022r2. Continue reading to learn about the new annotation types. Currently,&#8230;]]></description>
										<content:encoded><![CDATA[
<p>The annotations feature on PDFDocument has been significantly extended in the release of Xojo 2022r2. Continue reading to learn about the new annotation types.</p>



<p>Currently, Xojo&#8217;s PDFDocument supports the most common type of annotations for PDF &#8211; you know those little yellow boxes displayed like sticky notes on the pages of the PDF document that display their contents when clicked on.</p>



<p>Now with Xojo 2022r2 and later you have more options! And while most of these don&#8217;t look like &#8220;real&#8221; annotations or like something made using the Graphics methods, they will behave as the annotations you are familiar with using in PDF. What I mean by this is that they will display the associated text for the annotation while also allowing the user to Accept/Decline the annotation or interact with them by adding, for example, new replies.</p>



<p>Before reviewing the new options, let me just remind you: The PDF Standard dictates how some features must be implemented for a PDF. After that, it is up to the developers of the PDF viewer app to decide what features are implemented, keep in mind results can vary depending on the PDF viewer you or your user chose to use. As other many things related with PDF files, don&#8217;t expect every PDF viewer apps out there to support or adhere to the annotations outside of the most basic ones.</p>



<p>Adobe is the original creator of the PDF specification and its free PDF viewer, <a href="https://www.adobe.com/acrobat/pdf-reader.html">Acrobat Reader</a> app does support everything Xojo&#8217;s PDFDocument offers.</p>



<h3 class="wp-block-heading">Attaching Files to the PDF</h3>



<p>You&#8217;ll be able to embed any kind of file (except for those based in a Bundle structure) into the PDF document itself, for example an Excel file, a Hi-Res image, etc. Then the user viewing the PDF document will be able to open the attached file clicking in the annotation using whichever PDF Viewer app their computer/device has installed for the attached file format. Because this is an annotation, the user will be able to also edit the annotation or add new replies to it.</p>



<p>This is an example about how to create these kind of annotations:</p>



<pre class="wp-block-code"><code>Var d As New PDFDocument
Var g As Graphics = d.Graphics
Const kContentText As String = "Attached File Annotation: double click on me!"

g.FontSize = 20
g.DrawText(kContentText, 40, 60)

If exampleFile &lt;&gt; Nil Then
  
  // Creating a new EmbeddedSound.
  d.AddEmbeddedFile(exampleFile, 40, 60, g.TextWidth(kContentText), 20)
  
  // Saving the created PDF document to the selected path.
  Var f As FolderItem = FolderItem.ShowSaveFileDialog("","PDFAttachedFile.pdf")
  
  If f &lt;&gt; Nil Then
    
    d.Save(f)
    
  End If
End If
</code></pre>



<p>Here <code>exampleFile</code> is a FolderItem property that has been added to the project and that&#8217;s pointing to the file to embed.</p>



<p>And this is how it looks like in the resulting PDF file:</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1024" height="439" src="https://blog.xojo.com/wp-content/uploads/2022/06/AttachedFilePDF-1024x439.png" alt="" class="wp-image-10490" srcset="https://blog.xojo.com/wp-content/uploads/2022/06/AttachedFilePDF-1024x439.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/06/AttachedFilePDF-300x129.png 300w, https://blog.xojo.com/wp-content/uploads/2022/06/AttachedFilePDF-768x329.png 768w, https://blog.xojo.com/wp-content/uploads/2022/06/AttachedFilePDF-1536x658.png 1536w, https://blog.xojo.com/wp-content/uploads/2022/06/AttachedFilePDF-2048x878.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<h3 class="wp-block-heading">Callout Annotations</h3>



<p>These kind of annotations are perfect for pointing our or calling attention to any other item in the PDF page. They are highly customizable- you can decide for example a solid or dashed line, the termination of the line, the color and, of course the text to be displayed in the annotation itself.</p>



<p>This is an example showing how to add a Callout annotation to a PDFDocument:</p>



<pre class="wp-block-code"><code>Var d As New PDFDocument
Var g As Graphics = d.Graphics
Const kContentText As String = "Callout Annotation in PDF"

g.FontSize = 40
g.Bold = True
g.DrawText(kContentText, 40, 60)

g.Bold = False
g.FontSize = 12
g.DrawText(kSampleText, 40, 100, 200)

Var originY As Double = (g.TextHeight(kSampleText, 200) / 2)

Var tCallout As New PDFCallout("Callout Example", New Point(250, originY), New Point(300, originY + 50), _
 New Point(350, originY + 50), 100, 50)

tCallout.BorderStyle = PDFAnnotation.BorderStyles.Dashed
tCallout.DashPattern = Array(2.0, 2.0)
tCallout.DrawingColor = Color.Orange
tCallout.LineEndingStyle = PDFAnnotation.LineEndingStyles.OpenArrow
tCallout.Text = "Some sample text in the annotation"
tCallout.FontSize = 9.5

d.AddCallout(tCallout)

// Saving the created PDF document to the selected path.
Var f As FolderItem = FolderItem.ShowSaveFileDialog("","PDFCalloutExample.pdf")

If f &lt;&gt; Nil Then
  
  d.Save(f)
  
End If
</code></pre>



<p>Where <code>kSampleText</code> is a Constant added to the project containing some sample text to be put in the page of the PDF.</p>



<p>And this is how the Callout will look like when opening the resulting PDF file in the viewer app:</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1024" height="599" src="https://blog.xojo.com/wp-content/uploads/2022/06/Callout-1024x599.png" alt="" class="wp-image-10491" srcset="https://blog.xojo.com/wp-content/uploads/2022/06/Callout-1024x599.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/06/Callout-300x176.png 300w, https://blog.xojo.com/wp-content/uploads/2022/06/Callout-768x450.png 768w, https://blog.xojo.com/wp-content/uploads/2022/06/Callout-1536x899.png 1536w, https://blog.xojo.com/wp-content/uploads/2022/06/Callout-2048x1199.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<h3 class="wp-block-heading">Line Annotations</h3>



<p>A &#8220;Line&#8221; annotation displays a straight line on the page with a text caption inside the line or above it.</p>



<p>It is also possible to add leader lines to both sides of the main line (with possitive or negative values) plus set other properties as the type of the line (solid, dashed, etc), the kind of termination used on both ends of the main line (i.e: open/close arrow, butt, circle, diamond, square…), the drawing color, line width or font size.</p>



<p>This is how a Line annotation looks like when the resulting PDFDocument is viewed using Acrobat Reader (in this case, using Leader lines):</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1024" height="605" src="https://blog.xojo.com/wp-content/uploads/2022/06/Line-1024x605.png" alt="" class="wp-image-10493" srcset="https://blog.xojo.com/wp-content/uploads/2022/06/Line-1024x605.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/06/Line-300x177.png 300w, https://blog.xojo.com/wp-content/uploads/2022/06/Line-768x454.png 768w, https://blog.xojo.com/wp-content/uploads/2022/06/Line-1536x907.png 1536w, https://blog.xojo.com/wp-content/uploads/2022/06/Line-2048x1210.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<h3 class="wp-block-heading">Video Annotations</h3>



<p>Yes, you can embed .mp4 files in the PDF created with PDFDocument, and these will be played from the PDF itself. This will increase the size of the generated PDF file because it will add the size of the embedded mp4 file itself! So it is good practice to optimize the video files as much as possible and use the video resolution you want them to be played and not a higher one.</p>



<p>You can also add this kind of content as an Attached File annotation too. In both cases the data of the file will be embedded in the generated PDF file. The main difference in this case is that the mp4 file will be opened using an external app and that you&#8217;ll be able to include other video file format besides .mp4.</p>



<p>The way to add this kind of annotation to a PDFDocument instance is quite simple, for example:</p>



<pre class="wp-block-code"><code>Var d As New PDFDocument
Var g As Graphics = d.Graphics
Const kContentText As String = "Embedded Video Annotation"

g.FontSize = 30
g.DrawText(kContentText, 40, 60)

If exampleVideo &lt;&gt; Nil Then
  
  // Creating a new EmbeddedSound.
  d.AddEmbeddedMovie(exampleVideo, 40, 100, 478, 360)
  
  // Saving the created PDF document to the selected path.
  Var f As FolderItem = FolderItem.ShowSaveFileDialog("","PDFEmbeddedVideo.pdf")
  
  If f &lt;&gt; Nil Then
    
    d.Save(f)
    
  End If
End If
</code></pre>



<p>Where <code>exampleVideo</code> is a FolderItem Property that has been added to the project. This is how a video annotation will look like when opening the resulting PDF in Acrobat Reader:</p>



<figure class="wp-block-image is-style-default"><img loading="lazy" decoding="async" width="918" height="600" src="https://blog.xojo.com/wp-content/uploads/2022/06/VideoAnnotation.gif" alt="" class="wp-image-10494"/></figure>



<h3 class="wp-block-heading">Sound Annotations</h3>



<p>In addition to video annotations, it is also possible to add sound files that can be played from the PDF itself. In this case, the audio files need to be in AIFF format with 2 audio channels (stereo), 16 bits of resolution and a sampling frequency of 44,1 kHz.</p>



<p>As it is the case with video annotations, you can opt to add this kind of content as an Attached File annotation, so it will be opened with an external app and opens the range of sound file formats you can embed into the PDF.</p>



<p>The way to add Sound annotations using PDFDocument is shown here:</p>



<pre class="wp-block-code"><code>Var d As New PDFDocument
Var g As Graphics = d.Graphics
g.FontSize = 30

Const kContentText As String = "Embedded Sound Annotation"

Var x, y, width, height As Double

x = g.Width/2 - width/2
y = 60

width = g.TextWidth(kContentText)
height = g.TextHeight

g.DrawText(kContentText, x, y)

If exampleSound &lt;&gt; Nil Then
  
  // Creating a new EmbeddedSound.
  d.AddEmbeddedSound(exampleSound,x,y,width,height)
  
  // Saving the created PDF document to the selected path.
  Var f As FolderItem = FolderItem.ShowSaveFileDialog("","PDFEmbeddedSound.pdf")
  
  If f &lt;&gt; Nil Then
    
    d.Save(f)
    
  End If
End If
</code></pre>



<p>Here <code>exampleSound</code> is a FolderItem Property added to the project. And this is how a Sound annotation will look when the PDF document is opened using Acrobat Reader:</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1024" height="361" src="https://blog.xojo.com/wp-content/uploads/2022/06/SoundAnnotation-1024x361.png" alt="" class="wp-image-10495" srcset="https://blog.xojo.com/wp-content/uploads/2022/06/SoundAnnotation-1024x361.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/06/SoundAnnotation-300x106.png 300w, https://blog.xojo.com/wp-content/uploads/2022/06/SoundAnnotation-768x271.png 768w, https://blog.xojo.com/wp-content/uploads/2022/06/SoundAnnotation-1536x542.png 1536w, https://blog.xojo.com/wp-content/uploads/2022/06/SoundAnnotation-2048x722.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<h3 class="wp-block-heading">Markup Annotations</h3>



<p>A Markup annotation is intended to mark an underlying text content using any of the different available types, for example &#8220;Highlight&#8221;, &#8220;Squiggly&#8221; (usually used to mark a text that needs some kind of correction), &#8220;Underline&#8221; or &#8220;Strikeout&#8221;. Besides the Markup type, it is also possible to set the color of the annotation.</p>



<p>For example, the following snippet of code adds two Markup annotations to the page of the PDFDocument using the Highlight and Squiggly types:</p>



<pre class="wp-block-code"><code>Var d As New PDFDocument
Var g As Graphics = d.Graphics
Const kContentText As String = "Markup Annotation in PDF"

g.FontSize = 40
g.Bold = True
g.DrawText(kContentText, 40, 60)

// Adding a Markup annotation with the Highlight type (Default)
d.AddMarkup(40,40,g.TextWidth(kContentText),g.FontSize,"Let's focus on this Section")

g.Bold = False
g.FontSize = 12
g.DrawText(kSampleText, 40, 100, g.Width-80)

// Adding a Markup annotation with the Squiggly type
d.AddMarkup(40,195,210,g.FontSize,"Some text to correct!",Color.Red,PDFAnnotation.MarkupTypes.Squiggly)

// Saving the created PDF document to the selected path.
Var f As FolderItem = FolderItem.ShowSaveFileDialog("","PDFMarkupExample.pdf")

If f &lt;&gt; Nil Then
  
  d.Save(f)
  
End If</code></pre>



<p>And this is how it looks when the resulting document is opened in Adobe Acrobat Reader:</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1024" height="632" src="https://blog.xojo.com/wp-content/uploads/2022/06/MarkupAnnotation-1024x632.png" alt="" class="wp-image-10499" srcset="https://blog.xojo.com/wp-content/uploads/2022/06/MarkupAnnotation-1024x632.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/06/MarkupAnnotation-300x185.png 300w, https://blog.xojo.com/wp-content/uploads/2022/06/MarkupAnnotation-768x474.png 768w, https://blog.xojo.com/wp-content/uploads/2022/06/MarkupAnnotation-1536x949.png 1536w, https://blog.xojo.com/wp-content/uploads/2022/06/MarkupAnnotation-2048x1265.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


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



<p>Let me end with one other minor improvement to PDFDocument annotations: starting with Xojo 2022r2 all of them include metadata information about the creation and modification date and time. this information will be displayed as part of the annotation metadata when the item is selected in the viewer app.</p>



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



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

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

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

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

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Creating Presentations with PDF and Xojo</title>
		<link>https://blog.xojo.com/2022/05/26/creating-presentations-with-pdf-and-xojo/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Thu, 26 May 2022 15:35:00 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[XDC]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[PDF]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=10319</guid>

					<description><![CDATA[I know, I know, it's not the usual thing to do when making presentations, but did you know that it is possible to create presentations using Xojo's and PDF? If you're interested in this little experiment, read on and I'll show you how to do it using Xojo's PDFDocument. ]]></description>
										<content:encoded><![CDATA[
<p>I know, I know, it&#8217;s not the <em>usual</em> thing to do when making presentations, but did you know that it is possible to create presentations using Xojo&#8217;s and PDF? If you&#8217;re interested in this little experiment, read on and I&#8217;ll show you how to do it using Xojo&#8217;s <a href="https://documentation.xojo.com/api/pdf/pdfdocument.html#pdfdocument">PDFDocument</a>. </p>



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



<p>Why, you ask? What are the advantages of using a PDF for your presentations? PDF is portable, meaning you can distribute these files easily, usually, with a small file footprint. The content is vectorial (except for images), what means that it will look great no matter the screen resolution of the display/projector used for playing the presentation.</p>



<p>There is one current issue to watch out for, currently <a href="https://acrobat.uservoice.com/forums/590923-acrobat-for-windows-and-mac/suggestions/44616444-fullscreen-page-transitions-in-pdfs-no-longer-work">there&#8217;s a bug on macOS</a> where Acrobat Reader is not able to apply the assigned transitions on Big Sur and later; they still work under Catalina and previous versions of macOS.</p>



<p>In this example project I will create a shortened version of the slides I used in the <a href="https://youtu.be/aSfff3hQaX4">Using Xojo&#8217;s PDFDocument</a> presentation. You&#8217;ll need to change the font names (and any other item) to those you are using and that are installed in your computer.</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="960" height="540" src="https://blog.xojo.com/wp-content/uploads/2022/04/Presentation.gif" alt="" class="wp-image-10320"/></figure>
</div>


<h3 class="wp-block-heading">Setting the Viewer Options</h3>



<p>Start by creating a new project for the target you&#8217;re most comfortable with &#8211; Xojo&#8217;s PDFDocument is cross-platform and supported on Desktop, Web, iOS and Console projects. Next, add the Opening Event Handler to the default DesktopWindow/WebWindow/MobileScreen, or choose the Run Event Handler if you chose to create a new Console Project.</p>



<p>Write the following lines of code in the associated Code Editor:</p>



<pre class="wp-block-preformatted">// Let's create a new PDFDocument instance with
// the page size set to HD resolution

Var Presentation As New PDFDocument(1920, 1080)

// Let's make sure that the fonts used are embedded in the
// document, so there are no unexpected problems when the
// PDF is opened in a device that doesn't have that
// same fonts installed

Presentation.EmbeddedFonts = True</pre>



<p>The next lines of code will set the default for the View mode of the document when it is opened in Acrobat Reader or any other PDF reader. Since it&#8217;s a presentation, you&#8217;ll likely want the document to be opened in Full Screen mode by default, so let&#8217;s make that happen:</p>



<pre class="wp-block-preformatted">// Let's create a new Instance from the PDFViewerOptions class

Var ViewerOptions As New PDFViewerOptions

// And set the FullScreen property to True
// so the document will set that view size
// when opened in the PDF Viewer app

ViewerOptions.FullScreen = True</pre>



<h3 class="wp-block-heading">Drawing the Background of the Page</h3>



<p>Use a linear gradient brush to fill in the background of all the slides. For convenience, create a new method for it using the following values in the Inspector Panel:</p>



<ul class="wp-block-list"><li><strong>Name:</strong> DrawPageBackground</li><li><strong>Parameters:</strong> g As Graphics</li></ul>



<p>Type the following code in the associated Code Editor for the method:</p>



<pre class="wp-block-preformatted">Static backgroundfilling As LinearGradientBrush

If backgroundfilling = Nil Then
  backgroundfilling = New LinearGradientBrush
  backgroundfilling.StartPoint = New Point(g.Width / 2, 0)
  backgroundfilling.EndPoint = New Point(g.Width / 2, g.Height)
  backgroundfilling.GradientStops.Add(New Pair(0.0, &amp;c000000))
  backgroundfilling.GradientStops.Add(New Pair(0.7, &amp;c000000))
  backgroundfilling.GradientStops.Add(New Pair(1.0, &amp;ccccccc))
End If

g.Brush = backgroundfilling
g.FillRectangle(0, 0, g.Width, g.Height)</pre>



<p>All this code does is create a LinearGradientBrush instance ranging from full black to some degree of gray at the bottom of the page. Because we are not going to change the values of the gradient every time we need to call the method, it makes sense to assign it to a Static instead of a Variable.</p>



<p>Then the LinearGradientBrush is assigned to the Brush property of the received Graphic context and, finally, used as the &#8220;filling color&#8221; when drawing the filled rectangle.</p>



<h3 class="wp-block-heading">Drawing the Header</h3>



<p>Now add the method that will be responsible for drawing the header shared by all the slides. Use the following values in the Inspector Panel:</p>



<ul class="wp-block-list"><li><strong>Method Name:</strong> DrawTopHeader</li><li><strong>Parameters:</strong> g As Graphics</li></ul>



<p>And type the following code in the associated Code Editor:</p>



<pre class="wp-block-preformatted">Const kPDFDocumentHeader As String = "PDFDocument"

DrawUpperBand(g, 0, 50)

g.FontName = "Helvetica"
g.FontSize = 180
g.Bold = True

Var x As Double = g.Width / 2 - g.TextWidth(kPDFDocumentHeader) / 2
Var y As Double = 220

g.DrawingColor = &amp;cC9F2C900
g.DrawText(kPDFDocumentHeader, x + 4, 224)

g.DrawingColor = Color.Black

Static linearGradient As LinearGradientBrush

If linearGradient = Nil Then
  Lineargradient = New LinearGradientBrush
  linearGradient.StartPoint = New point(x, y - 224)
  linearGradient.EndPoint = New point(x, y)
  linearGradient.GradientStops.Add(New Pair(0.0, &amp;c00BD4E00))
  linearGradient.GradientStops.Add(New Pair(0.7, &amp;c00FD1F00))
  linearGradient.GradientStops.Add(New Pair(1.0, &amp;c25712900))
End If

g.Brush = LinearGradient
g.DrawText(kPDFDocumentHeader, x, y)</pre>



<p>As you can see, this is quite similar to the previous code. We are using a new Linear Gradient as the filling for the &#8220;PDFDocument&#8221; text. But first, it calls the DrawUpperBand method. This is a method that will draw a picture with a 50% opacity behind the header text, as well as the XDC logo in the lower left corner of the slide. Add a new method using the following values:</p>



<ul class="wp-block-list"><li><strong>Method Name:</strong> DrawUpperBand</li><li><strong>Parameters:</strong> g As Graphics, x As Integer, y As Integer</li></ul>



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



<pre class="wp-block-preformatted">g.Transparency = 50.0
g.DrawPicture(UpperBand, x, y)
g.Transparency = 0
g.DrawPicture(XDC2x, 20, g.Height - XDC2x.Height)</pre>



<p>Both &#8220;UpperBand&#8221; and &#8220;XDC2x&#8221; are PNG image files added to the project.</p>



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



<p>Because the background and the header are common items in all the slides, we will render them every time we add a new slide (page) to the presentation (document). Create a new method using the following values:</p>



<ul class="wp-block-list"><li><strong>Method Name:</strong> NextPage</li><li><strong>Parameters:</strong> g As Graphics</li></ul>



<p>And type the following lines of code:</p>



<pre class="wp-block-preformatted">g.NextPage(1920, 1080)
DrawPageBackground(g)
DrawTopHeader(g)</pre>



<h3 class="wp-block-heading">Creating the Content of the Slides</h3>



<p>Now let&#8217;s add the method that will be responsible for adding the text of the main topic on every slide:</p>



<ul class="wp-block-list"><li><strong>Method Name:</strong> DrawTopic</li><li><strong>Parameters:</strong> g As Graphics, topic As String</li></ul>



<p>And type the following code in the associated Code Editor:</p>



<pre class="wp-block-preformatted">Var x, y As Double
g.FontName = "Anoxic Light"
g.FontSize = 150

x = g.Width / 2 - g.TextWidth(topic) / 2
y = g.Height / 2 - g.TextHeight / 2

Static LinearGradient As LinearGradientBrush

If LinearGradient = Nil Then
  linearGradient = New LinearGradientBrush
  linearGradient.StartPoint = New Point(x, y)
  linearGradient.EndPoint = New Point(x, y - 80)
  linearGradient.GradientStops.Add(New pair(1.0, &amp;c9FE1FF00))
  linearGradient.GradientStops.Add(New pair(0.0, &amp;cF6F6F600))
End If

g.Brush = linearGradient
g.DrawText(topic, x, y)</pre>



<h3 class="wp-block-heading">Setting Transitions Between Slides</h3>



<p>PDFDocument does support the range of transitions available under the PDF standard. In this case we are going to use the simplest: Fade. So, create a new method with the following values:</p>



<ul class="wp-block-list"><li><strong>Method Name:</strong> AddTransitions</li><li><strong>Parameters:</strong> d as PDFDocument</li></ul>



<p>And type the following lines of code in the associated Code Editor:</p>



<pre class="wp-block-preformatted">// New PDFTransition instance, using the Fade style
// with one second of length.

Var t As New PDFTransition(PDFTransition.Styles.Fade, 1)

// And apply it on every page of the PDFDocument, starting on Page 2.
If d.PageCount &gt; 2 Then
  For n As Integer = 2 To d.PageCount
    d.TransitionAt(n) = t
  Next
End If</pre>



<h3 class="wp-block-heading">Putting It All Together</h3>



<p>Now we have all the pieces needed to create this small presentation in PDF. Go back to the Opening Event Handler and type the following lines of code below the last one:</p>



<pre class="wp-block-preformatted">DrawPageBackground(g)
DrawTopHeader(g)
DrawTopic(g, "First Slide")
NextPage(g)
DrawTopic(g, "Second Slide")
NextPage(g)
DrawTopic(g, "Third Slide")
NextPage(g)
DrawTopic(g, "Fourth Slide")

AddTransitions(d)

d.Save(SpecialFolder.Desktop.Child("Presentation.pdf"))</pre>



<p>Done! Run the project and the PDF document will be saved to your computer Desktop. Once you open it in Adobe Reader, the app will detect that the document wants to use the full screen mode and, as soon as you confirm, it will begin the presentation. Depending on your preferences in Acrobat Reader, you may need to use the mouse button or arrow keys to change slides, or it may automatically advance to the next slide after the amount of time set.</p>



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



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

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

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

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

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>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>Tutorial: Deploying Web Apps on Linux</title>
		<link>https://blog.xojo.com/2021/05/28/tutorial-deploying-web-apps-on-linux/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Fri, 28 May 2021 15:00:00 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[App Hosting]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Deployment]]></category>
		<category><![CDATA[Hello World]]></category>
		<category><![CDATA[Nginx]]></category>
		<category><![CDATA[SSH]]></category>
		<category><![CDATA[webdev]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=8552</guid>

					<description><![CDATA[This tutorial provides a step-by-step guide to deploying Xojo web apps on a Linux server. You'll find deployment of more complex web apps can follow the same basic principles. If all of this seems too complex, Xojo Cloud is the easy, powerful and secure way to deploy web apps.]]></description>
										<content:encoded><![CDATA[<p>This tutorial provides a step-by-step guide to deploying Xojo web apps on a Linux server. We will use <strong>Ubuntu 20.4</strong> (64-bit) running on a remote server (VPS) in this example, but this tutorial should work on other Linux distros with minimal change, for example CentOS.</p>
<p>First, in order to deploy a web app you&#8217;ll need a way to access the remote server using the Terminal (macOS) or through the Command line, also a way to create and/or modify several files, and to copy files from your local computer to the remote server using (S)FTP.</p>
<blockquote><p><strong>Note:</strong> While we are using the &#8220;root&#8221; user for all the operations to keep the tutorial as short as possible, including files/folders/directories creation/edition and also for launching the web app, you&#8217;ll probably want to create a specific user with the proper privileges/group configuration for this. As we all know, you don&#8217;t usually want to run anything as the root user!</p></blockquote>
<p>Though this tutorial is focused on the <strong>deployment</strong> aspects of a web app, we&#8217;ll first create a very simple web app in Xojo. Feel free to use a web app of your own. At the end of this tutorial, you&#8217;ll find deployment of more complex web apps can follow the same basic principles.</p>
<h2>1. The Web App</h2>
<p>This very simple app will display a message when the button is clicked.  Start the Xojo IDE and choose Web from the Project Selector window:</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-8553 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2021/05/1-ProyectoWeb.png" alt="" width="882" height="538" srcset="https://blog.xojo.com/wp-content/uploads/2021/05/1-ProyectoWeb.png 882w, https://blog.xojo.com/wp-content/uploads/2021/05/1-ProyectoWeb-300x183.png 300w, https://blog.xojo.com/wp-content/uploads/2021/05/1-ProyectoWeb-768x468.png 768w" sizes="auto, (max-width: 882px) 100vw, 882px" /></p>
<p>Click on the <code>WebPage1</code> item displayed in the Navigator to access the webpage Layout Editor.</p>
<p>Next, drag a button from the Library panel and drop it anywhere on the Layout Editor.</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-8554 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2021/05/2-Pagina.png" alt="" width="766" height="583" srcset="https://blog.xojo.com/wp-content/uploads/2021/05/2-Pagina.png 766w, https://blog.xojo.com/wp-content/uploads/2021/05/2-Pagina-300x228.png 300w" sizes="auto, (max-width: 766px) 100vw, 766px" /></p>
<p>With the button still selected, add the <code>Pressed</code> Event Handler and type this line of code in the Code Editor:</p>
<pre>MessageBox "Hola Mundo"</pre>
<p>The classic &#8220;Hello World&#8221; en español, this is everything the web app will do.</p>
<h2>2. Setting the Deployment Options</h2>
<p>Click on the <code>Shared</code> option found under the <code>Build Settings</code> section in the Navigator. Next, enter <code>9000</code> as the port under the <code>Build Settings</code> section in the Inspector Panel.</p>
<blockquote><p><strong>Note:</strong> Adding the port is not required at this time because the port can be assigned when running the app once it is deployed to the server.</p></blockquote>
<p><img loading="lazy" decoding="async" class="size-full wp-image-8567 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2021/05/InspectorPanel.png" alt="" width="301" height="710" srcset="https://blog.xojo.com/wp-content/uploads/2021/05/InspectorPanel.png 301w, https://blog.xojo.com/wp-content/uploads/2021/05/InspectorPanel-127x300.png 127w" sizes="auto, (max-width: 301px) 100vw, 301px" /></p>
<h2>3. Compile the Web App</h2>
<p>Make sure to choose the Linux checkbox in <code>Build Settings</code>. Then, select <code>X86 64 bit</code> from the <code>Build</code> popup menu in the Inspector Panel.</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-8556 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2021/05/4-AjustesCompilacion.jpg" alt="" width="596" height="355" srcset="https://blog.xojo.com/wp-content/uploads/2021/05/4-AjustesCompilacion.jpg 596w, https://blog.xojo.com/wp-content/uploads/2021/05/4-AjustesCompilacion-300x179.jpg 300w" sizes="auto, (max-width: 596px) 100vw, 596px" /></p>
<p>Next, click on the <code>Build</code> button in Xojo&#8217;s IDE toolbar. Once the app is compiled, you&#8217;ll get a Folder/Directory with the following items inside:</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-8557 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2021/05/5-BuiltApp.png" alt="" width="626" height="341" srcset="https://blog.xojo.com/wp-content/uploads/2021/05/5-BuiltApp.png 626w, https://blog.xojo.com/wp-content/uploads/2021/05/5-BuiltApp-300x163.png 300w" sizes="auto, (max-width: 626px) 100vw, 626px" /></p>
<p>This is the folder you will copy to the server. I&#8217;m using the <a href="https://cyberduck.io">Cyberduck</a> app on macOS but you can choose any method you like.</p>
<h2>4. Copying the App Folder to the Server</h2>
<p>Make sure to copy the folder with the compiled app to the <code>/var/XojoApps</code> path on the server (you&#8217;ll need to create that folder/directory first). Once all the files have been copied, make sure to set <code>750</code> as the privileges value for the folder and files (choose the option to apply these recursively to all of them).</p>
<p><img loading="lazy" decoding="async" class="size-large wp-image-8568 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2021/05/SFTP-CopyFiles-1024x462.png" alt="" width="1024" height="462" srcset="https://blog.xojo.com/wp-content/uploads/2021/05/SFTP-CopyFiles-1024x462.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/05/SFTP-CopyFiles-300x135.png 300w, https://blog.xojo.com/wp-content/uploads/2021/05/SFTP-CopyFiles-768x346.png 768w, https://blog.xojo.com/wp-content/uploads/2021/05/SFTP-CopyFiles.png 1426w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></p>
<h2>5. Installing Nginx</h2>
<p>If the server doesn&#8217;t have <a href="http://nginx.com">Nginx</a> already installed, install it now. Nginx is a light web server which provides more performance when compared with Apache (that is, it is able to serve more requests per second, among other improvements).</p>
<p>To install Nginx, access the remote server using SSH:</p>
<pre>&gt; SSH root@xxx.xxx.xxx.xxx</pre>
<p>Once the new session is open, type the following commands to install Nginx:</p>
<pre>$ sudo apt update
$ sudo apt install nginx</pre>
<h2></h2>
<h2>6. (Really) Basic Firewall Configuration</h2>
<p>Let&#8217;s tackle the firewall. It will need to accept incoming connections from Nginx. Nginx registers itself as a <a href="https://en.wikipedia.org/wiki/Uncomplicated_Firewall"><code>ufw</code></a> service during its installation. In order to simplify the deployment example, use the most restrictive option allowing only web traffic from port 80:</p>
<pre>$ sudo ufw allow 'Nginx HTTP'</pre>
<p>Type the following command to verify the changes:</p>
<pre>$ sudo ufw status</pre>
<p>The output should be similar to this (in my case access from SSH and 8080 ports are also enabled).</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-8592" src="https://blog.xojo.com/wp-content/uploads/2021/05/7-ufw-status.png" alt="" width="390" height="143" srcset="https://blog.xojo.com/wp-content/uploads/2021/05/7-ufw-status.png 390w, https://blog.xojo.com/wp-content/uploads/2021/05/7-ufw-status-300x110.png 300w" sizes="auto, (max-width: 390px) 100vw, 390px" /></p>
<blockquote><p><strong>Note:</strong> This tutorial does not discuss web security which in the overwhelming majority of cases should be a paramount issue and not ignored. Securing a server is a very complicated process which is why we take care of the for you with <a href="https://www.xojo.com/cloud">Xojo Cloud</a>.</p></blockquote>
<h2>7. Creating a New Nginx &#8220;block&#8221;</h2>
<p>Once Nginx is installed, Ubuntu automatically starts this process, so the web server should be active already. Test this by typing:</p>
<pre>$ systemctl status nginx</pre>
<p>The output  should be similar to this:</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-8559 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2021/05/8-Nginx-Status.png" alt="" width="841" height="192" srcset="https://blog.xojo.com/wp-content/uploads/2021/05/8-Nginx-Status.png 841w, https://blog.xojo.com/wp-content/uploads/2021/05/8-Nginx-Status-300x68.png 300w, https://blog.xojo.com/wp-content/uploads/2021/05/8-Nginx-Status-768x175.png 768w" sizes="auto, (max-width: 841px) 100vw, 841px" /></p>
<p>Once the server is running, create a new server block. Think about this block like the virtual hosts on Apache. They will encapsulate the configuration details and will allow hosting of more than one domain on the same server.</p>
<p>Nginx loads these configuration files from the <code>/etc/nginx/sites-available</code> path. Create a new file using the <code>nano</code> editor:</p>
<pre>$ sudo nano /etc/nginx/sites-available/XojoDemo</pre>
<p>Next type the following block in the resulting new document:</p>
<pre>server	{
listen 80;
listen [::]:80;
root /var/XojoApps/XojoDemo;
index index.html index.htm index.nginx-debian.html;

server_name xxx.xxx.xxx.xxx;

location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:9000;
}
}</pre>
<p>Replace <code>xxx.xxx.xxx.xxx</code> with your server IP address or the server domain (DNS record, if you have one pointing to it). We are instructing Nginx to redirect the traffic from port 80 to 9000 where our web app will be listening.</p>
<p>Save the file and exit <code>nano</code>. Next, enable the file by creating a link from the file to the <code>sites-enabled</code> directory where Nginx reads the configuration files:</p>
<pre>$ sudo ln -s /etc/nginx/sites-available/XojoDemo /etc/nginx/sites-enabled/</pre>
<p>Finally, check for syntax errors in the Nginx configuration files:</p>
<pre>$ sudo nginx -t</pre>
<p><img loading="lazy" decoding="async" class="size-full wp-image-8560 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2021/05/9-Nginx-check.png" alt="" width="486" height="44" srcset="https://blog.xojo.com/wp-content/uploads/2021/05/9-Nginx-check.png 486w, https://blog.xojo.com/wp-content/uploads/2021/05/9-Nginx-check-300x27.png 300w" sizes="auto, (max-width: 486px) 100vw, 486px" /></p>
<p>If everything is Ok, then reload <code>Nginx</code> so it reads the configuration files again and applies the changes:</p>
<pre>$ sudo systemctl restart nginx</pre>
<h2></h2>
<h2>8. Executing the Xojo Web App</h2>
<p>It&#8217;s time to start our Xojo web app and test the access from the web browser of your choice. Change the current path to the one where you copied the web app. In this example:</p>
<pre>$ cd /var/XojoApps/XojoDemo</pre>
<p>Next, start the app by issuing the following command:</p>
<pre>$ ./XojoDemo --port=9000</pre>
<p>Open a new window/tab in the web browser and enter the IP address/web domain pointing to the web server. There is the web app up and running:</p>
<p><img loading="lazy" decoding="async" class="size-large wp-image-8561 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2021/05/10-HolaMundo-1024x592.png" alt="" width="1024" height="592" srcset="https://blog.xojo.com/wp-content/uploads/2021/05/10-HolaMundo-1024x592.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/05/10-HolaMundo-300x174.png 300w, https://blog.xojo.com/wp-content/uploads/2021/05/10-HolaMundo-768x444.png 768w, https://blog.xojo.com/wp-content/uploads/2021/05/10-HolaMundo.png 1070w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></p>
<p>Congrats! Now for the harsh truth. This way of executing web apps is not ideal. Because it started from the SSH session on the server, if we exit or interrupt the SSH connection, the web app will exit and won&#8217;t be accessible anymore for anyone. This problem also results in a 504 Gateway Time-Out page served by Nginx:</p>
<p><img loading="lazy" decoding="async" class="size-large wp-image-8562 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2021/05/11-TimeOut-1024x592.png" alt="" width="1024" height="592" srcset="https://blog.xojo.com/wp-content/uploads/2021/05/11-TimeOut-1024x592.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/05/11-TimeOut-300x174.png 300w, https://blog.xojo.com/wp-content/uploads/2021/05/11-TimeOut-768x444.png 768w, https://blog.xojo.com/wp-content/uploads/2021/05/11-TimeOut.png 1070w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></p>
<p>In order to fix this problem, create a <code>Service</code>.  A service will allow the app to run without any intervention, even if there is a server interruption, for example, if the server is restarted or the app crashes.</p>
<h2>9. Creating a Service</h2>
<p>Type the following in the current SSH session:</p>
<pre>$ sudo nano /lib/systemd/XojoDemoApp.service</pre>
<p>Next, type the following snippet of text in the new, opened document (make sure to save the changes once you exit nano).</p>
<pre>[Service]
Type=simple
Restart=always
RestartSec=3
User=root
ExecStart=/var/XojoApps/XojoDemo/XojoDemo --port=9000
[Install]
WantedBy=multi-user.target</pre>
<p>Now that you have exited nano, and with the new service created, activate it with the following commands:</p>
<pre>$ sudo systemctl enable /lib/systemd/XojoDemoApp.service
$ sudo systemctl start XojoDemoApp.service</pre>
<p>Get the service status by typing the following command:</p>
<pre>$ sudo systemctl status XojoDemoApp.service</pre>
<p>You should get an output similar to this:</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-8570 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2021/05/ServiceStatus.png" alt="" width="664" height="134" srcset="https://blog.xojo.com/wp-content/uploads/2021/05/ServiceStatus.png 664w, https://blog.xojo.com/wp-content/uploads/2021/05/ServiceStatus-300x61.png 300w" sizes="auto, (max-width: 664px) 100vw, 664px" /></p>
<p>Now, you can be confident that the Xojo web app will be running even if you close the current SSH connection with the remote server <em>and</em> that it will restart even if the remote server is restarted or the app crashes.</p>
<p>If all of this seems more complex than you care to manage, <a href="https://www.xojo.com/cloud">Xojo Cloud</a> is the easy, powerful and secure way to deploy web apps. Xojo does not provide support for configuring your web server for use with Xojo web apps. To read more about deploying Xojo web apps, visit the Xojo Docs <a href="https://documentation.xojo.com/topics/application_deployment/web/deployment_overview.html">Web Deployment Overview</a> and the <a href="https://documentation.xojo.com/topics/application_deployment/web/deployment_details.html">Web Deployment Details</a> pages.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Setting up puTTY to create a SSH tunnel from Windows to Xojo Cloud</title>
		<link>https://blog.xojo.com/2020/10/29/setting-up-putty-to-create-a-ssh-tunnel-from-windows-to-xojo-cloud/</link>
		
		<dc:creator><![CDATA[Wayne Golding ]]></dc:creator>
		<pubDate>Thu, 29 Oct 2020 10:00:52 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[SSH]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=7644</guid>

					<description><![CDATA[Here’s the configuration document for getting puTTY to connect to the Xojo Cloud database.  You might want to note that while Windows 10 now includes a SSH client it doesn’t support SSH tunnels very well due to always executing a connection command.]]></description>
										<content:encoded><![CDATA[
<p>There are just a few steps to get puTTY to connect to your Xojo Cloud database.&nbsp; You might want to note that while Windows 10 now includes a SSH client, it doesn’t support SSH tunnels very well due to always executing a connection command.</p>



<p>First, expand the SSH tree in the categories list and select tunnels.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="678" height="662" src="https://blog.xojo.com/wp-content/uploads/2020/10/image.png" alt="" class="wp-image-7645" srcset="https://blog.xojo.com/wp-content/uploads/2020/10/image.png 678w, https://blog.xojo.com/wp-content/uploads/2020/10/image-300x293.png 300w" sizes="auto, (max-width: 678px) 100vw, 678px" /></figure>



<p>Add a new forwarded port, here we are using port 5432 for Postgres, but you could also use 3306 for mySQL.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="678" height="664" src="https://blog.xojo.com/wp-content/uploads/2020/10/image-1.png" alt="" class="wp-image-7646" srcset="https://blog.xojo.com/wp-content/uploads/2020/10/image-1.png 678w, https://blog.xojo.com/wp-content/uploads/2020/10/image-1-300x294.png 300w" sizes="auto, (max-width: 678px) 100vw, 678px" /></figure>



<p>Press the &#8220;Add&#8221; button to save the forward and tick the &#8220;Local ports accept connections from other hosts&#8221; checkbox.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="678" height="664" src="https://blog.xojo.com/wp-content/uploads/2020/10/image-2.png" alt="" class="wp-image-7650" srcset="https://blog.xojo.com/wp-content/uploads/2020/10/image-2.png 678w, https://blog.xojo.com/wp-content/uploads/2020/10/image-2-300x294.png 300w" sizes="auto, (max-width: 678px) 100vw, 678px" /></figure>



<p>Select the SSH tree and tick the “Don’t start a shell or command at all&#8221; checkbox. This is the bit missing from the Windows native SSH client.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="678" height="664" src="https://blog.xojo.com/wp-content/uploads/2020/10/image-3.png" alt="" class="wp-image-7651" srcset="https://blog.xojo.com/wp-content/uploads/2020/10/image-3.png 678w, https://blog.xojo.com/wp-content/uploads/2020/10/image-3-300x294.png 300w" sizes="auto, (max-width: 678px) 100vw, 678px" /></figure>



<p>Select &#8220;Session&#8221; at the very top of the categories list and enter your Xojo Cloud IP address along with a session name and Save so you’ll have this configuration available to you next time.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="678" height="664" src="https://blog.xojo.com/wp-content/uploads/2020/10/image-4.png" alt="" class="wp-image-7652" srcset="https://blog.xojo.com/wp-content/uploads/2020/10/image-4.png 678w, https://blog.xojo.com/wp-content/uploads/2020/10/image-4-300x294.png 300w" sizes="auto, (max-width: 678px) 100vw, 678px" /></figure>



<p>Now you can open the connection where you will be prompted for your SSH Username (dbadmin) &amp; password.&nbsp; If this is successful, you will be left with a terminal window that appears to do nothing – leave it open until you want to disconnect.</p>



<p>Once the tunnel is established you can use localhost as the host address of your Postgres or MySQL database. </p>



<p><em>Wayne Golding has been a Xojo developer since 2005 and is a Xojo MVP. He operates the IT Company <a href="http://www.axisdirect.nz">Axis Direct Ltd </a>which primarily develops applications using Xojo that integrate with Xero www.xero.com. Wayne’s hobby is robotics where he uses Xojo to build applications for his Raspberry Pi, often implementing IoT for remote control.</em></p>



<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Quick Tips: Xojo Cloud and Databases</title>
		<link>https://blog.xojo.com/2020/09/02/quick-tips-xojo-cloud-and-databases/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Wed, 02 Sep 2020 10:00:00 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=7209</guid>

					<description><![CDATA[Based on recent conversations with a couple Xojo users, here are a few quick tip for uploading and working with SQLite and MySQL databases on Xojo Cloud.]]></description>
										<content:encoded><![CDATA[<p>Based on recent conversations with a couple Xojo users, here are a few quick tips for uploading and working with SQLite and MySQL databases on Xojo Cloud.</p>
<p>If you aren&#8217;t already familiar with <a href="https://www.xojo.com/cloud/">Xojo Cloud</a>, it&#8217;s simple, secure, maintenance-free hosting for your Xojo web apps. </p>
<p><span id="more-7209"></span></p>
<h3>SQLite Database Tip</h3>
<p>For the first tip, which involves SQLite databases, this is the scenario: Let&#8217;s say you added a SQLite database to the project using a Build step and set the proper Folder/Subfolder, and then you connect to it from the <code>Session.Opening</code> event (or any other, for this case) in order to access its tables.</p>
<p>Even if you are running your Web app in local or debug mode (from the IDE) the connection to the SQLite database works, no matter if you&#8217;re typing the database file name in either upper or lowercase. Remember, when you are deploying the database to Xojo Cloud, you need to pass along the database name using the proper lowercase and uppercase characters in its original name.</p>
<p>Let&#8217;s suposse that the original database name on disk is &#8220;MyPrettyDatabase.sqlite&#8221;, then you&#8217;re using the following code in order to connect to it:</p>
<pre>#if DebugBuild then
    f=SpecialFolder.Desktop.Child("myprettydatabase.sqlite")
#else
    f=specialfolder.documents.child("myprettydatabase.sqlite")
#EndIf

BBDD.DatabaseFile=f

Try

    BBDD.Connect

catch e as IODatabaseException

End Try</pre>
<p>In this case, when running the web app from your computer everything will work fine (because most desktop operating systems use a case-insensitive file system, although Linux is often case-sensitive); but if you deploy the web app to Xojo Cloud you&#8217;ll find yourself with a database that does not connect. Fixing this is as simple as typing the string representing the database filename observing the uppercase characters existing in its original name:</p>
<pre>#if DebugBuild then
    f=SpecialFolder.Desktop.Child("myprettydatabase.sqlite")
#else
    f=specialfolder.documents.child("MyPrettyDatabase.sqlite")
#EndIf

    BBDD.DatabaseFile=f

Try

    BBDD.Connect

catch e as DatabaseException

End Try</pre>
<p><em><strong>SQLite Tip</strong>: Xojo 2020r1 updated to SQLite 3.31.1, which adds some <a href="https://blog.xojo.com/2020/08/31/sqlite-3-31-1-new-features/">cool new features</a>!</em></p>
<h3>MySQL/MariaDB Database Tip</h3>
<p>The second problem we&#8217;re solving involves the connection with MySQL/MariaDB databases hosted on a remote server from your Xojo Cloud app.</p>
<p>Although connecting to a remote MySQL database is <a href="https://documentation.xojo.com/api/databases/mysqlcommunityserver.html">well documented here</a>, let&#8217;s review. If you need to establish this kind of connection, remember to open the Xojo Cloud firewall port first.</p>
<p>For example, something like this code snippet will let the web app work when deployed on Xojo Cloud and when you are doing a local test running it from the IDE (debug mode):</p>
<pre>#If TargetXojoCloud
    Var fwp As New XojoCloud.FirewallPort(3306, XojoCloud.FirewallPort.Direction.Outgoing)
    fwp.Open
    If fwp.isOpen Then
        connectDatabase
    End If
#Else
    ConnectDatabase
#EndIf</pre>
<p>Where, in this case, ConnectDatabase is the method in charge of doing the real connection setting the usual parameters agains the MySQLCommunityServer instance.</p>


<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The Modern Control Panel + 4 More Powerful Features New in Xojo Cloud</title>
		<link>https://blog.xojo.com/2020/08/27/modern-control-panel-powerful-features-new-xojo-cloud/</link>
		
		<dc:creator><![CDATA[Geoff Perlman]]></dc:creator>
		<pubDate>Thu, 27 Aug 2020 11:17:00 +0000</pubDate>
				<category><![CDATA[Security]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[App Hosting]]></category>
		<category><![CDATA[CGI]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=7389</guid>

					<description><![CDATA[Our vision for Xojo Cloud is a simple, one-click deployment option for your web app. Xojo Cloud allows you to focus on developing your app instead of dealing with the nitty gritty details of web hosting and security. Xojo Cloud has tons of new stuff to compliment apps built with Xojo 2020r1! ]]></description>
										<content:encoded><![CDATA[
<p>Our vision for Xojo Cloud has always been a simple, safe, one-click deployment option for your web apps. Xojo Cloud allows you to focus on developing your apps instead of dealing with the nitty gritty details of web hosting and security. Xojo Cloud has tons of new stuff to compliment apps built with Xojo 2020r1! </p>



<p>Here&#8217;s what&#8217;s new:</p>



<ul class="wp-block-list"><li>Apps deployed to Xojo Cloud are now 64-bit stand-alone apps for better security and faster performance*</li><li>Apps deployed to Xojo Cloud are now automatically load-balanced to support more concurrent users</li><li>Domains can now be <a href="https://documentation.xojo.com/index.php?title=UserGuide:Xojo_Cloud_General_Information&amp;oldid=71856#Pointing_Your_Domain_or_SubDomain_at_A_Specific_Xojo_Cloud_App">pointed at individual web apps</a></li><li>Unique <a href="https://documentation.xojo.com/index.php?title=UserGuide:Xojo_Cloud_General_Information&amp;oldid=71856#Using_A_XojoCloud.Net_Subdomain">subdomains are available</a> on the xojocloud.net domain for users who don&#8217;t have dedicated app domains</li><li>Manage team members and grant access to your server directly from the all-new, made-with-Xojo, <a href="https://documentation.xojo.com/topics/xojo_cloud/introduction_to_xojo_cloud.html_Control_Panel">Xojo Cloud Control Panel</a></li></ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="800" height="484" src="https://blog.xojo.com/wp-content/uploads/2020/08/Xojo-Cloud-Control-Panel.jpg" alt="" class="wp-image-7390" srcset="https://blog.xojo.com/wp-content/uploads/2020/08/Xojo-Cloud-Control-Panel.jpg 800w, https://blog.xojo.com/wp-content/uploads/2020/08/Xojo-Cloud-Control-Panel-300x182.jpg 300w, https://blog.xojo.com/wp-content/uploads/2020/08/Xojo-Cloud-Control-Panel-768x465.jpg 768w" sizes="auto, (max-width: 800px) 100vw, 800px" /></figure>



<p>Xojo Cloud eliminates the complicated process of deploying a web application; it requires no configuration, includes security, automatic backups and predictable pricing. Xojo Cloud servers are available in locations around the globe and start at <a href="https://www.xojo.com/store/#cloud">just $49/month</a>. More details about using Xojo Cloud can be found in the <a href="https://documentation.xojo.com/topics/xojo_cloud/introduction_to_xojo_cloud.html">User&#8217;s Guide</a>.</p>



<p>*CGI-based web apps built with previous versions of Xojo are still supported.</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>Xojo 2020 Video Update</title>
		<link>https://blog.xojo.com/2020/03/25/xojo-2020-video-update/</link>
		
		<dc:creator><![CDATA[Dana Brown]]></dc:creator>
		<pubDate>Wed, 25 Mar 2020 18:41:39 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[XDC]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[XOJO.CONNECT]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=6795</guid>

					<description><![CDATA[As you may have heard, we had to make the difficult decision to cancel XOJO.CONNECT 2020 in Nashville. Since we know you were waiting to&#8230;]]></description>
										<content:encoded><![CDATA[
<p>As you may have heard, we had to make the difficult decision to <a rel="noreferrer noopener" href="https://xojo.com/xdc/" target="_blank">cancel</a> XOJO.CONNECT 2020 in Nashville. Since we know you were waiting to hear all of our exciting news, we have put together some videos for you all to enjoy. </p>



<p>2020 is going to be a very exciting year for Xojo &#8211; we finally see the finish line for several of our multi-year projects! Starting now you can watch <a rel="noreferrer noopener" href="https://youtu.be/oi5MCrDlpsg" target="_blank">Geoff&#8217;s 2020 Update</a> to get an overview of what&#8217;s been going on behind the scenes at Xojo and what to expect this year. Then, check out our Android update with Paul and Web 2.0 with Greg videos below!</p>



<hr class="wp-block-separator"/>



<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Xojo 2020 with Geoff Perlman" width="500" height="281" src="https://www.youtube.com/embed/oi5MCrDlpsg?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Xojo Programming - Android Update" width="500" height="281" src="https://www.youtube.com/embed/rQBe-Cp-0x8?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Xojo Programming - Web Framework 2.0 Update" width="500" height="281" src="https://www.youtube.com/embed/mJE_S9cMK1s?start=1&#038;feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Xojo 2020 Q&amp;A with Geoff Perlman" width="500" height="281" src="https://www.youtube.com/embed/0QVRI2hEezE?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>3 Steps to Seamlessly Deploy SQLite Projects on Desktop, Web &#038; iOS</title>
		<link>https://blog.xojo.com/2020/03/17/3-steps-to-seamlessly-deploy-sqlite-projects-on-desktop-web-ios/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Tue, 17 Mar 2020 10:00:25 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[Deployment]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Object-Oriented]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=6725</guid>

					<description><![CDATA[This tutorial will show you how to deploy your SQLite based projects so they behave right on Desktop, Web and iOS, copying the database file to the right place on every target.]]></description>
										<content:encoded><![CDATA[<p>This tutorial will show you how to deploy your SQLite based projects so they behave right on Desktop, Web and iOS, copying the database file to the right place on every target.</p>
<h2>1. Adding the database file</h2>
<p>You probably created your SQLite database file using an external editor; so first add that file to your Xojo project.</p>
<p>You can do that in several ways, but usually it&#8217;s best to add a Build Step. This way, the file will be added automatically to the folder of your choice every time you compile your app. <em>Bonus: Doing this allows you to decide to use different paths when debugging or deploying your app.</em></p>
<p>In order to add a new Build Step in a <span style="text-decoration: underline;">Desktop</span> project select the target in the Build Settings then, from the contextual menu, choose the &#8220;Add to Build Settings &gt; Build Step &gt; Copy Files&#8221; option.</p>
<p><img loading="lazy" decoding="async" class="size-medium wp-image-6726 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2020/03/Screenshot-2020-03-04-at-12.37.51-300x70.png" alt="" width="300" height="70" srcset="https://blog.xojo.com/wp-content/uploads/2020/03/Screenshot-2020-03-04-at-12.37.51-300x70.png 300w, https://blog.xojo.com/wp-content/uploads/2020/03/Screenshot-2020-03-04-at-12.37.51.png 655w" sizes="auto, (max-width: 300px) 100vw, 300px" /></p>
<p>The previous action will give you access to the Inspector Panel for the just-added item where you will be able to type a name for the Build Step, choose if the copy file action will be executed both for debugging or deployment and, most importantly, choose the location where the file should be copied when the app compiles.</p>
<p>In fact, the Destination menu contains a number of typical paths (or most relevant folders). For example, a good Destination option would be &#8220;Resources Folder&#8221;. Of course, don&#8217;t forget to add the database file itself using the buttons on the Build Editor toolbar.</p>
<p><img loading="lazy" decoding="async" class="size-medium wp-image-6727 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2020/03/Screenshot-2020-03-04-at-12.42.04-300x173.png" alt="" width="300" height="173" srcset="https://blog.xojo.com/wp-content/uploads/2020/03/Screenshot-2020-03-04-at-12.42.04-300x173.png 300w, https://blog.xojo.com/wp-content/uploads/2020/03/Screenshot-2020-03-04-at-12.42.04.png 359w" sizes="auto, (max-width: 300px) 100vw, 300px" /></p>
<p>When you&#8217;re working with a <span style="text-decoration: underline;">Web project</span>, you&#8217;ll find exactly the same behavior, even if you choose to deploy with Xojo Cloud.</p>
<p>On <span style="text-decoration: underline;">iOS</span>, the only change is that you&#8217;ll have to choose the icon with an iPhone picture in it in order to access the Build Step contextual menu; in addition to the fact that every added resource needs to be signed with a certificate.</p>
<p><img loading="lazy" decoding="async" class="size-medium wp-image-6728 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2020/03/Screenshot-2020-03-04-at-12.43.45-300x47.png" alt="" width="300" height="47" srcset="https://blog.xojo.com/wp-content/uploads/2020/03/Screenshot-2020-03-04-at-12.43.45-300x47.png 300w, https://blog.xojo.com/wp-content/uploads/2020/03/Screenshot-2020-03-04-at-12.43.45.png 608w" sizes="auto, (max-width: 300px) 100vw, 300px" /></p>
<h2>2. Copying the database file to a &#8220;Working&#8221; folder</h2>
<p>You may think that the previous step is all you need to do, because if the database file is already copied in a well know path then you only need to provide that path as the DatabaseFile property on a new SQLiteDatabase or iOSSQLiteDatabase instance. But this is not the case.</p>
<p>They are many reasons you shouldn&#8217;t do that, specifically because the database would be open in read/write mode and if you write to that database file inside an application bundle, then you&#8217;ll be modifying a resource that would invalidate any certificate signature on your app.</p>
<p>The best thing to do is o detect every time you run the app if the database file has already been copied from the app bundle (or folder) into a target folder that doesn&#8217;t have an access problem when it is time to use the database. The Application Support folder is a good place for Desktop apps, while the Documents folder is fine for Xojo Cloud and iOS apps.</p>
<p>For example, if our database file is named &#8220;EddiesElectronics.sqlite&#8221; and our app name is &#8220;Xojotest&#8221;, then we can add the following code fragment into the Open Event Handler of a Desktop app:</p>
<pre>Var source As FolderItem = SpecialFolder.Resource("EddiesElectronics.sqlite")
Var name As String = app.ExecutableFile.name.NthField(".",1)

// We check if there is a folder with the App name in special Application Data
// if not, we create it and copy the database file from Resources bundle/directory
If Not (SpecialFolder.ApplicationData.Child(name).Exists And SpecialFolder.ApplicationData.Child(name).IsFolder) Then SpecialFolder.ApplicationData.Child(name).CreateFolder
If Not SpecialFolder.ApplicationData.child(name).child(source).exists Then source.CopyTo(SpecialFolder.ApplicationData.Child(name))

Try
  // Create a SQLiteDatabase instance and try to open our database file from
  // the path
  pDatabase = New SQLiteDatabase
  pDatabase.DatabaseFile = SpecialFolder.ApplicationData.Child(name).Child("EddiesElectronics.sqlite")
  pDatabase.Connect

Catch e As DatabaseException
  MessageBox e.Message
End Try</pre>
<p>For an iOS app, the code would be:</p>
<pre>Var source As Xojo.IO.FolderItem = xojo.io.SpecialFolder.GetResource("EddiesElectronics.sqlite")

// We check if there is our database file already copied on the Documents Sandbox folder
// if not, we copy the database file from Resources bundle/directory
If Not xojo.io.SpecialFolder.Documents.Child("EddiesElectronics.sqlite").Exists Then
  source.CopyTo(xojo.io.SpecialFolder.documents)
End If

Try
  // Create a SQLiteDatabase instance and try to open our database file from
  // the path
  pDatabase = New iosSQLiteDatabase

  Var f As FolderItem = xojo.io.SpecialFolder.Documents
  pDatabase.DatabaseFile = f.Child("EddiesElectronics.sqlite")
  Call pDatabase.Connect

Catch e As RuntimeException
  MessageBox e.Reason
End Try</pre>
<p>If you&#8217;re working on Xojo Cloud, the code will be even shorter. First, make sure that the Copy File Build Step has the following values in the Inspector Panel:</p>
<ul>
<li><strong>Destination:</strong> Contents Folder</li>
<li><strong>Subdirectory:</strong> Documents</li>
</ul>
<p>Then, the code will be:</p>
<pre>Try
  pDatabase = new SQLiteDatabase
  pDatabase.DatabaseFile = SpecialFolder.Documents.Child("EddiesElectronics.sqlite")
  pDatabase.connect
Catch e as RuntimeException
  MessageBox e.Reason
End Try</pre>
<p>What about a Web app that you host? That would mean you are in control about the folder/directory you want to use to store the app resources. Thus, it wouldn&#8217;t make much sense to automatize this process (but it is certainly doable following the same principles).</p>
<h2>3. Simplifying the process</h2>
<p>What we have seen already works, but that means that you need to change the file database name and probably that would change on every app you build. That also means that you&#8217;ll have to write the same code snippet again and again on every new app. Wouldn&#8217;t it be great to be able to extend the SQLiteDatabase and iOSSQLiteDatabase classes in order to simplify that?</p>
<p>Well, you can do that! Start by adding a new Module to the example project (for example one named &#8220;DatabaseExtensions&#8221;) with a couple of methods on it. The first method will be the one executed on our Desktop, Web and Console apps, because all of these targets use the SQLiteDatabase class.</p>
<p>So, add a new method using the following signature in the just-created module:</p>
<pre>OpenDatabase( databaseName as String )</pre>
<p>It extends the SQLiteDatabase class, adding a new method that takes as parameter the name of the file we want to copy on the &#8220;work&#8221; folder/directory.</p>
<p>The code you should type on this method is:</p>
<pre>pDatabase = New SQLiteDatabase

#If TargetDesktop Or TargetConsole Or TargetWeb Then

  Var source As FolderItem = SpecialFolder.Resource( databaseName )
  Var name As String = app.ExecutableFile.name.NthField(".",1)
  // We check if there is a folder with the App name in special Application Data
  // if not, we create it and copy the database file from Resources bundle/directory
  If Not (SpecialFolder.ApplicationData.Child(name).Exists And SpecialFolder.ApplicationData.Child(name).IsFolder) Then
SpecialFolder.ApplicationData.Child(name).CreateFolder
If Not SpecialFolder.ApplicationData.Child(nam).Child(Source).exists Then source.CopyTo(SpecialFolder.ApplicationData.Child(name))

  Try
    // Create a SQLiteDatabase instance and try to open our database file from
    // the path
    pDatabase.DatabaseFile = SpecialFolder.ApplicationData.Child(name).Child(databaseName)
    pDatabase.Connect

  Catch e As DatabaseException
    MessageBox e.Message
  End Try

#ElseIf TargetXojoCloud
  Try
    pDatabase.DatabaseFile = SpecialFolder.Documents.Child( databaseName )
    pDatabase.connect
  Catch e As RuntimeException
    MessageBox e.Reason
  End Try
#EndIf</pre>
<p>Of course, we need to add the &#8220;pDatabase&#8221; property to our module too: pDatabase As SQLiteDatabase</p>
<p>Now, you&#8217;ll only need to use:</p>
<pre>OpenDatabase("EddiesElectronics.sqlite")</pre>
<p>With the method selected in the Project Browser, click on the Attributes section of the Inspector Panel (the Cog Wheel icon), and uncheck the &#8220;iOS 64&#8221; checkbox. This way, that method will not be included when compiling for iOS apps.</p>
<p><img loading="lazy" decoding="async" class="size-medium wp-image-6729 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2020/03/Captura-de-pantalla-2020-03-09-a-las-6.55.49-281x300.png" alt="" width="281" height="300" srcset="https://blog.xojo.com/wp-content/uploads/2020/03/Captura-de-pantalla-2020-03-09-a-las-6.55.49-281x300.png 281w, https://blog.xojo.com/wp-content/uploads/2020/03/Captura-de-pantalla-2020-03-09-a-las-6.55.49.png 420w" sizes="auto, (max-width: 281px) 100vw, 281px" /></p>
<p>Do the same thing with the &#8220;pDatabase&#8221; property, so it is only compiled on the supported targets.</p>
<p>The second method is the one we will be using for iOS apps. The method signature would be:</p>
<pre>OpenDatabase(databseName as String)</pre>
<p>And typing the following fragment of code in the associated Code Editor:</p>
<pre>pIOSDatabase = New iOSSQLiteDatabase

Var source As Xojo.IO.FolderItem = xojo.io.SpecialFolder.GetResource( databaseName )

// We check if there is our database file already copied on the Documents Sandbox folder
// if not, we copy the database file from Resources bundle/directory
If Not xojo.io.SpecialFolder.Documents.Child( databaseName ).Exists Then
  source.CopyTo(xojo.io.SpecialFolder.documents)
End If

Try
  // Create a SQLiteDatabase instance and try to open our database file from
  // the path

  Var f As FolderItem = xojo.io.SpecialFolder.Documents
  pIOSDatabase.DatabaseFile = f.Child( databaseName )
  Call db.Connect

Catch e As RuntimeException
  MessageBox e.Reason
End Try</pre>
<p><img loading="lazy" decoding="async" class="size-medium wp-image-6730 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2020/03/Captura-de-pantalla-2020-03-09-a-las-6.55.27-282x300.png" alt="" width="282" height="300" srcset="https://blog.xojo.com/wp-content/uploads/2020/03/Captura-de-pantalla-2020-03-09-a-las-6.55.27-282x300.png 282w, https://blog.xojo.com/wp-content/uploads/2020/03/Captura-de-pantalla-2020-03-09-a-las-6.55.27.png 423w" sizes="auto, (max-width: 282px) 100vw, 282px" /></p>
<p>Lastly, and with the method item still selected in the Project Browser, go to the Attributes section of the Inspector Panel and make sure that the &#8220;iOS 64&#8221; checkbox is the only one selected under the &#8220;Include In&#8221; section. This way, we make sure that the method will be compiled only on iOS targets.</p>
<p>And do the same thing with the &#8220;piOSDatabase&#8221;, so it is only compiled for iOS targets.</p>
<h2>To Summarize</h2>
<p>As we see, the use of Modules in combination with OOP Class Extension is a good way to get more flexibility when developing your apps; using a common function (or method) name no matter if you are working on Desktop, Web or iOS. Additionally, that leads to a more convenient reutilization of your codeand, of course, less code to maintain through all our projects!</p>
<p>(You can find this article in Spanish <a href="https://www.aprendexojo.com/2020/03/prepara-bases-de-datos-sqlite-para-despliegue-en-desktop-web-y-ios/">here</a>)</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Setting up SSL in Xojo Cloud</title>
		<link>https://blog.xojo.com/2019/04/19/setting-up-ssl-in-xojo-cloud/</link>
		
		<dc:creator><![CDATA[Xojo]]></dc:creator>
		<pubDate>Fri, 19 Apr 2019 10:00:17 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[App Hosting]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[SSL]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=5683</guid>

					<description><![CDATA[Setting up SSL in Xojo Cloud is as simple as adding your domain name. ]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-5684" src="https://blog.xojo.com/wp-content/uploads/2019/04/XojoCloudSSL.gif" alt="" width="1232" height="1080" /></p>
<p><span id="more-5683"></span></p>
<p>that&#8217;s the simplicity of Xojo Cloud.</p>
<ol>
<li>click &#8220;Set Up SSL&#8221;,</li>
<li>type your domain,</li>
<li>click &#8220;Enable SSL&#8221;</li>
</ol>
<p>SSL Done.</p>
<p>Learn more about <a href="https://www.xojo.com/cloud/">Xojo Cloud</a>, read the <a href="https://documentation.xojo.com/topics/xojo_cloud/introduction_to_xojo_cloud.html_Control_Panel">User Guide</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Change your DNS settings for a smooth transition to a bigger, better server</title>
		<link>https://blog.xojo.com/2019/03/13/change-your-dns-settings-for-a-smooth-transition-to-a-bigger-better-server/</link>
		
		<dc:creator><![CDATA[Jason Parsley]]></dc:creator>
		<pubDate>Wed, 13 Mar 2019 10:00:51 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[DNS]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=5516</guid>

					<description><![CDATA[But moving your projects from one server to another is easier said than done. You'll need to plan carefully to avoid downtime. Here is a simple change you can make to your DNS settings in order to limit downtime, making the move to a better server smoother.]]></description>
										<content:encoded><![CDATA[<p>Most <a href="https://www.xojo.com/cloud/">Xojo Cloud</a> users have already switched to the newer Xojo Cloud servers. These new servers have more RAM and SSDs and are the priced lower or the same as our previous servers. But moving your projects from one server to another is easier said than done. You&#8217;ll need to plan carefully to avoid downtime. Here is a simple change you can make to your DNS settings in order to limit downtime, making the move to a better server smoother.</p>
<p><span id="more-5516"></span></p>
<p>The current A record in your DNS settings points to your existing Xojo Cloud server&#8217;s IP address and probably has a TTL (time to live) of 24 hours. At least 24 hours before you plan to move your server data and change the IP address, set the TTL to 5 minutes. Doing this means that you can change the IP address to your new server IP address and most of the DNS servers out there should pick up on the change in around 5 minutes.</p>
<p>After you have made the move to the new server, you should set your TTL back to 24 hours, or whatever it was set to previously. And that&#8217;s it!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>5 Reasons to Rely on Cloud Services</title>
		<link>https://blog.xojo.com/2018/04/23/5-reasons-to-rely-on-cloud-services/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Mon, 23 Apr 2018 10:00:02 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[Cloud]]></category>
		<guid isPermaLink="false">http://blog.xojo.com/?p=2730</guid>

					<description><![CDATA[The Cloud is everywhere these days. And lots of companies offer Cloud products or services. Why should you use them?]]></description>
										<content:encoded><![CDATA[<p>The Cloud is everywhere these days. And lots of companies offer Cloud products or services. Why should you use them?</p>
<p><span id="more-2730"></span></p>
<p><strong>1. Synchronized Data</strong><br />
A big benefit of using a cloud product over something installed on your computer (or device) is that your data is available anywhere you have an Internet connection. You can work on a document in the cloud when you are working from home and it will be immediately available to you when you go back to the office.</p>
<p align="center"><img loading="lazy" decoding="async" src="https://www.xojo.com/cloud/cloud10.jpg" alt="Cloud Hosting" width="300" height="197" /></p>
<p><strong>2. Easy Installation</strong><br />
Or more precisely, no installation. To use cloud software, you just have to enter the URL in your web browser. You don’t have to download and install software. Nor do you have to worry about upgrading anything. It’s all transparent and easy for you.</p>
<p><strong>3. No Administration</strong><br />
Sometimes you can install software on your own web server to get cloud benefits without having to pay for a service. This is useful, but you still are left with having to do the installation, manage security and handle upgrades yourself all of which can take significant time and expertise. If you go with a cloud service, you let the service provider do all that work for you.</p>
<p><strong>4. Consistent Pricing</strong><br />
With a cloud service, pricing is typically a small amount per month. This has the benefit of being a predictable expense that can be far easier to justify to management than something with a large up-front cost. And many cloud services providers offer an alternative up-front yearly payment at a reduced rate for those that want to save money.</p>
<p><strong>5. No Worries</strong><br />
Essentially, with cloud services you don’t have to worry about maintaining the software you use to do your job. You only have to worry about doing your job.</p>
<p>Want to create your own cloud software or services? Consider using <a href="http://www.xojo.com/cloud">Xojo with Xojo Cloud hosting</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Xojo Cloud Server Stats</title>
		<link>https://blog.xojo.com/2018/04/18/xojo-cloud-server-stats/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Wed, 18 Apr 2018 16:01:32 +0000</pubDate>
				<category><![CDATA[Xojo Cloud]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=4133</guid>

					<description><![CDATA[Xojo 2018 Release 1 has a new feature for Xojo Cloud users: Xojo Cloud Server Stats. You can now get statistics for your Xojo Cloud Server and its running apps from the Xojo IDE itself]]></description>
										<content:encoded><![CDATA[<p>Xojo 2018 Release 1 has a new feature for Xojo Cloud users: Xojo Cloud Server Stats.</p>
<p><span id="more-4133"></span></p>
<p>You can now get statistics for your Xojo Cloud Server and its running apps from the Xojo IDE itself. To display the Statistics window, open any Web project, select Xojo Cloud in the Build Settings, select your Server and then click the Show button next to the Statistics property.</p>
<p>This displays the server statistics window:</p>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-4156" src="https://blog.xojo.com/wp-content/uploads/2018/04/XojoCloudStats.png" alt="" width="600" height="379" /></p>
<p>Use the drop-down in the window to show stats for the apps you have running on the server.</p>
<p>You need to first deploy an app to Xojo Cloud before statistics will be available.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Do I need a Xojo Cloud server during development?</title>
		<link>https://blog.xojo.com/2017/10/10/do-i-need-a-xojo-cloud-server-during-development/</link>
		
		<dc:creator><![CDATA[Geoff Perlman]]></dc:creator>
		<pubDate>Tue, 10 Oct 2017 10:00:00 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[webdev]]></category>
		<guid isPermaLink="false">http://blogtemp.xojo.com/2015/06/10/do-i-need-a-xojo-cloud-server-during-development/</guid>

					<description><![CDATA[You can develop your application on your own computer and sign up for a Xojo Cloud server when you are getting close to deployment and are ready to test in as close to a real world situation as possible. There are differences of course between how a web app will execute on your computer with a single user (you) versus on a server that is anywhere from hundreds to thousands of miles away with many users connected all at the same time. For the most part, you don't have to think very much about this but there are areas where you should.]]></description>
										<content:encoded><![CDATA[<p>If you are just starting the development of your first web app you may be wondering if you need to get a <a href="http://www.xojo.com/cloud">Xojo Cloud</a> server right away. In most cases, the answer is no. You can develop your application on your own computer and sign up for a Xojo Cloud server when you are getting close to deployment and are ready to test in as close to a real world situation as possible.</p>
<p>There are differences of course between how a web app will execute on your computer with a single user (you) versus on a server that is anywhere from hundreds to thousands of miles away with many users connected all at the same time. For the most part, you don&#8217;t have to think very much about this but there are areas where you should.</p>
<p>Keep the following 3 things in mind when developing without a cloud server.</p>
<p><span id="more-241"></span></p>
<h3>Database Connections</h3>
<p>If your application is accessing a database server, your code should test the database connection each time you use it. Some servers, such as MySQL, will drop idle connections in low memory situations. That&#8217;s something you may never run into while testing your app on your own. During development testing you can load thousands of rows into a listbox and not even notice it. In the real world, that&#8217;s likely to be a problem so you&#8217;ll want to find a way to reduce the number of rows you load into a listbox.</p>
<h3>Data Processing</h3>
<p>If you have a function that is processor-intensive and takes a while to finish, you may want to move that to a separate console app. Xojo web apps execute on a single core so creating helper apps for data processing jobs allows you to move this work to other available cores and will keep your app more responsive. Even if your particular Xojo Cloud server has a single core, by building it to take advantage of multiple cores, you can easily upgrade to a larger, multicore server when you need the extra power.</p>
<h3>Installing Updates</h3>
<p>You&#8217;ll also want to think about what you want the user experience to be when you update the app. When you install an update to your web app, Xojo Cloud will quit your existing app to install the update and all users will be unexpectedly disconnected. <span style="line-height: 1.62;">If your app has a login you&#8217;ll want to provide a way to prevent new users from logging in and notify existing users that the app will be down for a few minutes.</span></p>
<p><span style="line-height: 1.62;">If your app writes out files, you will want to update your code so that when it&#8217;s running on Xojo Cloud, it writes these files out to the Shared Documents directory if you want these files to remain when you install an update to your app. Use <a title="TargetXojoCloud" href="http://documentation.xojo.com/index.php/TargetXojoCloud" target="_blank" rel="noopener noreferrer">TargetXojoCloud</a> to determine if your app is running on Xojo Cloud or not.</span></p>
<p>If you keep these things in mind while developing your app, you should only need to set up a Xojo Cloud server when you are ready to start beta testing your application.*</p>
<p>*Though it&#8217;s a secure and easy option for hosting your web app, you&#8217;re never required to use Xojo Cloud and can deploy your web apps as <a href="http://developer.xojo.com/userguide/web-app-deployment-overview">CGI or Standalone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
