<?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>JSON &#8211; Xojo Programming Blog</title>
	<atom:link href="https://blog.xojo.com/tag/json/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, 04 Nov 2024 20:40:06 +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>Create Fast RESTful APIs in Xojo</title>
		<link>https://blog.xojo.com/2024/10/14/create-fast-restful-apis-in-xojo/</link>
		
		<dc:creator><![CDATA[Gabriel Ludosanu]]></dc:creator>
		<pubDate>Mon, 14 Oct 2024 12:01:31 +0000</pubDate>
				<category><![CDATA[Learning]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[API Development]]></category>
		<category><![CDATA[Backend Development]]></category>
		<category><![CDATA[Client-Server Architecture]]></category>
		<category><![CDATA[Data Communication]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Microservices]]></category>
		<category><![CDATA[Server-Side Programming]]></category>
		<category><![CDATA[Web API]]></category>
		<category><![CDATA[Web Service]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13881</guid>

					<description><![CDATA[Application programming interfaces (APIs) are essential for enabling digital interactions. They facilitate communication and data sharing between systems, forming the backbone of many applications and&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Application programming interfaces (APIs) are essential for enabling digital interactions. They facilitate communication and data sharing between systems, forming the backbone of many applications and services.</p>



<p>This article examines Xojo&#8217;s capabilities by building a simple web API service. You will learn to handle different HTTP methods, manage requests, and send meaningful responses. Xojo&#8217;s simplicity makes it an excellent choice for experienced developers transitioning from other languages, as well as those familiar with its user-friendly language.</p>



<h3 class="wp-block-heading">Foundation: The HandleURL Function</h3>



<div class="wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-ad2f72ca wp-block-group-is-layout-flex">
<p>At the heart of every Xojo-developed web API service is the <a href="https://documentation.xojo.com/api/web/webapplication.html#webapplication-handleurl" target="_blank" rel="noreferrer noopener">HandleURL</a> function, included in the App class, responsible for handling the request-response cycle. It receives incoming web requests (<a href="https://documentation.xojo.com/api/web/webrequest.html" target="_blank" rel="noreferrer noopener">WebRequest</a>), processes them based on their characteristics, and crafts appropriate responses (<a href="https://documentation.xojo.com/api/web/webresponse.html" target="_blank" rel="noreferrer noopener">WebResponse</a>) to send back.</p>
</div>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="286" height="79" src="https://blog.xojo.com/wp-content/uploads/2024/10/image.png" alt="" class="wp-image-13882"/></figure>
</div>


<h3 class="wp-block-heading">Defining API Endpoints for GET Requests</h3>



<p>GET requests are primarily used to retrieve data. To handle these requests effectively, let&#8217;s see how to define API endpoints that correspond to specific data or actions in the following code example:</p>



<pre class="wp-block-code"><code>If request.Method = "GET" Then
  Select Case request.Path
  <strong>Case "time"</strong>
    Var currentTime As String = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
    response.Write("{""message"": """ + currentTime + """}")
    response.Status = 200
    Return True
  <strong>Case "hello"</strong>
    response.Write("{""message"": ""Hello, World!""}")
    response.Status = 200
    Return True
  End Select
End If</code></pre>



<p>Here, we define two endpoints: /time and /hello.</p>



<p>A GET request to /time will return the current date and time in JSON format, while a request to /hello will return a friendly &#8220;Hello, World!&#8221; greeting.</p>



<p>The response.Status is set to 200, indicating a successful response. Learn more here about <a href="https://en.wikipedia.org/wiki/List_of_HTTP_status_codes" data-type="link" data-id="https://en.wikipedia.org/wiki/List_of_HTTP_status_codes" target="_blank" rel="noreferrer noopener">HTTP status codes</a>.</p>



<h3 class="wp-block-heading">Defining API Endpoints for POST Requests</h3>



<p>While GET requests primarily retrieve data, POST requests submit data to the API for processing. Consider submitting a form online – you are sending data to the server via a POST request.</p>



<pre class="wp-block-code"><code>If request.Method = "POST" Then
  Select Case request.Path
  <strong>Case "some-data"</strong>
    Try
      Var jReceivedData As New JSONItem(request.Body)
      Response.Write(jReceivedData.ToString)
      Response.Status = 200
      Return True
    Catch e As JSONException
      response.Write("{""error"": ""Internal Server Error""}")
      response.Status = 500
      Return True
    End Try
  End Select
End If</code></pre>



<p>In this example, a POST request to the /some-data endpoint expects to receive JSON data (<a href="https://documentation.xojo.com/api/web/webrequest.html#webrequest-body" target="_blank" rel="noreferrer noopener">request.Body</a>) for processing.</p>



<p>If the data is successfully parsed, the API responds with the received data.</p>



<p>Otherwise, an error status and message are returned to the client.</p>



<h3 class="wp-block-heading">Bringing it all Together</h3>



<p>Now that you know how to manage &#8220;GET&#8221; and &#8220;POST&#8221; requests, you can start building more complex APIs, with different endpoints available for different methods. To further illustrate API endpoint development, consider the following detailed code example that can be used as template:</p>



<pre class="wp-block-code"><code>Function HandleURL(request As WebRequest, response As WebResponse) Handles HandleURL as Boolean
  response.MIMEType = "application/json"
  
  Try
    Select Case request.Method
    Case "GET"
      
      Select Case request.Path
      Case "time"
        Var currentTime As String = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
        response.Write("{""message"": """ + currentTime + """}")
        response.Status = 200
        Return True
      Case "hello"
        response.Write("{""message"": ""Hello, World!""}")
        response.Status = 200
        Return True
      Else
        response.Write("{""error"": ""Not Found""}")
        response.Status = 404
        Return True
      End Select
      
    Case "POST"
      
      Select Case request.Path
      Case "some-data"
        Try
          Var jReceivedData As New JSONItem(request.Body)
          Response.Write(jReceivedData.ToString)
          Response.Status = 200
          Return True
        Catch e As JSONException
          response.Write("{""error"": ""Internal Server Error""}")
          response.Status = 500
          Return True
        End Try
      Else
        response.Write("{""error"": ""Not Found""}")
        response.Status = 404
        Return True
      End Select
      
    End Select
    
  Catch e As RuntimeException
    response.Write("{""error"": ""Internal Server Error""}")
    response.Status = 500
    Return True
  End Try
  
  response.Write("{""error"": ""Not Found""}")
  response.Status = 404
  Return True
  
End Function</code></pre>



<p>Small note: observe the start line within the HandleURL function.</p>



<pre class="wp-block-code"><code>response.MIMEType = "application/json"</code></pre>



<p>This line of code informs the client (browser, application) that the API service is responding using the JSON format. Setting the MIMEType to &#8220;application/json&#8221; is best practice and helps prevent any potential parsing errors on the client side.</p>



<h3 class="wp-block-heading">Next Steps</h3>



<p>You might notice that some code is repeating itself (hint: the error responses), so a good idea would be to create a helper method that deals with this particular type of code repetition. Additionally, consider moving the code from the HandleURL function to a separate method that is then invoked within the HandleURL function for improved organization. This restructuring will enhance code organization, making it easier to maintain, read, and improve the efficiency of the program.</p>



<p>P.S.: You should also check the <a href="https://blog.xojo.com/2024/09/24/microservices-building-modern-scalable-applications/" data-type="link" data-id="https://blog.xojo.com/2024/09/24/microservices-building-modern-scalable-applications/" target="_blank" rel="noreferrer noopener">article about microservices</a> and their purpose to get a better idea of what kind of API interfaces you can create.</p>



<p><em>Gabriel is a digital marketing enthusiast who loves coding with Xojo to create cool software tools for any platform. He is always eager to learn and share new ideas!</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>Multiplatform Madness &#8211; JSONReader</title>
		<link>https://blog.xojo.com/2023/05/18/multiplatform-madness-jsonreader/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Thu, 18 May 2023 18:00:35 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[XDC]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=11563</guid>

					<description><![CDATA[In my session at XDC 2023, I talked about ways to design your apps so you reuse code across platforms. The first project is JSONReader, so let’s dive in.]]></description>
										<content:encoded><![CDATA[
<p>In my session at XDC 2023, I talked about ways to design your apps so you reuse code across platforms.</p>



<p>In this series of blog posts, I will cover the sixteen sample projects I created for that session (JSONReader, Mastodon, DisplayDB, DrawCards, with separate versions for desktop, web, iOS and Android) in more detail.</p>



<p>You can watch the presentation on YouTube:</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 title="Multiplatform Madness - Paul Lefebvre" width="500" height="281" src="https://www.youtube.com/embed/V4KVeQ6Xp80?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>The accompanying hands-on session might also be interesting, where I show the projects running on Android:</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 title="Android Hands On Training, XDC 2023" width="500" height="281" src="https://www.youtube.com/embed/UOHBEpMeFsg?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>You can also <a href="https://files.xojo.com/XDC/2023/MadnessExamples.zip">download all the sample projects</a>.&nbsp;</p>



<p>The first project is JSONReader, so let’s dive in.</p>



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



<p>This sample demonstrates a couple classes that can read some specifically formatted JSON. I generated this “mock” JSON data using <a href="https://www.mockaroo.com/">Mockaroo</a>.</p>



<p>The two classes are <strong>Staff</strong> and <strong>StaffDetail</strong>. The Staff class contains the JSON data as a constant for simplicity, but it could load it from anywhere, such as a file or from the web. These classes use standard Xojo framework code and are fully compatible with desktop, web, iOS and Android projects.</p>



<p>On Staff are three methods which are used to fetch information from the JSON: Everyone(), GetNames() and GetSlogans().</p>



<p>Each of these methods are similar in that they loop through the items in the JSON like so:</p>



<pre class="wp-block-code"><code>FOR pos As Integer = 0 To JSONData.Count - 1</code></pre>



<p>The simplest method is GetNames() which just fetches the first and last name from the JSON and combines them into a single string. It then returns all of these names as a string array.</p>



<p>GetSlogans() is similar, but it instead fetches the Slogan field from the JSON, returning them all as a string array.</p>



<p>The Everyone() method makes use of the StaffDetail class which is just a storage class with properties for each field in the JSON. It also loops through the JSON, but grabs each value and puts it into a StaffDetail instance. All of these are collected into an array and returned.</p>



<p>Although this design is simple, it demonstrates how to separate processing code from the UI. Because everything related to JSON is hidden in these classes and returned as arrays, the UI code (which will be different between platforms) only has to deal with arrays and not with how they were created. You can copy and use the classes as needed in whatever project types you are creating.</p>



<p>For the desktop app, the Window has three buttons which display the results of the above methods in a ListBox.</p>



<p>For example, the NamesButton has this code in its Pressed event:</p>



<pre class="wp-block-code"><code>DataList.RemoveAllRows
Var allStaff As New Staff
Var names() As String = allStaff.GetNames

For Each name As String In names
&nbsp; DataList.AddRow(name)
Next</code></pre>



<p>The SloganButton is similar. The AllButton code only differs by having an array of StaffDetail:</p>



<pre class="wp-block-code"><code>DataList.RemoveAllRows
Var allStaff As New Staff
Var everyone() As StaffDetail = allStaff.Everyone

For Each detail As StaffDetail In everyone
&nbsp; DataList.AddRow(detail.FirstName + " works on " + detail.Slogan + ".")
Next</code></pre>



<p>When you look at the projects, notice that the code for the WebPage, iOS Screen and Android Screen buttons is exactly the same as the code for the desktop Window buttons!</p>



<p>That won’t always be the case, of course, but it is a good first start and demonstrates how similar the UI API is across platforms.</p>



<p>In my next post, I will look at the Mastodon sample projects which make use of URLConnection.</p>



<p><em>Paul learned to program in BASIC at age 13 and has programmed in more languages than he remembers, with Xojo being an obvious favorite. When not working on Xojo, you can find him talking about retrocomputing at <a href="https://goto10.substack.com" target="_blank" rel="noreferrer noopener">Goto 10</a> and </em>on Mastodon @lefebvre@hachyderm.io.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>SQLite 3.39.4: New Features</title>
		<link>https://blog.xojo.com/2022/12/13/sqlite-new-features-in-xojo-2022r4/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Tue, 13 Dec 2022 14:32:00 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Database Applications]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLite]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=11053</guid>

					<description><![CDATA[In Xojo 2022r4, we have updated our SQLite library to SQLite v3.39.4. I thought I'd highlight a few notable upgrades including: STRICT tables
PRAGMA table_list
RIGHT and FULL OUTER JOIN
Built-in JSON support]]></description>
										<content:encoded><![CDATA[
<p>In Xojo 2022r4, we have updated our SQLite library to SQLite v3.39.4. Previously Xojo was using 3.36.0, and since there have been <a href="https://www.sqlite.org/changes.html">quite a few SQLite updates since then</a> I thought I&#8217;d highlight a few notable features:</p>



<ul class="wp-block-list"><li>STRICT tables</li><li>PRAGMA table_list</li><li>RIGHT and FULL OUTER JOIN</li><li>Built-in JSON support</li></ul>



<p>More about each of these below.</p>



<h2 class="wp-block-heading">STRICT Tables</h2>



<p>One of SQLite&#8217;s most unusual capabilities is that it does not care about what data goes into a column. Although you could specify a type for a column, it was really more of a suggestion as other types of data could be put into the column. This behavior is different than most other relational databases and can sometimes be a source of confusion.</p>



<p>Now you can create your tables using the <a href="https://www.sqlite.org/stricttables.html">STRICT keyword</a> to force them to require column types and to force the column types to always be checked when putting data into them.</p>



<p>You are still limited to INT, INTEGER, REAL, TEXT and BLOB. That means there is still no DATE or DATETIME type like you might find in other databases. Instead use TEXT with YYYY-MM-DD format.</p>



<p>However, an ANY type was added which essentially allows you to clearly state that the column can contain anything. This allows you to have a mixture of specific types and generic types in your STRICT tables.</p>



<p>Note that the STRICT keyword goes at the end of the CREATE TABLE command:</p>



<pre class="wp-block-preformatted">CREATE TABLE Team (ID INTEGER, Name TEXT, Coach TEXT, City TEXT, PRIMARY KEY(ID)) STRICT;</pre>



<p>The <a href="https://www.sqlite.org/stricttables.html">SQLite docs</a> have more information about the new STRICT table feature.</p>



<h2 class="wp-block-heading">PRAGMA table_list</h2>



<p>With Xojo you could always get the list of tables by using the <a href="https://documentation.xojo.com/api/databases/database.html#database-tables">Database.Tables()</a> method. However if you wanted to get the list of table using SQL you had to directly query the sqlite_master table.</p>



<p>Now there is a simple PRAGMA that can do the same thing:</p>



<pre class="wp-block-code"><code>PRAGMA table_list</code></pre>



<p>It returns a list of tables and some other details about the table (which may change over time <a href="https://www.sqlite.org/pragma.html#pragma_table_list">according to the SQLite docs</a>).</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" src="https://blog.xojo.com/wp-content/uploads/2022/12/CleanShot-2022-12-12-at-10.16.02@2x-1024x852.png" alt="" class="wp-image-11057" width="625" height="520" srcset="https://blog.xojo.com/wp-content/uploads/2022/12/CleanShot-2022-12-12-at-10.16.02@2x-1024x852.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/12/CleanShot-2022-12-12-at-10.16.02@2x-300x250.png 300w, https://blog.xojo.com/wp-content/uploads/2022/12/CleanShot-2022-12-12-at-10.16.02@2x-768x639.png 768w, https://blog.xojo.com/wp-content/uploads/2022/12/CleanShot-2022-12-12-at-10.16.02@2x.png 1144w" sizes="auto, (max-width: 625px) 100vw, 625px" /></figure>



<h2 class="wp-block-heading">RIGHT and FULL OUTER JOIN</h2>



<p>Joining tables is a common task with SQL. The most common type of join is an INNER JOIN where only the rows common to both tables are included in the result. Other less common types of joins include LEFT OUTER, RIGHT OUTER and FULL OUTER (sometimes OUTER is omitted when referring to these types of joins).</p>



<p>SQLite has had support for LEFT OUTER joins for a long time, but support for RIGHT OUTER and FULL OUTER were missing. But now they are here, giving your more complicated queries better compatibly with the &#8220;big name&#8221; databases.</p>



<p>Learn more about these types of joins at <a href="https://www.w3schools.com/sql/sql_join.asp">W3 schools</a>.</p>



<h2 class="wp-block-heading">JSON Support</h2>



<p>I&#8217;ve saved the big one for last: your SQL databases can now work with JSON data within columns.</p>



<p>Here is a sample table to work with with some JSON data that is stored in the players column:</p>



<pre class="wp-block-preformatted">CREATE TABLE team(id INTEGER PRIMARY KEY, Name TEXT, players TEXT);</pre>



<pre class="wp-block-preformatted">INSERT INTO TEAM VALUES (NULL, 'Seagulls', '[ {"Name":"Bob","position":"1B"}, {"Name":"Tom","position":"2B"} ]')</pre>



<pre class="wp-block-preformatted">INSERT INTO TEAM VALUES (NULL, 'Pigeons', '[ {"Name":"Bill","position":"1B"}, {"Name":"Tim","position":"2B"} ]')</pre>



<pre class="wp-block-preformatted">INSERT INTO TEAM VALUES (NULL, 'Crows', '[ {"Name":"Betty","position":"1B"}, {"Name":"Tina","position":"2B"} ]')</pre>



<p>Let&#8217;s say you want to get the first player on each team. Without SQLite JSON support you would have to pull out the JSON column data and parse it out separately. But now you can do it with this SQL like this:</p>



<pre class="wp-block-preformatted">SELECT players -&gt; 0 FROM team</pre>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="590" height="568" src="https://blog.xojo.com/wp-content/uploads/2022/12/CleanShot-2022-12-12-at-10.54.09@2x.png" alt="" class="wp-image-11063" srcset="https://blog.xojo.com/wp-content/uploads/2022/12/CleanShot-2022-12-12-at-10.54.09@2x.png 590w, https://blog.xojo.com/wp-content/uploads/2022/12/CleanShot-2022-12-12-at-10.54.09@2x-300x289.png 300w" sizes="auto, (max-width: 590px) 100vw, 590px" /></figure>



<p>The above SQL says: for each row fetch the first array element from the JSON data in players.</p>



<p>This is how you would list all the players on all the teams:</p>



<pre class="wp-block-preformatted">SELECT team.Name, json_each.value -&gt; 'Name' FROM team, json_each(team.players)</pre>



<p>And if you want to get the actual value without the quotes, you can use the -&gt;&gt; operator (and also rename the result):</p>



<pre class="wp-block-preformatted">SELECT team.Name, json_each.value -&gt;&gt; 'Name' As PlayerName FROM team, json_each(team.players)</pre>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="544" src="https://blog.xojo.com/wp-content/uploads/2022/12/CleanShot-2022-12-12-at-11.40.49@2x-1024x544.png" alt="" class="wp-image-11075" srcset="https://blog.xojo.com/wp-content/uploads/2022/12/CleanShot-2022-12-12-at-11.40.49@2x-1024x544.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/12/CleanShot-2022-12-12-at-11.40.49@2x-300x159.png 300w, https://blog.xojo.com/wp-content/uploads/2022/12/CleanShot-2022-12-12-at-11.40.49@2x-768x408.png 768w, https://blog.xojo.com/wp-content/uploads/2022/12/CleanShot-2022-12-12-at-11.40.49@2x.png 1250w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>The SQLite JSON support can do much, much more which you can read about on the <a href="https://www.sqlite.org/json1.html">SQLite JSON doc page</a>.</p>



<p><em>Paul learned to program in BASIC at age 13 and has programmed in more languages than he remembers, with Xojo being an obvious favorite. When not working on Xojo, you can find him talking about retrocomputing at <a href="https://goto10.substack.com" target="_blank" rel="noreferrer noopener">Goto 10</a> and </em>on Mastodon @lefebvre@hachyderm.io.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>CatsUp! 2022</title>
		<link>https://blog.xojo.com/2022/03/16/catsup-2022/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Wed, 16 Mar 2022 15:53:53 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Fun]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Cats]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Multi-Platform Development]]></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=10135</guid>

					<description><![CDATA[With just a few lines of code, you can create a Xojo app for iOS and Android that shows a new cat picture each time you launch it. I call this app “CatsUp!”. It's a play on ketchup/catsup, get it?]]></description>
										<content:encoded><![CDATA[
<p>Back in 2015, I wrote a <a href="https://blog.xojo.com/2015/10/01/cats-up-using-httpsocket-with-the-cat-rest-api/">blog post</a> about an iOS app called CatsUp! that used <a href="https://thecatapi.com">The Cat API</a> to display random cat pictures. Things have changed a lot since then, so it&#8217;s time for an update!</p>



<p>With just a few lines of code, you can create a mobile app that shows a new cat picture each time you launch it. I call this app “CatsUp!”. It&#8217;s a play on <a href="https://writingexplained.org/catsup-vs-ketchup-difference">ketchup/catsup</a>, get it?</p>



<h3 class="wp-block-heading">Set Up The Project</h3>



<p>Create a new iOS project called “CatsUp”. Drag an ImageViewer control onto Screen1, make it fill most of the area and change its Name to &#8220;CatImage&#8221;. Drag a Button to the bottom and change its Caption to “Cat Me!”. Also change the Screen Title to be &#8220;CatsUp!&#8221;. The result should look something like this:</p>



<figure class="wp-block-image size-medium"><img loading="lazy" decoding="async" width="184" height="300" src="https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-16-at-09.52.48@2x-184x300.png" alt="" class="wp-image-10136" srcset="https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-16-at-09.52.48@2x-184x300.png 184w, https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-16-at-09.52.48@2x-626x1024.png 626w, https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-16-at-09.52.48@2x.png 750w" sizes="auto, (max-width: 184px) 100vw, 184px" /></figure>



<h3 class="wp-block-heading">The Cat API</h3>



<p>The&nbsp;<a href="https://docs.thecatapi.com/">Cat API documentation page</a>&nbsp;describes the full API. For access to most features you will want to sign up for a free account and use an API key. For the purposes of this post, I will just use it without an API key. The URL for the method to get a random cat picture is:</p>



<pre class="wp-block-preformatted">https://api.thecatapi.com/v1/images/search</pre>



<p>The above URL returns JSON that contains the location of a picture to display. Paste it into a web browser to try it. In my test I got this JSON:</p>



<pre class="wp-block-preformatted">[{"breeds":[],"id":"99v","url":"https://cdn2.thecatapi.com/images/99v.jpg","width":384,"height":384}]</pre>



<p>To make CatsUp, we will essentially add some code to 1) send the first request, 2) get the JSON and pull out the picture URL, 3) get the picture and display it.</p>



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



<p>Add the Pressed event to the Button with this code:</p>



<pre class="wp-block-preformatted">CatConnection.Send("GET", "https://api.thecatapi.com/v1/images/search")</pre>



<p>This calls the Send() method on a URLConnection object, called CatConnection, to get the JSON with the picture URL.</p>



<p>So now you need to drag a URLConnection object from the Library onto the Screen. Click on this newly added URLConnection1 item in the Tray and in the Inspector change its name to &#8220;CatConnection&#8221;. Add its ContentReceived event with this code:</p>



<pre class="wp-block-preformatted">Var json As JSONItem = New JSONItem
json.Load(content)

Var catItem As JSONItem
catItem = json.ValueAt(0)

Var picURL As String
picURL = catItem.Value("url").StringValue

ImageDownload.Send("GET", picURL)</pre>



<p>The above code loads the JSON into a JSONItem and then fetches the &#8220;url&#8221; value. It sends this URL to another URLConnection, called ImageDownload, to get the actual picture to display.</p>



<p>Drag a second URLConnection onto the screen and change its name to &#8220;ImageDownload&#8221;. Add its ContentReceived event with this code:</p>



<pre class="wp-block-preformatted">Var pic As Picture = Picture.FromData(content)
CatImage.Image = pic</pre>



<p>Try running the project in the iOS Simulator. Click the button to see a new cat picture.</p>



<p>This is what I see:</p>



<figure class="wp-block-image size-medium is-resized"><img loading="lazy" decoding="async" src="https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-16-at-10.46.03@2x-157x300.png" alt="" class="wp-image-10139" width="229" height="438" srcset="https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-16-at-10.46.03@2x-157x300.png 157w, https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-16-at-10.46.03@2x-536x1024.png 536w, https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-16-at-10.46.03@2x-768x1468.png 768w, https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-16-at-10.46.03@2x-803x1536.png 803w, https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-16-at-10.46.03@2x-1071x2048.png 1071w, https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-16-at-10.46.03@2x.png 1204w" sizes="auto, (max-width: 229px) 100vw, 229px" /></figure>



<p>Oops, silly me. I actually created this as an Android project and ran it in the Android Emulator. Sorry about that, here is what it looks like as an iOS project running in the iOS Simulator:</p>



<figure class="wp-block-image size-medium is-resized"><img loading="lazy" decoding="async" src="https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-16-at-10.47.56@2x-edited.png" alt="" class="wp-image-10141" width="234" height="532" srcset="https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-16-at-10.47.56@2x-edited.png 1000w, https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-16-at-10.47.56@2x-edited-132x300.png 132w, https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-16-at-10.47.56@2x-edited-450x1024.png 450w, https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-16-at-10.47.56@2x-edited-768x1747.png 768w, https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-16-at-10.47.56@2x-edited-675x1536.png 675w, https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-16-at-10.47.56@2x-edited-900x2048.png 900w" sizes="auto, (max-width: 234px) 100vw, 234px" /></figure>



<p>That&#8217;s right, the exact same code for this project can be used in both <strong>iOS</strong> and <strong>Android</strong> projects! And for another bit of Android news, this CatsUp! app, with a couple minor enhancements, is now available in the <a href="https://play.google.com/store/apps/details?id=com.xojo.catsup">Google Play Store</a>:</p>



<figure class="wp-block-image size-large is-resized"><a href="https://play.google.com/store/apps/details?id=com.xojo.catsup"><img loading="lazy" decoding="async" src="https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-16-at-10.52.46@2x-618x1024.png" alt="" class="wp-image-10143" width="349" height="578" srcset="https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-16-at-10.52.46@2x-618x1024.png 618w, https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-16-at-10.52.46@2x-181x300.png 181w, https://blog.xojo.com/wp-content/uploads/2022/03/CleanShot-2022-03-16-at-10.52.46@2x.png 750w" sizes="auto, (max-width: 349px) 100vw, 349px" /></a></figure>



<p>Have fun with this and may every day be a Caturday!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>A Deep Dive into Custom Cell Renderers, Part II</title>
		<link>https://blog.xojo.com/2021/09/20/a-deep-dive-into-custom-cell-renderers-part-ii/</link>
		
		<dc:creator><![CDATA[Ricardo Cruz]]></dc:creator>
		<pubDate>Mon, 20 Sep 2021 13:51:43 +0000</pubDate>
				<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Rapid Application Development]]></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=9226</guid>

					<description><![CDATA[There is something that is even better than using Cell Renderers from third parties- building them yourself. In this second part, you will learn how&#8230;]]></description>
										<content:encoded><![CDATA[
<p>There is something that is even better than using Cell Renderers from third parties- building them yourself. In this second part, you will learn how to create your very own controls using Xojo&#8217;s WebSDK.</p>



<p>In case you missed it,&nbsp;<a rel="noreferrer noopener" href="https://blog.xojo.com/2021/09/09/a-deep-dive-into-custom-cell-renderers-part-i/" target="_blank">the previous article</a>&nbsp;explains in detail what Cell Renderers are and how to use them. Anything you can imagine can be done inside your WebListView control cells. In order to do so, be prepared to write some JavaScript code. Today we will create a very basic example, a Custom Cell Renderer capable of showing&nbsp;<a rel="noreferrer noopener" href="https://getbootstrap.com/docs/4.4/components/badge/#pill-badges" target="_blank">Bootstrap Badges</a>.</p>



<p>If we think about it, in a nutshell, what we want to achieve is to inject this HTML (coming directly from Bootstrap&#8217;s docs) into our cells:</p>



<pre class="wp-block-preformatted">&lt;span class="badge badge-pill badge-primary"&gt;Primary&lt;/span&gt;</pre>



<p>The first step is to create a new class in our Xojo project. Let&#8217;s call it BadgeColumn, for example. It will be a child of&nbsp;<a rel="noreferrer noopener" href="https://documentation.xojo.com/api/user_interface/web/weblistbox.htmlCellRenderer" target="_blank">WebListboxCellRenderer</a>&nbsp;Superclass. </p>



<figure class="wp-block-image size-full is-resized is-style-default"><img loading="lazy" decoding="async" src="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.10.01.png" alt="" class="wp-image-9294" width="468" height="256" srcset="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.10.01.png 314w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.10.01-300x164.png 300w" sizes="auto, (max-width: 468px) 100vw, 468px" /></figure>



<p>Extending WebListBoxCellRenderer will allow our class to listen to some events that Xojo will emit, used to render our badges inside the table. There are three: Deserialize, JavascriptClassCode and Serialize. </p>



<figure class="wp-block-image size-full is-resized is-style-default"><img loading="lazy" decoding="async" src="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.22.21.png" alt="" class="wp-image-9295" width="468" height="140" srcset="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.22.21.png 341w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.22.21-300x90.png 300w" sizes="auto, (max-width: 468px) 100vw, 468px" /></figure>



<p>We will ignore all of them for the moment, except JavascriptClassCode. But it is important to know that Serialize must return an instance of a&nbsp;<a rel="noreferrer noopener" href="https://documentation.xojo.com/api/text/json/jsonitem.html" target="_blank">JSONItem</a>&nbsp;class, or you will get a NilObjectException, as soon as you add a new row using this renderer. </p>



<p>Let&#8217;s add this code to the Serialize event, we will come back to this event later:</p>



<pre class="wp-block-preformatted">Return New JSONItem</pre>



<p>JavascriptClassCode event will be executed only once, no matter the amount of instances of our renderers we have. It must return a String containing a JavaScript class that extends XojoWeb.ListboxCellRenderer, containing a render() method inside (remember that JavaScript is case-sensitive). </p>



<p>In render(), we will simply replace the contents of the cell DOM element with the badge HTML code snippet provided by the Bootstrap docs that we just saw.</p>



<p>In order to keep it as readable as possible, what I prefer to do is to create a String Constant called &#8220;kJavascriptClass&#8221; (the name is arbitrary, use anything you want), with the JavaScript code inside:</p>



<pre class="wp-block-preformatted">class BadgeColumn extends XojoWeb.ListboxCellRenderer {
&nbsp; &nbsp; render(controlID, row, data, rowIndex, columnIndex, cell) {
&nbsp; &nbsp; &nbsp; &nbsp; cell.innerHTML = '&lt;span class="badge badge-pill badge-primary"&gt;Primary&lt;/span&gt;';
&nbsp; &nbsp; }
}</pre>



<figure class="wp-block-image size-large is-style-default"><img loading="lazy" decoding="async" width="1024" height="674" src="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.37.59-1024x674.png" alt="" class="wp-image-9296" srcset="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.37.59-1024x674.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.37.59-300x197.png 300w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.37.59-768x505.png 768w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.37.59.png 1369w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Having our raw JavaScript as a String constant, our JavascriptClassCode event can just return it:</p>



<pre class="wp-block-preformatted">Return kJavascriptClass</pre>



<p>Congratulations! That&#8217;s your first Cell Renderer. It won&#8217;t do a lot of things, but that&#8217;s the basic plumbing needed to start creating lots of them. With this new class, following the steps you&#8217;ve learned on the first part of this tutorial, you will be able to use it in your tables. Drop a WebListView into your WebPage and add a handler for the Opening event. Then add this code:</p>



<pre class="wp-block-preformatted">Me.AddRow("Hello, World!")
Me.CellValueAt(0, 0) = New BadgeColumn</pre>



<p>It will add a row to the control, and then it will make use of our new Cell Renderer to replace the first cell of the first row. If you run your project, you will see a website that looks like the following screenshot:</p>



<figure class="wp-block-image size-large is-style-default"><img loading="lazy" decoding="async" width="1024" height="743" src="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.46.01-1024x743.png" alt="" class="wp-image-9297" srcset="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.46.01-1024x743.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.46.01-300x218.png 300w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.46.01-768x557.png 768w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.46.01.png 1027w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>While promising, you will notice the badge says &#8220;Primary&#8221; instead of the &#8220;Hello, World!&#8221; message we want. Looking at the render() method, within our Javascript, you will find &#8220;data&#8221; as one of the parameters it receives. It is a JSON object that comes from (I&#8217;m sure you&#8217;ve guessed it already) the Serialize event we saw a few paragraphs ago. </p>



<p>Edit the Serialize event handler. This time, instead of returning an empty JSONItem, we will fill it with some data.</p>



<pre class="wp-block-preformatted">Var json As New JSONItem
json.Value("content") = "Test"
json.Value("appearance") = "success"
Return json</pre>



<p>Next, update your kJavascriptClass constant with the following snippet of code. Notice we are making use of the values we have in the data parameter, coming as a Javascript object:</p>



<pre class="wp-block-preformatted">class BadgeColumn extends XojoWeb.ListboxCellRenderer {
&nbsp; &nbsp; render(controlID, row, data, rowIndex, columnIndex, cell) {
&nbsp; &nbsp; &nbsp; &nbsp; cell.innerHTML = '&lt;span class="badge badge-pill badge-' + data.appearance + '"&gt;' + data.content + '&lt;/span&gt;';
&nbsp; &nbsp; }
}</pre>



<p>Running the web application again will make you smile a bit:</p>



<figure class="wp-block-image size-large is-style-default"><img loading="lazy" decoding="async" width="1024" height="743" src="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-19.05.34-1024x743.png" alt="" class="wp-image-9298" srcset="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-19.05.34-1024x743.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-19.05.34-300x218.png 300w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-19.05.34-768x557.png 768w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-19.05.34.png 1027w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Nearly there! Now that we know how to communicate between Xojo and the cell that is running in our browser, we just need to find a way to create instances of these BadgeColumn classes, using real content. </p>



<p>My preference is to create a Constructor with the parameters I want, and some class properties. This is completely up to you.</p>



<p>Create a few properties for our BadgeColumn class:</p>



<ul class="wp-block-list"><li>Content As String</li><li>Appearance As String</li></ul>



<p>Then a Constructor with the following parameters:</p>



<ul class="wp-block-list"><li>content As String</li><li>appearance As String</li></ul>



<figure class="wp-block-image size-full is-resized is-style-default"><img loading="lazy" decoding="async" src="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-20.50.43.png" alt="" class="wp-image-9299" width="541" height="343" srcset="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-20.50.43.png 375w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-20.50.43-300x190.png 300w" sizes="auto, (max-width: 541px) 100vw, 541px" /></figure>



<p>Inside our new Constructor, you will need to call its Superclass Constructor, wiring the internal properties of the instance with the parameters, as following:</p>



<pre class="wp-block-preformatted">Super.Constructor
Self.Content = content
Self.Appearance = appearance</pre>



<p>The Serialize event handler can be updated now to make use of our new properties, instead hardcoded data:</p>



<pre class="wp-block-preformatted">Var json As New JSONItem
json.Value("content") = Content
json.Value("appearance") = Appearance
Return json</pre>



<p>Finally, we need to update the Opening event we used in our ListBox. Just remember thtat BadgeColumn now needs to be instantiated with some parameters:</p>



<pre class="wp-block-preformatted">Me.AddRow("")
Me.CellValueAt(0, 0) = New BadgeColumn("Hello, World!", "warning")</pre>



<p>Run the application again and see what happens:</p>



<figure class="wp-block-image size-large is-style-default"><img loading="lazy" decoding="async" width="1024" height="743" src="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-19.22.55-1024x743.png" alt="" class="wp-image-9300" srcset="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-19.22.55-1024x743.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-19.22.55-300x218.png 300w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-19.22.55-768x557.png 768w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-19.22.55.png 1027w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Whoops! That doesn&#8217;t looks right, does it? We are missing one important step. </p>



<p>The communication between Xojo and the control that lives inside JavaScript is bidirectional. This way, &#8220;Data&#8221; can be modified while running in your browser, and it will be sent back to Xojo. In order to fix our issue, we just have to take care of the Deserialize event handler we&#8217;ve completely ignored until now, with the following code:</p>



<pre class="wp-block-preformatted">Content = js.Value("content")
Appearance = js.Value("appearance")</pre>



<p>This will recreate our instance using fresh data coming from JavaScript. Run the project again and voilà!, your table looks perfect now:</p>



<figure class="wp-block-image size-large is-style-default"><img loading="lazy" decoding="async" width="1024" height="743" src="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-19.34.15-1024x743.png" alt="" class="wp-image-9301" srcset="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-19.34.15-1024x743.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-19.34.15-300x218.png 300w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-19.34.15-768x557.png 768w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-19.34.15.png 1027w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>This is not the end, but the beginning of your journey. With this little recipe you already have a lot of knowledge and hours of fun ahead, building your Cell Renderers. Once you feel comfortable, the next step I recommend is to learn how to emit custom cell actions from your JavaScript that you can handle from the CustomCellAction event of your WebListBox controls.  In order to see how this works, check some of the examples coming with Xojo, under Web &gt; WebSDK &gt; WebListBox Cell Renderers. The open source repository we saw in the previous article,&nbsp;<a rel="noreferrer noopener" href="https://github.com/piradoiv/xojo-web-cell-renderers" target="_blank">xojo-web-cell-renderers</a>, also makes use of this event in some of the included Cell Renderers.</p>



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



<p>While we had to get our hands dirty with JavaScript, it&#8217;s really fun to create Cell Renderers for our Xojo projects. They are super easy to share and reuse, and will make your tables look so much better. The source code for this example project can be downloaded <a href="https://blog.xojo.com/wp-content/uploads/2021/09/Custom-Cell-Renderers.xojo_binary_project.zip">here</a>.</p>



<p>I hope you find this tutorial useful, if you have any question, please feel free to ask them in&nbsp;<a rel="noreferrer noopener" href="https://forum.xojo.com/" target="_blank">the forum</a>.</p>



<p><em><a href="https://en.rcruz.es">Ricardo Cruz</a> helps companies with large websites to optimise and secure them, making them reliable and ensuring they are always online. He uses Xojo for building internal tools, but he is starting to explore the desktop software market, with apps like <a href="https://today.rcruz.es">Today</a> and <a href="https://beautyshot.rcruz.es">Beauty Shot</a>. As a hobby, during his free time, Ricardo has been teaching Scuba Diving for more than 10 years.</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Building a weather station with MBS by using a JSON API</title>
		<link>https://blog.xojo.com/2020/10/01/building-a-weather-station-with-mbs-by-using-a-json-api/</link>
		
		<dc:creator><![CDATA[Stefanie Juchmes]]></dc:creator>
		<pubDate>Thu, 01 Oct 2020 14:48:13 +0000</pubDate>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Monkeybread Software]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=7550</guid>

					<description><![CDATA[Learn how to retrieve the data of an API over a CURL connection and evaluate the JSON to build a weather station. This example uses a free key from the OpenWeather API. The API returns a JSON text containing information such as current weather description, current temperature, pressure, humidity and many more. ]]></description>
										<content:encoded><![CDATA[
<p>I want to show you how to retrieve the data of an API over a CURL connection and evaluate the JSON to build a weather station.</p>



<p>In this example I work with a free key from the OpenWeather API. OpenWeather provides an API with weather data that you can access by an URL. The API returns a JSON text containing information such as current weather description, current temperature, pressure, humidity and many more. This is uses the CURL Plugin for the network query and Util plugin for JSON.</p>



<p><strong>The Layout&nbsp;</strong></p>



<p>We want to take a closer look at this JSON together later. But first we want to build the layout in which we can enter our weather information. This layout basically consists of two areas, one is the data area where our information will be displayed and the other is our area where we can enter the location of the wanted forecast and the unit of measurement for the temperature.&nbsp;</p>



<p>We start with the settings area. Here there must be a text field for the location. To set the temperature unit we use a popup menu.&nbsp;</p>



<p>The popup menu has the following entries: °C, °F and K. So later you should be able to choose between Celsius, Fahrenheit and Kelvin as display unit. °C is the default value of the popup menu. In the event &#8220;Change&#8221; of this popup menu we write the selected unit into a property which we can later need in the program. The default value of the property is &#8220;C&#8221; and stands for the unit Celsius. The code of the event then looks like this:&nbsp;</p>



<pre class="wp-block-preformatted"> If PopupMenu1.SelectedRowValue="°C" Then
  TempUnit="C"
Elseif PopupMenu1.SelectedRowValue="°F" Then
  TempUnit="F"
Else
  TempUnit="K"
end if </pre>



<p>We also need a button with which we can start the search.&nbsp; So we are done with the layout in the settings area. Of course this area can also be decorated and highlighted.&nbsp;</p>



<p>Now let&#8217;s get to the layout of the data area. We first need to know which data should be displayed.&nbsp;</p>



<p>You can visit the <a href="https://openweathermap.org/current" target="_blank" rel="noreferrer noopener">OpenWeather website</a> for more details about the available information. In our application the following information should be displayable:</p>



<p>*Weather description<br>*Current temperature<br>*Perceived temperature<br>*Minimum temperature<br>*Maximum temperature<br>*Humidity<br>*Wind speed<br>*Atmospheric pressure<br>*Sunrise and sunset time  </p>



<p>We create a separate label for each of these information.&nbsp;Information behind which a unit of measurement should be placed, gets an additional label field with the unit of measurement. The unit of measurement fields for the temperatures are all named the same, so we create an array of labels. This is important, because these units of measurement are to be changed afterwards by script. Of course the inscription must not be missing, so that we can see what information is actually displayed. These can then also be decorated appropriately.&nbsp;</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="761" src="https://blog.xojo.com/wp-content/uploads/2020/09/weather-station-1-1024x761.png" alt="" class="wp-image-7554" srcset="https://blog.xojo.com/wp-content/uploads/2020/09/weather-station-1-1024x761.png 1024w, https://blog.xojo.com/wp-content/uploads/2020/09/weather-station-1-300x223.png 300w, https://blog.xojo.com/wp-content/uploads/2020/09/weather-station-1-768x571.png 768w, https://blog.xojo.com/wp-content/uploads/2020/09/weather-station-1-1536x1141.png 1536w, https://blog.xojo.com/wp-content/uploads/2020/09/weather-station-1.png 1680w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p><strong>The CURL Connection to the API&nbsp;</strong></p>



<p>When we have entered a location and clicked on the search button, the matching values should appear. Now we have to think about where we get our current weather data. As mentioned before we work with the OpenWeather API. To access this API we pass some information with our URL like the desired location and our key. The structure of the URL can look like this:</p>



<p>api.openweathermap.org/data/2.5/weather?q={city name}&amp;appid={your api key}</p>



<p>The informations in the curly brackets must be replaced with your wanted query. For example you want the current weather information for London, where the next Xojo conference will take place and your key would be „123“ the url look like this&nbsp;</p>



<p><a href="http://api.openweathermap.org/data/2.5/weather?q=London&amp;appid=123">api.openweathermap.org/data/2.5/weather?q=London&amp;appid=123</a></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="279" src="https://blog.xojo.com/wp-content/uploads/2020/09/weather-station-2-1024x279.png" alt="" class="wp-image-7555" srcset="https://blog.xojo.com/wp-content/uploads/2020/09/weather-station-2-1024x279.png 1024w, https://blog.xojo.com/wp-content/uploads/2020/09/weather-station-2-300x82.png 300w, https://blog.xojo.com/wp-content/uploads/2020/09/weather-station-2-768x209.png 768w, https://blog.xojo.com/wp-content/uploads/2020/09/weather-station-2-1536x419.png 1536w, https://blog.xojo.com/wp-content/uploads/2020/09/weather-station-2-2048x558.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption>example result of the URL with a valid key</figcaption></figure>



<p>The result that the URL returns is a JSON text, that contains the requested informations. So we need the text in our program. For this we use a CURL connection. We build it in the action event of the search button and pass the URL&nbsp;</p>



<p><strong>Action Event:&nbsp;</strong></p>



<p><em>Dim c As New MyCURL<br>c.OptionURL = &#8220;api.openweathermap.org/data/2.5/weather?<br>q=&#8221;+Search.Text+&#8221;&amp;appid=&#8221;+Key<br>Call c.Perform </em></p>



<p>In the code we see that we create a new instance of the MyCurl class. The <strong>MyCurl </strong>class has the superclass <strong>CURLSMBS</strong>. We need the new class because we want to fill events with code.&nbsp;</p>



<p>Then we build our URL. We pass the location that is contained in the search text field. Our key is in a property. This has the advantage that we only have to change it in one place and don&#8217;t have to search in the source code in case we would query several URLs. At this point it should be mentioned that the Open Weather API can find the weather not only by place name, but also by longitude and latitude, City ID or ZipCode.</p>



<p>Besides the current weather data, forecasts and much more can be called up. When using an API, it is always useful to have a look at the documentation of an API to be able to use it correctly.</p>



<p>The <strong>Perform</strong> method calls the specified URL. In the event <strong>Write</strong> of the <strong>MyCurl</strong> class we get the data of the url. We save the data in the property JSONText as String, because we need this text in different scripts. Then we test if we get valide weather data. E.g. Our key can be wrong or the city is not found. For that test we write a method <strong>test</strong>, that return a boolean value. If the return value is true we run the method <strong>run</strong>, that set the informations form the API to our labels. If the result is false, we display in a message Box an error code that is save in a property Error.&nbsp;</p>



<p><strong>Write Event:&nbsp;</strong></p>



<pre class="wp-block-preformatted">weather.JSONText=data<br> Dim c As Boolean=weather.test
If c Then
  weather.run
Else 
  MsgBox weather.Error 
End If  </pre>



<p>So let’s start to write the method <strong>test</strong> as first.&nbsp;</p>



<p>Let&#8217;s think about what could go wrong: For example our API key might be wrong. Let&#8217;s enter our URL in the browser and change a character in the key so that it doesn&#8217;t match ours. The result looks like this:&nbsp;</p>



<pre class="wp-block-preformatted">{"cod":401, "message": "Invalid API key. Please see http://openweathermap.org/faq#error401 for more info.“}</pre>



<p>We get a code number and an error message as result. The same we can test for a wrong city name&nbsp;</p>



<pre class="wp-block-preformatted">{"cod":"404","message":"city not found“}</pre>



<p>Also here we get only these two keys. We look whether there are also these keys with a normal and valid, functioning query. The answer is yes! In a validquery the key „cod“ always has the value 200, also for different Cities in different Countries. We can use this. So we check whether cod has the value 200. If it is not equal, there was an error and we save the text under the key message in the property Error. This text will be written into a dialog in the Write event. Otherwise the method returns true.&nbsp;</p>



<p><strong>Method test()as boolean :</strong></p>



<pre class="wp-block-preformatted">Dim json As New JSONMBS(JSONText)<br> Dim cod As JSONMBS =json.Child ("cod")
If cod.toString <>"200" Then
  Dim message As JSONMBS= json.Child ("message")
  Error=message.toString
  Return False
Else
  Error=""
  Return True
End If </pre>



<p>So we first create a new instance of the class <strong>JSONMBS</strong>, to which we pass our JSON from the API.&nbsp;</p>



<p>We want the result of „cod&#8221;. We can compare it. We call the method <strong>Child</strong>, which we pass the key as parameter. The result is again of type <strong>JSONMBS</strong>. To be able to read the result, we call the method <strong>toString</strong> to convert the result to a string that we can compare.&nbsp;</p>



<p>If the result is not equal 200, we use again the method <strong>Child</strong> to get the information from the key „message“ and read the information with <strong>toString</strong>.</p>



<p><strong>Working with the JSON&nbsp;</strong></p>



<p>We now come to the already used method run.&nbsp;</p>



<p>In this method we first enter the units of temperature into the labels. Then we create a new instance of the JSONMBS class, that gets the JSON text from the API.&nbsp;</p>



<pre class="wp-block-preformatted">For i As Integer= 0 To 3<br>   deg(i).Text= PopupMenu1.SelectedRowValue
Next

Dim json As New JSONMBS(JSONText) </pre>



<p>This instance is used for all data queries. The idea of the data query is always the same. We look at the original JSON where the information we want to read is. e.g. the description text of the weather. We go backwards and note the path&nbsp;</p>



<pre class="wp-block-preformatted"><em>…<br> "weather":[
      {
         "id":804,
         "main":"Clouds",
         "description":"overcast clouds",
         "icon":"04d"
      }
   ],
… </em></pre>



<p>The description text is located under the key description. Description is located in an array. In the array, the desired description is in the first element. (Note that an array starts counting at 0) The array is located in the object weather. So we can build the path from right to left as follows&nbsp;</p>



<p><strong>weather[0].description</strong></p>



<p>We now unravel this path with various methods and go deeper layer by layer. We start with weather. This key is a Child of or JSON Text. Because of this we write :</p>



<pre class="wp-block-preformatted">Dim weather As JSONMBS= json.Child („weather“)</pre>



<p>Now the variable has the following content&nbsp;</p>



<pre class="wp-block-preformatted"><em>"weather":[
      {
         "id":804,
         "main":"Clouds",
         "description":"overcast clouds",
         "icon":"04d"
      }
   ],</em></pre>



<p>Next we need to get into the array. We need the first element. We use the method ArrayItem and pass 0 as parameter, because we want to address the first element with the index 0.</p>



<pre class="wp-block-preformatted">Dim weatherArray As JSONMBS=weather.ArrayItem(0)</pre>



<p>The JSON in weatherArray has the following structure:&nbsp;</p>



<pre class="wp-block-preformatted"><em>&nbsp; {<br> "id":804,
         "main":"Clouds",
         "description":"overcast clouds",
         "icon":"04d"
      } </em></pre>



<p>Now the description is again a child of this object. And we use the Child method again&nbsp;</p>



<pre class="wp-block-preformatted">Dim description As JSONMBS= weatherArray.Child(„description“)</pre>



<p>Now we have to put the JSON text as MBSJSON datatype into a format that can be read.&nbsp; For this we use the <strong>toString</strong> method. Now we have a string that still has quotation marks, which we can replace with an empty string by using the <strong>ReplaceAll </strong>method.</p>



<pre class="wp-block-preformatted">weatherDes.Text=ReplaceAll(description.toString, Chr(34),"")</pre>



<p>The paths of the other information can be read and build similarly.</p>



<p><strong>Convert the temperature&nbsp;</strong></p>



<p>We get the temperatures by default in Kelvin. You can change this with an addition in the URL. But because we want to choose between Kelvin, Celsius and Fahrenheit anyway, we mostly have to convert the extracted results into the desired unit. So we pass any temperature we get from the API to the <strong>tempConvert</strong> method. This method has as input the temperature as a double</p>



<p>In If and Else If statements we check which temperature unit is selected in the popup menu. Matching this we do the conversion. The formulas are as follows:</p>



<p><strong>Kelvin -&gt; Fahrenheit&nbsp;</strong><br>Fahrenheit= Kelvin*(9/5)-459.67 </p>



<p><strong>Kelvin -&gt;Celsius&nbsp;</strong><br>Celsius= Kelvin -273</p>



<p><strong>Kelvin-&gt; Kelvin&nbsp;</strong><br>Kelvin = Kelvin</p>



<p>These conversions can of course result in unwanted decimal digits. Therefore we format to the first digit after the decimal point and return this value. The Code of this method look like this:&nbsp;</p>



<p><strong>tempConvert (temp as double) as double:</strong></p>



<pre class="wp-block-preformatted">Dim tempConv As Double
<br> If tempunit="F" Then 
   tempConv = temp*(9/5)-459.67
Elseif tempunit="C" Then 
   tempConv = temp-273.15
Else
   tempConv = temp
End If 
tempConv=Format(tempConv, "#.#").Val

Return tempConv </pre>



<p>A further conversion is needed for the sunset and sunrise time. We have given the times in Unix time. That means we have given the seconds from January 1st 1970 00:00 to the time of our time value. We have to convert this into a time that is readable for humans. The code for the sunrise look like this.&nbsp;</p>



<pre class="wp-block-preformatted"> Dim d1 As New DateTime(rise.ValueInteger, TimeZone.Current)
sunrise.Text=d1.Hour.ToString+":"+d1.Minute.ToString</pre>



<p>The code for the sunset looks similar.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="877" src="https://blog.xojo.com/wp-content/uploads/2020/09/weather-station-3-1024x877.png" alt="" class="wp-image-7557" srcset="https://blog.xojo.com/wp-content/uploads/2020/09/weather-station-3-1024x877.png 1024w, https://blog.xojo.com/wp-content/uploads/2020/09/weather-station-3-300x257.png 300w, https://blog.xojo.com/wp-content/uploads/2020/09/weather-station-3-768x658.png 768w, https://blog.xojo.com/wp-content/uploads/2020/09/weather-station-3.png 1256w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption>the weather in London</figcaption></figure>



<p>Now I wish you a lot of fun with your own weather station. Download the project <a href="https://blog.xojo.com/wp-content/uploads/2020/09/Weather-Station-Example.zip" target="_blank" rel="noreferrer noopener">here</a> and if you have any questions please feel free to contact me. </p>



<p><em>Stefanie Juchmes studies computer science at the University of Bonn. She came in touch with Xojo due to the work of her brother-in-law and got a junior developer position in early 2019 at <a rel="noreferrer noopener" href="https://www.monkeybreadsoftware.de/xojo/" target="_blank">Monkeybread Software.</a> You may have also read her articles in <a rel="noreferrer noopener" href="http://www.xdevmag.com/" target="_blank">Xojo Developer Magazine</a>. </em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>JSON Tree</title>
		<link>https://blog.xojo.com/2019/03/11/json-tree/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Mon, 11 Mar 2019 10:00:52 +0000</pubDate>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=5493</guid>

					<description><![CDATA[If you open unformatted JSON in a text editor you'll probably find it a bit dense. Here's how to get around that.]]></description>
										<content:encoded><![CDATA[<p><a href="https://json.org">JSON</a> (JavaScript Object Notation) is a great text-based data format that can be used for files and web services data communication.</p>
<p>The structure is simpler than XML which makes it much smaller and since it does not make use of all the tags you&#8217;ll find in XML, it is also significantly easier to read. However, if you open unformatted JSON in a text editor you&#8217;ll probably find it a bit dense. Here&#8217;s how to get around that.</p>
<p><span id="more-5493"></span></p>
<p>Here is a JSON file shown in bbEdit:</p>
<p><img loading="lazy" decoding="async" class="wp-image-5498 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2019/03/2019-03-01_09-01-34.png" alt="" width="600" height="756" /></p>
<p>You could <a href="https://blog.xojo.com/2015/08/14/format-json/">apply formatting to it</a>, but another option is to display it in a tree to get a better understanding of its structure and content.</p>
<p>Here&#8217;s a simple Xojo project that displays JSON in a hierarchical ListBox (inspired by a <a href="https://forum.xojo.com/52661-display-json-data-in-a-visual-tree">user&#8217;s forum request</a>):</p>
<p><a href="http://files.xojo.com/BlogExamples/JSONTree.xojo_binary_project">Download JSONTree</a></p>
<p>Here&#8217;s the above JSON displayed using JSONTree:</p>
<p><img loading="lazy" decoding="async" class="wp-image-5499 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2019/03/2019-03-01_09-02-55.png" alt="" width="600" height="592" /></p>
<p>The code on the &#8220;Load JSON&#8221; button loads a JSON file into a <a href="https://documentation.xojo.com/api/text/json/jsonitem.html">JSONItem</a> using a <a href="https://documentation.xojo.com/topics/file_managment/accessing_text_files.html">TextInputStream</a>. It then calls the <strong>DisplayJSON</strong> method displays the top-level values for the JSON in a <a href="https://documentation.xojo.com/topics/user_interface/desktop/desktop_controls/list_box.html#Hierarchical_Lists_.28Tree_View.29">hierarchical ListBox</a>. The RowTag gets the JSONItem for the item that is displayed.</p>
<p>In the ListBox.ExpandRows event, the JSONItem that is displayed is passed to the DisplayJSON method to then display it&#8217;s top-level items. You can keep expanding the JSON until you reach an end item.</p>
<p>Check out these doc topics to learn more about JSON:</p>
<ul>
<li><a href="https://documentation.xojo.com/topics/file_managment/reading_and_writing_data_in_json_format.html">User Guide:JSON</a> topic</li>
<li><a href="https://documentation.xojo.com/api/text/json/jsonitem.html">JSONItem</a> class</li>
</ul>
<p>Update (March 11, 2019): Xojo developer extraordinaire Kem Tekinay took this project and enhanced it with an even better display. You can grab his project here: <a href="http://files.xojo.com/BlogExamples/JSONTree2.xojo_binary_project">JSONTree2</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The Klingon Translator App You Definitely Need</title>
		<link>https://blog.xojo.com/2019/03/07/the-klingon-translator-app-you-definitely-need/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Thu, 07 Mar 2019 10:00:02 +0000</pubDate>
				<category><![CDATA[Fun]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Star Trek]]></category>
		<category><![CDATA[Translation]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=5512</guid>

					<description><![CDATA[chay' tlhIngan Hol mughwI' chenmoH qaStaHvIS 20 tlhegh ngoq xojo je ghoj

Qapla']]></description>
										<content:encoded><![CDATA[<p>I love the new Star Trek Discovery and there are a fair amount of Klingons in it, from time to time. It occurred to me that someone has probably built a web service to translate English to Klingon and if so, I <em>needed</em> to build a Xojo app to use it.</p>
<p>A quick Google search turned up an API by FunTranslations: <a href="https://funtranslations.com/api/klingon">https://funtranslations.com/api/klingon</a></p>
<p>It has simple usage where you send along the text in English and you get back a JSON result containing the text translated to Klingon. Here&#8217;s the result of my 15 minutes of effort to use this in a Xojo desktop app:</p>
<p><span id="more-5512"></span></p>
<p><img loading="lazy" decoding="async" class="wp-image-5513 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2019/03/2019-03-06_15-34-28.png" alt="" width="600" height="422" /></p>
<p>This is a pretty simple project with less than 20 lines of code.</p>
<p>You can recreate the layout using a couple TextFields and a Button. I used <a href="https://documentation.xojo.com/api/networking/urlconnection.html">URLConnection</a> to connect to the web service. You can also add that to the layout by dragging an Object from the Library and changing its Super property to &#8220;URLConnection&#8221;. I named this object &#8220;KlingonAPI&#8221;.</p>
<p>In the Button&#8217;s Action event the code sets up the call to the web service using the text entered in the first TextArea:</p>
<pre>Dim url As String = "https://api.funtranslations.com/translate/klingon.json"

Dim param As String = "text=" + EncodeURLComponent(EnglishArea.Text)

KlingonAPI.SetRequestContent(param, "application/x-www-form-urlencoded")
KlingonAPI.Send("POST", url)</pre>
<p>In the KlingonAPI URLConnection object, add the ContentReceived event. This code grabs the translated Klingon text from the JSON and displays it in the 2nd TextArea:</p>
<pre>Try
  Dim json As New JSONItem(content)
  Dim contents As JSONItem
  contents = json.Value("contents")
  Dim klingonTranslation As String = contents.Value("translated")
  KlingonArea.Text = klingonTranslation
Catch e As JSONException
  MsgBox("Error processing API call. Content=" + content)
End Try</pre>
<p>You can also add the Error event and have it display an error in case there&#8217;s a problem with the API call:</p>
<pre>MsgBox("API Error: " + e.Message)</pre>
<p>And that&#8217;s all there is to it.</p>
<p>You can download the project from here: <a href="http://files.xojo.com/BlogExamples/KlingonTranslator.xojo_binary_project">KlingonTranslator Project</a>, just remember some things can&#8217;t be translated!</p>
<p><a href="https://imgflip.com/i/1rqwov"><img loading="lazy" decoding="async" class="aligncenter" title="made at imgflip.com" src="https://i.imgflip.com/1rqwov.jpg" width="438" height="329" /></a></p>
<p>I&#8217;ll leave it up to you to implement a Klingon to English translator, although you may want to make that a mobile app in case you are ever teleported to the bridge of a Klingon vessel.</p>
<p>Qapla&#8217;</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>#JustCode Challenge Week 10 &#8211; NetTank</title>
		<link>https://blog.xojo.com/2018/08/24/justcode-challenge-week-10-nettank/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Fri, 24 Aug 2018 10:00:54 +0000</pubDate>
				<category><![CDATA[Fun]]></category>
		<category><![CDATA[#JustCode]]></category>
		<category><![CDATA[Games]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[UDP]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=4851</guid>

					<description><![CDATA[For the 10th week of the #JustCode Challenge I took a look at networking. For my project this week I've created a networked version of the Combat game, which has two tanks on the screen shooting at each other. ]]></description>
										<content:encoded><![CDATA[<p>For the 10th week of the #JustCode Challenge I took a look at networking. For my project this week I&#8217;ve created a networked version of the Combat game, which has two tanks on the screen shooting at each other. The network version allows you to control one tank with the app running on your computer and someone else to control the other tank with the app running on their computer. I call it NetTank.</p>
<p><span id="more-4851"></span></p>
<p>I made a version of Combat in Xojo a while ago (it&#8217;s included in the Xojo examples folder in the Download) so I figured I would start there. To provide network capabilities to a game, you generally want to go with something fast and that means UDP (User Datagram Protocol), which is provided by the UDPSocket. There&#8217;s also a UDPSocket example included with Xojo which I used as a reference.</p>
<p>To start I first decided what data I wanted to send back and forth. I narrowed it down to these actions:</p>
<ul>
<li>JoinAction</li>
<li>MoveAction</li>
<li>HitAction</li>
</ul>
<p>These are all sent as JSON by broadcasting to a Multicast group.</p>
<p>JoinAction is sent when a game is first started to allow the two client NetTank apps to negotiate who is player 1 and who is player 2. The two actions are &#8220;ready&#8221; and &#8220;player2&#8221;.</p>
<p>MoveAction contains the action that your tank just did to send to the other client so it can update its display. Initially I was just sending actions for &#8220;forward&#8221;, &#8220;left&#8221;, &#8220;right&#8221; and &#8220;fire&#8221;. But because UDP does not guarantee messages are received, the tanks would sometimes get out of sync if a lot of moves were sent quickly when there was network congestion. So I instead decided to send the actual xy coordinate and rotation angle for a forward move so that should a message get lost it will at least have the correct information in a future forward message.</p>
<p>When a tank is hit, HitAction contains the new location for the tank (it is moved to a random spot on the screen when hit) to send to the other client.</p>
<p>Because the Combat game already ran using Timers, I didn&#8217;t really have to change much of the original Combat game code for NetTank. I added a UDPSocket to the main CombatWindow and in its DataAvailable event I have the code to check for the messages and update the Tank objects as needed.</p>
<p>I also had to make a few tweaks to the main code to send the JSON messages for movements, hits and to properly identify which tank to move.</p>
<p>To try the game you&#8217;ll need to run it on two different computers. The first one that starts becomes player 1 (blue) and the second one is player 2 (red). Use the arrow keys to move the tanks and press the space bar to fire.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-4856" src="https://blog.xojo.com/wp-content/uploads/2018/08/2018-08-22_14-05-40.png" alt="" width="1220" height="437" /></p>
<p><a href="http://files.xojo.com/JustCode/NetworkTank.zip">Download the project</a> or <a href="https://gitlab.com/xojo/NetTank">check it out on GitLab</a>.</p>
<p>Add your #JustCode project to the <a href="https://forum.xojo.com/49555-just-code-challenge-week-10-projects">week 10 forum conversation</a>.</p>
<p>Download and check out earlier projects:</p>
<ul>
<li>Week 9: <a href="https://blog.xojo.com/2018/08/17/justcode-challenge-week-9-quote-web-service/">Quote Web Service</a></li>
<li>Week 8: <a href="https://blog.xojo.com/2018/08/10/justcode-challenge-week-8-jumpstart-app-launcher/">JumpStart App Launcher</a></li>
<li>Week 7: <a href="https://blog.xojo.com/2018/08/03/justcode-challenge-week-7-pitch-tracker/">Pitch Tracker</a></li>
<li>Week 6: <a href="https://blog.xojo.com/2018/07/27/justcode-challenge-week-6-bubble-popper/">Bubble Popper</a></li>
<li>Week 5: <a href="https://blog.xojo.com/2018/07/20/justcode-challenge-week-5-math-quiz/">Math Quiz</a></li>
<li>Week 4: <a href="https://blog.xojo.com/2018/07/13/justcode-challenge-week-4-mini-golf-scorekeeper/">Mini-Golf ScoreKeeper</a></li>
<li>Week 3: <a href="https://blog.xojo.com/2018/07/06/just-code-challenge-week3/">Dogs Up!</a></li>
<li>Week 2: <a href="https://blog.xojo.com/2018/06/29/just-code-challenge-week2/">Password Generator</a></li>
<li>Week 1: <a href="https://blog.xojo.com/2018/06/22/just-code-challenge-week1/">Color Picker</a></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>#JustCode Challenge Week 9 &#8211; Quote Web Service</title>
		<link>https://blog.xojo.com/2018/08/17/justcode-challenge-week-9-quote-web-service/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Fri, 17 Aug 2018 10:00:24 +0000</pubDate>
				<category><![CDATA[Fun]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[#JustCode]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[Web Service]]></category>
		<category><![CDATA[webdev]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=4829</guid>

					<description><![CDATA[We're wrapping up week 9 of #JustCode with a web app that demonstrates a web service, JSON and SQLite. The web app functions as both an app with a UI and a web service. It lets you enter your own quotes which are saved in a SQLite database. The web service randomly fetches a quote and returns it as JSON.]]></description>
										<content:encoded><![CDATA[<p>We&#8217;re wrapping up week 9 of #JustCode with a web app that demonstrates a web service, JSON and SQLite. The web app functions as both an app with a UI and a web service. It lets you enter your own quotes which are saved in a SQLite database. The web service randomly fetches a quote and returns it as JSON.</p>
<p><span id="more-4829"></span></p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-4831 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2018/08/2018-08-15_12-22-31.png" alt="" width="591" height="490" /></p>
<p>The SQLite database has just a single table called Quote with this structure:</p>
<pre>CREATE TABLE Quote (
ID INTEGER NOT NULL,
QuoteText TEXT,
QuoteSource TEXT, 
PRIMARY KEY (ID)
);</pre>
<p>To randomly fetch a single quote from the table, this SQL is used:</p>
<pre>SELECT QuoteText, QuoteSource FROM Quote ORDER BY RANDOM() LIMIT 1;</pre>
<p>As companion apps, I&#8217;ve also included simple desktop and iOS apps that call the web service to display a quote.</p>
<p>The raw JSON that is returned looks like this:</p>
<pre>{"QuoteText":"Simple things should be simple. Complex things should be possible.","QuoteSource":"Alan Kay"}</pre>
<p>I&#8217;ve published a version of this on <a href="https://www.xojo.com/cloud/">Xojo Cloud</a>. <a href="http://demos.xojo.com/QuoteService/">Access the app</a>.</p>
<p>Access the web service <a href="http://demos.xojo.com/QuoteService/index.cgi/api/quote">here</a>.</p>
<p>You can <a href="http://files.xojo.com/JustCode/QuoteService.zip">download the projects</a> or check it all out <a href="https://gitlab.com/xojo/QuoteService">on GitLab</a>.</p>
<p>Add your #JustCode project to the <a href="https://forum.xojo.com/49401-just-code-challenge-week-9-projects">week 9 forum conversation</a>.</p>
<p>Download and check out earlier projects:</p>
<ul>
<li>Week 8: <a href="https://blog.xojo.com/2018/08/10/justcode-challenge-week-8-jumpstart-app-launcher/">JumpStart App Launcher</a></li>
<li>Week 7: <a href="https://blog.xojo.com/2018/08/03/justcode-challenge-week-7-pitch-tracker/">Pitch Tracker</a></li>
<li>Week 6: <a href="https://blog.xojo.com/2018/07/27/justcode-challenge-week-6-bubble-popper/">Bubble Popper</a></li>
<li>Week 5: <a href="https://blog.xojo.com/2018/07/20/justcode-challenge-week-5-math-quiz/">Math Quiz</a></li>
<li>Week 4: <a href="https://blog.xojo.com/2018/07/13/justcode-challenge-week-4-mini-golf-scorekeeper/">Mini-Golf ScoreKeeper</a></li>
<li>Week 3: <a href="https://blog.xojo.com/2018/07/06/just-code-challenge-week3/">Dogs Up!</a></li>
<li>Week 2: <a href="https://blog.xojo.com/2018/06/29/just-code-challenge-week2/">Password Generator</a></li>
<li>Week 1: <a href="https://blog.xojo.com/2018/06/22/just-code-challenge-week1/">Color Picker</a></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>#JustCode Challenge Week 8 &#8211; JumpStart App Launcher</title>
		<link>https://blog.xojo.com/2018/08/10/justcode-challenge-week-8-jumpstart-app-launcher/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Fri, 10 Aug 2018 10:10:46 +0000</pubDate>
				<category><![CDATA[Fun]]></category>
		<category><![CDATA[#JustCode]]></category>
		<category><![CDATA[Atari]]></category>
		<category><![CDATA[Canvas]]></category>
		<category><![CDATA[ContainerControl]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[UI]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=4815</guid>

					<description><![CDATA[Replicating an app launcher he originally made for the Atari, Paul's JumpStart app for week 8 of #JustCode demonstrates save/load JSON, ContainerControl and Canvas-based Buttons in Xojo.]]></description>
										<content:encoded><![CDATA[<p>A long, long time ago (1989) one of the first apps I ever made was an app launcher for the Atari ST. I called it JumpSTART. I originally wrote it in <a href="https://en.wikipedia.org/wiki/GFA_BASIC">GFA BASIC</a> and then later re-implemented it in <a href="https://en.wikipedia.org/wiki/Pascal_(programming_language)">Pascal</a> (<a href="https://archive.org/details/OSSPersonalPascal">OSS Personal Pascal</a>, technically).</p>
<p>When I got my first modem I went online with <a href="https://en.wikipedia.org/wiki/GEnie">Genie</a> and <a href="https://en.wikipedia.org/wiki/Delphi_(online_service)">Delphi</a> and uploaded JumpSTART as freeware. Even though it was freeware, I got a few checks in the mail from people that liked it.</p>
<p>I was reminded of JumpSTART when I saw my dock getting crowed. I thought replicating JumpSTART in Xojo would be a good project for week 8 of #JustCode. Though let&#8217;s just call it JumpStart this time around.</p>
<p><span id="more-4815"></span></p>
<p>This is what JumpSTART looked like on monochrome 640&#215;480 screen:</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-4816 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2018/08/2018-08-09_14-06-09.png" alt="" width="640" height="434" /></p>
<p>JumpStart in Xojo is greatly simplified and looks like this:</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-4817 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2018/08/2018-08-09_14-10-06.png" alt="" width="680" height="392" /></p>
<p>The Xojo version automatically saves and loads the apps you&#8217;ve added so there was no need for separate Load/Save, Re-Read buttons. Technically they don&#8217;t have to be apps as even a document file can be launched as well.</p>
<p>You can right-click on an app button after you&#8217;ve added it to Rename, Change or Clear it so that also removed the need for some UI controls. And you just click on an empty button to add an app to it. When you click on a button with an app assigned, the app is launched and JumpStart hides itself.</p>
<p>This Xojo app demonstrates the use of a Canvas-based button, ContainerControls added dynamically to a window, and saving/loading JSON. The Canvas-based button will let me tweak the display, colors and maybe display an icon there.</p>
<p>You can <a href="http://files.xojo.com/JustCode/JumpStart.xojo_binary_project.zip">download the project</a> or <a href="https://gitlab.com/xojo/JumpStart">check it out on GitLab</a>.</p>
<p>As an added code treat, I&#8217;ve posted the <a href="https://github.com/paullefebvre/JumpSTART-AtariST">original JumpSTart Pascal code to GitHub</a>. FWIW, the original Pascal source is just over 1300 lines of code. The Xojo version is about 180.</p>
<p>Add your #JustCode project to the <a href="https://forum.xojo.com/49298-just-code-challenge-week-8-projects">week 8 forum conversation</a>.</p>
<p>Download and check out earlier projects:</p>
<ul>
<li>Week 7: <a href="https://blog.xojo.com/2018/08/03/justcode-challenge-week-7-pitch-tracker/">Pitch Tracker</a></li>
<li>Week 6: <a href="https://blog.xojo.com/2018/07/27/justcode-challenge-week-6-bubble-popper/">Bubble Popper</a></li>
<li>Week 5: <a href="https://blog.xojo.com/2018/07/20/justcode-challenge-week-5-math-quiz/">Math Quiz</a></li>
<li>Week 4: <a href="https://blog.xojo.com/2018/07/13/justcode-challenge-week-4-mini-golf-scorekeeper/">Mini-Golf ScoreKeeper</a></li>
<li>Week 3: <a href="https://blog.xojo.com/2018/07/06/just-code-challenge-week3/">Dogs Up!</a></li>
<li>Week 2: <a href="https://blog.xojo.com/2018/06/29/just-code-challenge-week2/">Password Generator</a></li>
<li>Week 1: <a href="https://blog.xojo.com/2018/06/22/just-code-challenge-week1/">Color Picker</a></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Xojo and Community Growth in 2017</title>
		<link>https://blog.xojo.com/2017/12/11/xojo-and-community-growth-in-2017/</link>
		
		<dc:creator><![CDATA[Alyssa Foley]]></dc:creator>
		<pubDate>Mon, 11 Dec 2017 08:00:07 +0000</pubDate>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Fun]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[XDC]]></category>
		<category><![CDATA[64-bit]]></category>
		<category><![CDATA[AprendeXojo]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[LLVM]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=3611</guid>

					<description><![CDATA[2017 has been a good year for Xojo! We hit some bumps but we&#8217;re ending the year with the much-awaited Xojo 64-bit IDE released in Xojo&#8230;]]></description>
										<content:encoded><![CDATA[<div>2017 has been a good year for Xojo! We hit some bumps but we&#8217;re ending the year with the much-awaited Xojo 64-bit IDE released in <a href="https://www.xojo.com/download/">Xojo 2017r3</a>.</div>
<div></div>
<div>Though we didn&#8217;t have a XDC in 2017, we&#8217;re gearing up for <a href="https://www.xojo.com/xdc/">XDC 2018 in Denver</a> in April. This is the longest between conferences in many years and we&#8217;re seeing an increase in early registrations. If you are planning on attending, please register soon. We have sold out before!</div>
<p><span id="more-3611"></span></p>
<div>Some highlights from the Xojo Blog in 2017:</div>
<ul>
<li>Growing? Read how one Xojo user took his app from <a href="https://blog.xojo.com/2017/04/25/taking-your-app-from-in-house-to-commercial/">in-house to commercial</a>,</li>
<li>Transitioning Windows Graphics: <a href="https://blog.xojo.com/2017/04/12/windows-graphics-direct2ddirectwrite-direction/">Direct2D/DirectWrite</a>,</li>
<li><a href="http://blog.xojo.com/2017/03/28/raspberry-pi-remote-debugging/">Remote Debugger for Raspberry Pi</a> and the <a href="https://blog.xojo.com/2017/04/12/windows-graphics-direct2ddirectwrite-direction/">Programming with Raspberry Pi Book</a>,</li>
<li>Check out our highly popular <a href="https://jsonfeed.org">JSON Feed</a> blog post series for <a href="https://blog.xojo.com/2017/05/31/json-feed-ios-app/">iOS</a>, <a href="https://blog.xojo.com/2017/05/30/json-feed-web-app/">web</a> and <a href="https://blog.xojo.com/2017/06/01/json-feed-desktop-app/">Desktop</a>,</li>
<li>We updated Xojo&#8217;s Linux Desktop framework to <a href="https://blog.xojo.com/2017/08/15/goodbye-gtk-2-hello-gtk-3/">GTK3</a> and HiDPI,</li>
<li>Whatever happens, Xojo has your back if <a href="https://blog.xojo.com/2017/09/29/what-it-means-for-your-xojo-projects-if-mac-goes-arm/">Mac goes ARM</a>, and</li>
<li>Jump into our ongoing Compiler blog post series: <a href="https://blog.xojo.com/2017/12/04/llvm-everywhere/">LLVM Everywhere</a>, <a href="https://blog.xojo.com/2017/12/06/compilers-101-overview-and-lexer/">Compiler 101 &#8211; Overview and Lexer</a>, and <a href="https://blog.xojo.com/2017/12/08/compilers-102-parser/">Compilers 102 &#8211; Parser</a>.</li>
</ul>
<p>A special mention on the topic of Net Neutrality in the US. Geoff has <a href="https://blog.xojo.com/2017/12/01/the-last-mile-why-net-neutrality-is-a-must/">shared his point of view</a> and we hope you make your voice heard to the <a href="https://www.fcc.gov/ecfs/filings/express">FCC</a> before December 14th. This is an issue that effects us all.</p>
<p>The Xojo community continues to grow with developers switching from VB, emerging citizen developers and small businesses all discovering what they can with Xojo. In the last 12 months the <a href="https://forum.xojo.com">Xojo Forum</a> has welcomed 1,688 new forum members and 60,772 forum posts.</p>
<p>Our blog post from back in June, <a href="https://blog.xojo.com/2017/06/21/daring-to-defy-software-extinction-a-limited-history/">Daring to Defy Software Extinction</a> sums up Xojo and Dev Tool history with some perspective. We&#8217;re proud of what we, along with the Xojo Community, have built over the past 21 years and we look forward to 2018 &#8211; Android support, I&#8217;m looking at you!</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3010" src="https://blog.xojo.com/wp-content/uploads/2017/06/Ltd-History-of-Dev-Tools-Info-Graphic.png" alt="" width="800" height="2000" /></p>
<p>From everyone at Xojo, thank you for your continued support. This community is truly one-of-a-kind and we look forward to all that 2018 has in store!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Xojo Monthly Round Up: JSON, NASA &#038; Punny References</title>
		<link>https://blog.xojo.com/2017/06/30/xojo-monthly-round-up-json-nasa-punny-references/</link>
		
		<dc:creator><![CDATA[Alyssa Foley]]></dc:creator>
		<pubDate>Fri, 30 Jun 2017 07:00:37 +0000</pubDate>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Women in Tech]]></category>
		<guid isPermaLink="false">http://blog.xojo.com/?p=2921</guid>

					<description><![CDATA[A few of our favorite things this month. See what the Xojo team was talking about in our Slack watercolor channel!]]></description>
										<content:encoded><![CDATA[<p>We&#8217;re starting a new thing! At the end of each month we&#8217;ll round up a few of our favorite things &#8211; from blog posts, announcements, technology, science and whatever other stuff the Xojo team thinks was noteworthy and I&#8217;ll post it. It&#8217;s the new Xojo Monthly Round Up!</p>
<p><span id="more-2921"></span></p>
<p>Our favorite Xojo Blog post in June was actually 3 posts: <a href="https://blog.xojo.com/2017/05/30/json-feed-web-app/">JSON Feed Web App</a>, <a href="https://blog.xojo.com/2017/05/31/json-feed-ios-app/">JSON Feed iOS App</a>, and JSON Feed Desktop App. Paul got to <a href="https://twitter.com/gruber/status/867194443396501505">talk server updates</a> with John Gruber (he&#8217;s <em>still</em> talking about around the watercoolor).</p>
<p>Sorry if no one replied to your email back on June 9th, we were reading the reviews on <a href="https://www.amazon.com/gp/product/B0047E0EII/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&amp;tag=fiwofoli-20&amp;camp=1789&amp;creative=9325&amp;linkCode=as2&amp;creativeASIN=B0047E0EII&amp;linkId=dcb616b9bfd2db2f2fd81e86ce2ccd22">this Banana Slicer</a>.</p>
<p>Javier brought to our attention that <a href="http://www.popularmechanics.com/space/a17991/voyager-1-voyager-2-retiring-engineer/">NASA had needed engineers that knew assembly languages and FORTRAN</a>. Sorry y&#8217;all, the post has been filled.</p>
<p>I was excited to learn that <a href="http://www.npr.org/2017/06/11/532249940/meet-your-lucky-stars-nasa-announces-a-new-class-of-astronaut-candidates">this year&#8217;s Astronaut class</a> of 12 includes 5 women!</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-3019" src="https://blog.xojo.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-10.21.27-AM.png" alt="" width="395" height="291" /></p>
<p>We just can&#8217;t get away from JSON! Paul found this <a href="http://blog.sqlizer.io/posts/json-history/">brief history of JSON</a>.</p>
<p>This <a href="https://en.wikipedia.org/wiki/CodeWarrior">punny bit</a> about the origin of the name CodeWarrior that we learned when researching its history for our post <a href="http://blog.xojo.com/2017/06/21/daring-to-defy-software-extinction-a-limited-history/">Daring to Defy Software Extinction</a> about the longevity of dev tools.</p>
<p>Speaking of puns, did you know there was a <a href="https://www.reddit.com/r/programmingpuns/">Programming Puns subreddit</a>? Now you do!</p>
<p>Catch <a href="http://vxug.org/meetings/">this recap</a> of the June Virtual Xojo User Group meeting &#8211; that&#8217;s VXUG for those of you in the know <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>Jason found out that GE is building the world’s largest ‘Additive’ Machine which will <a href="http://www.gereports.com/ge-building-worlds-largest-additive-machine-3d-printing-metals/">3D print metal parts for jets</a> from metal powder.</p>
<p>That&#8217;s all for June, we hope you enjoyed wasting a little time with us. See you next month!</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-3017" src="https://blog.xojo.com/wp-content/uploads/2017/06/Round-UP-2.png" alt="" width="560" height="315" /></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>JSON Feed Desktop App</title>
		<link>https://blog.xojo.com/2017/06/01/json-feed-desktop-app/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Thu, 01 Jun 2017 01:26:13 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<guid isPermaLink="false">http://blog.xojo.com/?p=2900</guid>

					<description><![CDATA[In this post, I'll show you how to create a Xojo desktop app to display the JSON feed for Daring Fireball in less than 20 lines of code. This app works without changes on macOS, Windows and Linux.]]></description>
										<content:encoded><![CDATA[<p>Recently, a new syndication format was introduced by Brent Simmons and Manton Reece called <a href="https://jsonfeed.org/">JSON Feed</a>. It is an alternative to RSS/Atom to get feeds for blog posts and podcasts. RSS/Atom are XML-based making them complex to work with. As its name implies JSON Feed uses JSON and is much simpler. I&#8217;ve shown in previous posts how easy it is to <a href="http://blog.xojo.com/2017/05/30/json-feed-web-app/">make a web</a> and <a href="http://blog.xojo.com/2017/05/31/json-feed-ios-app/">iOS apps </a>with Xojo to display the feed.</p>
<p>In this post, I&#8217;ll show you how to create a Xojo desktop app to display the JSON feed for <a href="https://daringfireball.net">Daring Fireball</a> in less than 20 lines of code. This app works without changes on macOS, Windows and Linux.</p>
<p><span id="more-2900"></span></p>
<h2>Designing the User Interface</h2>
<p>To start, <a href="http://www.xojo.com/download/">download Xojo for free</a>, install and launch it. At the <a href="http://developer.xojo.com/userguide/fundamentals">Project Chooser</a>, select &#8220;Desktop&#8221;, enter &#8220;JSONFeed&#8221; as the Application Name and click OK.</p>
<p>You are now looking at the <a href="http://developer.xojo.com/userguide/layout-editor">Layout Editor</a>. You can drag controls from the <a href="http://developer.xojo.com/userguide/library-inspector">Library</a> on the right to create your user interface. For this example, you&#8217;ll want 6 controls: 2 Labels, a TextField, a Button, a ListBox and an HTMLViewer. Drag them onto the web page layout as shown below:</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-2902" src="https://blog.xojo.com/wp-content/uploads/2017/05/2017-05-26_15-40-06.png" alt="" width="1355" height="823" /></p>
<p>Now click the <a href="http://developer.xojo.com/userguide/library-inspector">Inspector</a> button on the toolbar to see the Inspector which shows the properties. You are going to want to change some properties for a few of the controls. Click on a control to see its properties in the Inspector.</p>
<ol>
<li>Change the text property for the Label next to the TextField to be &#8220;Feed URL:&#8221;.</li>
<li>For the TextField, change its name to &#8220;URLField&#8221; and set its Text to the URL for the Daring Fireball JSON Feed: &#8220;https://daringfireball.net/feeds/json&#8221;. You&#8217;ll also want to click the right-most lock in the Locking section to allow this field to grow in size to fit the web page (Left, Top and Right should all be &#8220;locked&#8221;).</li>
<li>Click the button and change its Caption to &#8220;Load&#8221;. In the Locking section, make sure that only Top and Right are locked.</li>
<li>Select the Label below the TextField and change its name to &#8220;FeedTitleLabel&#8221;.</li>
<li>Click the ListBox and change its name to &#8220;FeedList&#8221;. Also change the ColumnCount to 2 and ColumnWidths to 75%. Also set the locking so that Left, Top and Right are locked.
<ol>
<li>To set the headers for the ListBox,</li>
</ol>
</li>
<li>Now select the HTMLViewer and change its Name to &#8220;ArticleViewer&#8221; and set the locking so that Left, Top, Right and Bottom are locked.</li>
<li>Lastly, you want to add a non-UI control to the web page. This control is what will connect and download the JSON Feed. Click on Library in the toolbar and scroll down to find the control called &#8220;Generic Object&#8221;. Drag that on to the web page layout where it will appear at the Shelf on the bottom. Switch to the Inspector and change the control Name to &#8220;FeedSocket&#8221; and the Super to &#8220;Xojo.Net.HTTPSocket&#8221;.</li>
</ol>
<p>That&#8217;s it for the UI. You can click the Run button on the toolbar to start this web app so you can see what it looks like.. It won&#8217;t do anything yet, but you can make sure all the controls are positioned properly. Try resizing the window as well.</p>
<h2>Adding Code</h2>
<p>Now it&#8217;s time to add the code. Start by double-clicking on the button the window layout. This displays the Event Handler window. Click on Action and select OK. You are now looking at a blank <a href="http://developer.xojo.com/userguide/code-editor">Code Editor</a>. The code you put here runs when the button is clicked. Your code needs to tell the FeedSocket to get the JSON feed for the URL entered in the TextField. This is the code to do that:</p>
<pre>FeedSocket.Send("GET", URLField.Text.ToText)</pre>
<p>Now you need to put code in FeedSocket to parse the JSON Feed that gets returned. Double-click FeedSocket to display the Event Handler window, select PageReceived and click OK. The code below <a href="http://developer.xojo.com/xojo-core-textencoding$ConvertDataToText">converts the JSON from binary data to Text</a>, then <a href="http://developer.xojo.com/xojo-data$ParseJSON">parses the JSON in the Text to get a Dictionary</a>. From the <a href="http://developer.xojo.com/xojo-core-dictionary">Dictionary</a> you can get the array of articles in the JSON (called items), loop through them and add them to the list.</p>
<pre>If HTTPStatus = 200 Then
  Dim jsonText As Text = Xojo.Core.TextEncoding.UTF8.ConvertDataToText(Content)
  Dim jsonDict As Xojo.Core.Dictionary = Xojo.Data.ParseJSON(jsonText)
 
  FeedList.DeleteAllRows
 
  // Display the feed title
  FeedTitleLabel.Text = jsonDict.Value("title")
 
  // Display the feed articles
  Dim items() As Auto = jsonDict.Value("items")
  For Each article As Xojo.Core.Dictionary In items
    Dim title As Text = article.Value("title")
    Dim pubDate As Text = article.Value("date_published")
    FeedList.AddRow(title, pubDate)
 
    // Save article content
    FeedList.RowTag(FeedList.LastIndex) = article.Value("content_html")
  Next
End If</pre>
<p>The last bit of code displays the content for the selected article. Double-click the FeedList control and in the Event Handler window choose Change and press OK. This is the event that is called when you click on a row in the list. In the Code Editor add this code to get the article content (that was previously saved in the RowTag) and load it into the ArticleViewer to display:</p>
<pre>Dim content As Text = Me.RowTag(Me.ListIndex)
ArticleViewer.LoadPage(content, GetTemporaryFolderItem)</pre>
<p>You can now run the project to see it in action. Once the page displays, click the Load button to load the Daring Fireball JSON Feed. Click on an article to view it. Here it is running on macOS:</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-2903" src="https://blog.xojo.com/wp-content/uploads/2017/05/2017-05-26_15-52-58.png" alt="" width="617" height="565" /></p>
<p>With a <a href="https://www.xojo.com/store">Xojo license</a> you can build this app for multiple platforms, including macOS, Windows and Linux, without having to change anything. Simply select the appropriate boxes in the Build Settings on the left.</p>
<p>With a little more work on your part, you can turn this into a full-featured JSON Feed viewer. For example, you can let users add multiple feeds and check them periodically for new posts.</p>
<p>Related posts: <a href="https://blog.xojo.com/2017/05/31/json-feed-ios-app/">JSON Feed iOS App</a> and <a href="https://blog.xojo.com/2017/05/30/json-feed-web-app/">JSON Feed Web App</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>JSON Feed iOS App</title>
		<link>https://blog.xojo.com/2017/05/31/json-feed-ios-app/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Wed, 31 May 2017 16:56:23 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Mobile]]></category>
		<guid isPermaLink="false">http://blog.xojo.com/?p=2867</guid>

					<description><![CDATA[In a previous post I showed how easy it was to create a web app that displays the JSON Feed for Daring Fireball. In this post, I'll show you how to make an iOS app to do it.]]></description>
										<content:encoded><![CDATA[<p>In a <a href="http://blog.xojo.com/2017/05/30/json-feed-web-app/">previous post</a> I showed how easy it was to create a web app that displays the <a href="https://jsonfeed.org/">JSON Feed</a> for <a href="http://daringfireball.net">Daring Fireball</a>. In this post, I&#8217;ll show you how to make an iOS app to do it.</p>
<p><span id="more-2867"></span></p>
<h2>Designing the User Interface</h2>
<p>To start, <a href="http://www.xojo.com/download/">download Xojo for free</a>, install and launch it. At the <a href="http://developer.xojo.com/userguide/fundamentals">Project Chooser</a>, select “iOS”, enter “JSONFeed” as the Application Name and click OK.</p>
<p>You are now looking at the <a href="http://developer.xojo.com/userguide/layout-editor">Layout Editor</a>. You can drag controls from the <a href="http://developer.xojo.com/userguide/library-inspector">Library</a> on the right to create your user interface. For this example you&#8217;ll create an iPhone app, so we&#8217;ll focus on that layout. The iPhone app will consist of two &#8220;views&#8221;. The first view will let you enter the JSON Feed URL and then display the article titles. When you click on an article, the second view will appear displaying the article content.</p>
<p>By default Xojo created your project with the first view, called View1. You&#8217;ll want to drag three controls to this view: a TextField, a Button and a Table. Arrange them to look like this:</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-2880" src="https://blog.xojo.com/wp-content/uploads/2017/05/2017-05-24_15-37-36.png" alt="" width="1340" height="1008" /></p>
<p>Next you&#8217;ll want to set some of the properties for these controls. But first, change the name of View1. Click the Inspector button on the toolbar to show properties and then click anywhere on the View that is not a control. This displays the properties for the view itself.</p>
<p>In the view change these properties:</p>
<ul>
<li>Name: FeedView</li>
<li>NavigationBarVisible: ON</li>
<li>Title: JSON Feed</li>
</ul>
<p>You&#8217;ll next change some properties for each of the controls. Click on the TextField and set these properties:</p>
<ul>
<li>Name: URLField</li>
<li>PlaceHolder: Enter JSON Feed URL</li>
<li>Text: https://daringfireball.net/feeds/json</li>
</ul>
<p>Now click on the Button and change these fields:</p>
<ul>
<li>Name: LoadButton</li>
<li>Caption: Load</li>
</ul>
<p>Lastly, click on the Table and change these fields:</p>
<ul>
<li>Name: FeedTable</li>
</ul>
<p>Lastly, you want to add a non-UI control to the view. This control is what will connect and download the JSON Feed. Click on Library in the toolbar and scroll down to find the control called “Generic Object”. Drag that on to the view layout where it will appear at the Shelf on the bottom. Switch to the Inspector and change these properties:</p>
<ul>
<li>Name: FeedSocket</li>
<li>Super: Xojo.Net.HTTPSocket</li>
</ul>
<p>With this view finished you now need to create the second view. From the Insert button or menu, select &#8220;View&#8221; to add a new view to the project. Click on the view and change these properties (select the Inspector if it is not visible):</p>
<ul>
<li>Name: ArticleView</li>
<li>NavigationBarVisible: ON</li>
</ul>
<p>This view has only a single control on it: HTMLViewer. Drag it onto the view so that it takes up the entire area of the layout like this:</p>
<p>Click on the Inspector to show the properties for the HTMLViewer and change these properties:</p>
<ul>
<li>Name: ArticleViewer</li>
</ul>
<p>With the two views done, you can now move on to adding code.</p>
<h2>Adding Code</h2>
<p>Now it’s time to add the code. Start by double-clicking on the button FeedView. This displays the Event Handler window. Click on Action and select OK. You are now looking at a blank <a href="http://developer.xojo.com/userguide/code-editor">Code Editor</a>. The code you put here runs when the button is tapped. Your code needs to tell the FeedSocket to get the JSON feed for the URL entered in the TextField. This is the code to do that:</p>
<pre>FeedSocket.Send("GET", URLField.Text)</pre>
<p>Next you need to put code in FeedSocket to parse the JSON Feed that gets returned. Double-click FeedSocket to display the Event Handler window, select PageReceived and click OK. The code below <a href="http://developer.xojo.com/xojo-core-textencoding$ConvertDataToText">converts the JSON from binary data to Text</a>, then <a href="http://developer.xojo.com/xojo-data$ParseJSON">parses the JSON in the Text to get a Dictionary</a>. From the <a href="http://developer.xojo.com/xojo-core-dictionary">Dictionary</a> you can get the array of articles in the JSON (called items), loop through them and add them to the table.</p>
<pre>If HTTPStatus = 200 Then
  Dim jsonText As Text = Xojo.Core.TextEncoding.UTF8.ConvertDataToText(Content)
  Dim jsonDict As Xojo.Core.Dictionary = Xojo.Data.ParseJSON(jsonText)
 
  FeedTable.RemoveAll
 
  // Display the feed title
  Self.Title = jsonDict.Value("title")
 
  // Display the feed articles
  FeedTable.AddSection("")
  Dim items() As Auto = jsonDict.Value("items")
  For Each article As Xojo.Core.Dictionary In items
    Dim title As Text = article.Value("title")
    Dim pubDate As Text = article.Value("date_published")
 
    // Create cell with values and content in the Tag
    Dim cell As iOSTableCellData = FeedTable.CreateCell
    cell.Text = title
    cell.DetailText = pubDate
    cell.Tag = article.Value("content_html")
    FeedTable.AddRow(0, cell)
  Next
End If</pre>
<p>The next bit of code displays the content for the selected article. Double-click the FeedTable control and in the Event Handler window choose Action and press OK. This is the event that is called when you tap on a row in the list. In the Code Editor add this code to get the article content (that was previously saved in the RowTag) and send it to the ArticleView to display there:</p>
<pre>Dim content As Text = Me.RowData(section, row).Tag

Dim v As New ArticleView
v.SetContent(content)
PushTo(v)</pre>
<p>The final code is the SetContent method on ArticleView (called by the code above) that takes the content and prepares it to display in the ArticleViewer. Select ArticleView and create a new method by clicking the &#8220;+&#8221; button on the command bar and choosing Method. Set these properties in the Inspector for the method:</p>
<ul>
<li>Method Name: SetContent</li>
<li>Parameters: content As Text</li>
</ul>
<p>This is the code to put in the method:</p>
<pre>// Save content to a file
Dim articleFile As FolderItem = SpecialFolder.Documents.Child("article.html")
Dim output As TextOutputStream
output = TextOutputStream.Create(articleFile, TextEncoding.UTF16)
output.Write(content)
output.Close

// Display the file
ArticleViewer.LoadURL(articleFile.URLPath)</pre>
<p>Since the HTMLViewer can only display content from a URL, the code first saves the content to a file in the app&#8217;s private Documents folder and then tells the ArticleView to load the file using its URLPath.</p>
<h2>Testing</h2>
<p>You can run the project to test it out. If you don&#8217;t already have it, you&#8217;ll need to first install Xcode so that you have the iOS Simulator. With Xcode installed you can click the Run button on the Xojo toolbar which builds your iOS app and launches it in the iOS Simulator.</p>
<p>Click the Load button to load the feed&#8230;wait. It didn&#8217;t show anything did it?</p>
<p>It turns out that the Daring Fireball site <a href="https://twitter.com/gruber/status/867194244276129792">does not yet have TLSv1.2 enabled</a>, which iOS requires by default to access web sites. I checked with <a href="https://twitter.com/gruber/status/867194443396501505">John Gruber and he said he&#8217;s been planning a server upgrade</a>, but until he does so we have to tell iOS to accept a lower level of security for this web site.</p>
<p>Anyway, quit the iOS Simulator for now.</p>
<p>To change security settings, create a text file (using your favorite text editor) and name it Info.plist. This is the contents of the plist file:</p>
<pre>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
&lt;plist version="1.0"&gt;
&lt;dict&gt;
  &lt;key&gt;NSAppTransportSecurity&lt;/key&gt;
  &lt;dict&gt;
    &lt;key&gt;NSExceptionDomains&lt;/key&gt;
    &lt;dict&gt;
      &lt;key&gt;daringfireball.net&lt;/key&gt;
      &lt;dict&gt;
        &lt;key&gt;NSIncludesSubdomains&lt;/key&gt;
        &lt;true/&gt;
        &lt;key&gt;NSTemporaryExceptionAllowsInsecureHTTPLoads&lt;/key&gt;
        &lt;true/&gt;
        &lt;key&gt;NSTemporaryExceptionMinimumTLSVersion&lt;/key&gt;
        &lt;string&gt;TLSv1.0&lt;/string&gt;
        &lt;key&gt;NSTemporaryExceptionRequiresForwardSecrecy&lt;/key&gt;
        &lt;false/&gt;
      &lt;/dict&gt;
    &lt;/dict&gt;
  &lt;/dict&gt;
&lt;/dict&gt;
&lt;/plist&gt;</pre>
<p>Now drag the text file to your Xojo JSONFeed project so that it can be incorporated into the app when it gets built.</p>
<p>You can now Run the JSONFeed project again. This time when you click the Load button you&#8217;ll see a list of the current Daring Fireball articles. Tap on one of the posts and a new view with the content appears. Tap the Back button to go back to the list of articles.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-2877" src="https://blog.xojo.com/wp-content/uploads/2017/05/2017-05-24_15-33-25.png" alt="" width="320" height="568" /><img loading="lazy" decoding="async" class="alignnone size-full wp-image-2878" src="https://blog.xojo.com/wp-content/uploads/2017/05/2017-05-24_15-34-32.png" alt="" width="320" height="568" /></p>
<p>Related posts: <a href="https://blog.xojo.com/2017/05/30/json-feed-web-app/">JSON Feed Web App</a> and <a href="https://blog.xojo.com/2017/06/01/json-feed-desktop-app/">JSON Feed Desktop App</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>JSON Feed Web App</title>
		<link>https://blog.xojo.com/2017/05/30/json-feed-web-app/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Tue, 30 May 2017 15:43:01 +0000</pubDate>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[webdev]]></category>
		<guid isPermaLink="false">http://blog.xojo.com/?p=2846</guid>

					<description><![CDATA[In fact, it is so simple that you can easily make web, desktop and iOS apps with Xojo to display the feed. In this post, I'll show you how to create a Xojo web app to display the JSON feed for Daring Fireball in less than 20 lines of code.]]></description>
										<content:encoded><![CDATA[<p>Recently, a new syndication format was introduced by Brent Simmons and Manton Reece called <a href="https://jsonfeed.org/">JSON Feed</a>. It is an alternative to RSS/Atom to get feeds for blog posts and podcasts. RSS/Atom are XML-based, making them complex to work with. As its name implies, JSON Feed uses JSON and is much simpler.</p>
<p>In fact, it is so simple that you can easily make web, desktop and iOS apps with Xojo to display the feed. In this post, I&#8217;ll show you how to create a Xojo web app to display the JSON feed for <a href="https://daringfireball.net">Daring Fireball</a> in less than 20 lines of code.</p>
<p><span id="more-2846"></span></p>
<h2>Designing the User Interface</h2>
<p>To start, <a href="http://www.xojo.com/download/">download Xojo for free</a>, install and launch it. At the <a href="http://developer.xojo.com/userguide/fundamentals">Project Chooser</a>, select &#8220;Web&#8221;, enter &#8220;JSONFeed&#8221; as the Application Name and click OK.</p>
<p>You are now looking at the <a href="http://developer.xojo.com/userguide/layout-editor">Layout Editor</a>. You can drag controls from the <a href="http://developer.xojo.com/userguide/library-inspector">Library</a> on the right to create your user interface. For this example, you&#8217;ll want 6 controls: 2 Labels, a TextField, a Button, a ListBox and an HTMLViewer. Drag them onto the web page layout as shown below:</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-2855" src="https://blog.xojo.com/wp-content/uploads/2017/05/2017-05-23_14-07-08.png" alt="" width="1233" height="801" /></p>
<p>Now click the <a href="http://developer.xojo.com/userguide/library-inspector">Inspector</a> button on the toolbar to see the Inspector which shows the properties. You are going to want to change some properties for a few of the controls. Click on a control to see its properties in the Inspector.</p>
<ol>
<li>Change the text property for the Label next to the TextField to be &#8220;Feed URL:&#8221;.</li>
<li>For the TextField, change its name to &#8220;URLField&#8221; and set its Text to the URL for the Daring Fireball JSON Feed: &#8220;https://daringfireball.net/feeds/json&#8221;. You&#8217;ll also want to click the right-most lock in the Locking section to allow this field to grow in size to fit the web page (Left, Top and Right should all be &#8220;locked&#8221;).</li>
<li>Click the button and change its Caption to &#8220;Load&#8221;. In the Locking section, make sure that only Top and Right are locked.</li>
<li>Select the Label below the TextField and change its name to &#8220;FeedTitleLabel&#8221;.</li>
<li>Click the ListBox and change its name to &#8220;FeedList&#8221;. Also change the ColumnCount to 2 and ColumnWidths to 75%. Also set the locking so that Left, Top and Right are locked.
<ol>
<li>To set the headers for the ListBox, hover the mouse over the ListBox and lick the &#8220;pencil&#8221; icon that appears. Double click on the header to edit the text and click the close icon when you are finished.</li>
</ol>
</li>
<li>Now select the HTMLViewer and change its Name to &#8220;ArticleViewer&#8221; and set the locking so that Left, Top, Right and Bottom are locked.</li>
<li>Lastly, you want to add a non-UI control to the web page. This control is what will connect and download the JSON Feed. Click on Library in the toolbar and scroll down to find the control called &#8220;Generic Object&#8221;. Drag that on to the web page layout where it will appear at the Shelf on the bottom. Switch to the Inspector and change the control Name to &#8220;FeedSocket&#8221; and the Super to &#8220;Xojo.Net.HTTPSocket&#8221;.</li>
</ol>
<p>That&#8217;s it for the UI. You can click the Run button on the toolbar to start this web app so you can see what it looks like in your browser. It won&#8217;t do anything yet, but you can make sure all the controls are positioned properly.</p>
<h2>Adding Code</h2>
<p>Now it&#8217;s time to add the code. Start by double-clicking on the button the web page layout. This displays the Event Handler window. Click on Action and select OK. You are now looking at a blank <a href="http://developer.xojo.com/userguide/code-editor">Code Editor</a>. The code you put here runs when the button is clicked. Your code needs to tell the FeedSocket to get the JSON feed for the URL entered in the TextField. This is the code to do that:</p>
<pre>FeedSocket.Send("GET", URLField.Text.ToText)</pre>
<p>Now you need to put code in FeedSocket to parse the JSON Feed that gets returned. Double-click FeedSocket to display the Event Handler window, select PageReceived and click OK. The code below <a href="http://developer.xojo.com/xojo-core-textencoding$ConvertDataToText">converts the JSON from binary data to Text</a>, then <a href="http://developer.xojo.com/xojo-data$ParseJSON">parses the JSON in the Text to get a Dictionary</a>. From the <a href="http://developer.xojo.com/xojo-core-dictionary">Dictionary</a> you can get the array of articles in the JSON (called items), loop through them and add them to the list.</p>
<pre>If HTTPStatus = 200 Then
  Dim jsonText As Text = Xojo.Core.TextEncoding.UTF8.ConvertDataToText(Content)
  Dim jsonDict As Xojo.Core.Dictionary = Xojo.Data.ParseJSON(jsonText)
 
  FeedList.DeleteAllRows
 
  // Display the feed title
  FeedTitleLabel.Text = jsonDict.Value("title")
 
  // Display the feed articles
  Dim items() As Auto = jsonDict.Value("items")
  For Each article As Xojo.Core.Dictionary In items
    Dim title As Text = article.Value("title")
    Dim pubDate As Text = article.Value("date_published")
    FeedList.AddRow(title, pubDate)
 
    // Save article content
    FeedList.RowTag(FeedList.LastIndex) = article.Value("content_html")
  Next
End If</pre>
<p>The last bit of code you need displays the content for the selected article. Double-click the FeedList control and in the Event Handler window choose SelectionChanged and press OK. This is the event that is called when you click on a row in the list. In the Code Editor add this code to get the article content (that was previously saved in the RowTag) and load it into the ArticleViewer to display:</p>
<pre>Dim content As Text = Me.RowTag(Me.ListIndex)
ArticleViewer.LoadPage(content)</pre>
<p>You can now run the project to see it in action. Once the page displays, click the Load button to load the Daring Fireball JSON Feed. Click on an article to view it. Here it is running in Safari:</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-2851" src="https://blog.xojo.com/wp-content/uploads/2017/05/2017-05-23_11-48-47.png" alt="" width="989" height="666" /></p>
<p>With a <a href="https://www.xojo.com/store">Xojo license</a> you can deploy this web app to your own server for others to use. Or you can use <a href="http://www.xojo.com/cloud/">Xojo Cloud</a> for easy one-click deployment right from the Xojo IDE. Here is this app running on Xojo Cloud:</p>
<p><a href="http://demos.xojo.com/JSONFeed-Dev">JSON Feed Example App</a></p>
<p>With a little more work on your part, you can turn this into a full-featured JSON Feed viewer. For example, you can let users add multiple feeds and check them periodically for new posts.</p>
<p>Related posts: <a href="https://blog.xojo.com/2017/05/31/json-feed-ios-app/">JSON Feed iOS App</a> and <a href="https://blog.xojo.com/2017/06/01/json-feed-desktop-app/">JSON Feed Desktop App</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Sending Notifications with Pushover</title>
		<link>https://blog.xojo.com/2017/03/06/sending-notifications-with-pushover/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Mon, 06 Mar 2017 14:57:59 +0000</pubDate>
				<category><![CDATA[Desktop]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[webdev]]></category>
		<guid isPermaLink="false">http://blog.xojo.com/?p=2427</guid>

					<description><![CDATA[Want a quick and easy way to send notifications to your devices (iOS, Android and web browsers) from Xojo desktop and web apps? Perhaps you want&#8230;]]></description>
										<content:encoded><![CDATA[<p>Want a quick and easy way to send notifications to your devices (iOS, Android and web browsers) from Xojo desktop and web apps? Perhaps you want to send a notification if a purchase is made, an error occurs or a long process has finished. If so, the free <a href="https://pushover.net">Pushover web service</a> might be what you need!</p>
<p><span id="more-2427"></span></p>
<p>Pushover is actually two things: a web service you can call to send notifications and an app you install on your device to receive notifications. Using it is really easy, but I&#8217;ve made a class you can use to make it even easier: just drag it onto your layout to use.</p>
<p>Here&#8217;s how to set things up:</p>
<ol>
<li>Go to www.pushover.net and create a free account.</li>
<li>Make a note of your User Key.</li>
<li>Go to your Pushover account page and create an Application. This creates an App Token. Make a note of it.</li>
<li>Install a Pushover device client on your mobile device. This works with <a href="https://pushover.net/clients">iOS, Android and web browsers</a>. You can use them in trial mode for 7 days, after which each is a one-time $5 purchase.</li>
<li>Grab the <a href="https://github.com/xojo/pushover">Xojo Pushover project from Github</a>.</li>
</ol>
<p>In the project, go to the Pushover module and change the <strong>kUserKey</strong> constant to be your User Key. Change the <strong>kAppToken</strong> to your App Token.</p>
<p>Now you can run the Xojo Pushover project. Enter some text in the text area and press the Send button. The notification should appear on your mobile device. Here you can see the notification as it appears on my iPhone:</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-2429" src="https://blog.xojo.com/wp-content/uploads/2017/03/Notification.png" alt="" width="360" height="640" /></p>
<p>I swiped on the notification and it opened in the Pushover app where you can see additional information including the URL that you can tap to open:</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-2430" src="https://blog.xojo.com/wp-content/uploads/2017/03/PushoverApp.png" alt="" width="360" height="222" /></p>
<p>To use this in your own projects, just add the Pushover module and then drag the Communicator class onto your layout. Call its SendNotification method to send a notification. Any errors are returned in the PageReceived event as JSON.</p>
<p>Like I said, it is super-easy and the <a href="https://github.com/xojo/pushover">code is available on Github</a>. Thanks to <a href="https://www.caseyliss.com/2017/2/25/push-it-real-good">Casey Liss for pointing out the Pushover service</a> to me. Enjoy your notifications!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Making An iOS App For The Daily WTF API</title>
		<link>https://blog.xojo.com/2016/01/20/making-an-ios-app-for-the-daily-wtf-api/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Wed, 20 Jan 2016 00:00:00 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Cats]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[PAW]]></category>
		<category><![CDATA[REST]]></category>
		<guid isPermaLink="false">http://blogtemp.xojo.com/2016/01/20/making-an-ios-app-for-the-daily-wtf-api/</guid>

					<description><![CDATA[Use web services to display articles from The Daily WTF technology snafu web site.]]></description>
										<content:encoded><![CDATA[<p>If you work in the technologiy industry, I&#8217;m sure you&#8217;ve heard of the <a href="http://thedailywtf.com">Daily WTF</a> site. Their fun stories about technology gone wrong makes it one of my favorite web sites.</p>
<p><span id="more-233"></span></p>
<p>Recently they just <a href="http://thedailywtf.com/articles/tdwtf-api">announced a web services API</a> for accessing their articles and other information. And as I&#8217;ve talked about <a href="../../../com/xojo/blog/test-web-services-with-rest-tester.html" target="_blank" rel="noopener">in</a> <a href="../../../com/xojo/blog/format-sql.html" target="_blank" rel="noopener">other</a> <a href="../../../com/xojo/blog/how-to-write-a-slackbot-in-less-than-20-lines-of-code.html" target="_blank" rel="noopener">posts</a> and <a href="https://www.youtube.com/playlist?list=PLPoq910Q9jXiH5A32myqHwd1WLuUnBTuO" target="_blank" rel="noopener">webinars</a>, it&#8217;s often quite easy to use web services with Xojo apps.</p>
<p>I&#8217;ll show you how you can quickly create an iOS app that shows the most recent TDWTF posts and then displays them when you tap on their title.</p>
<p>To start, create a Xojo iOS project.</p>
<p>On the default View (View1), use the Inspector to set a couple properties:</p>
<ul>
<li>BackButtonTitle: Articles</li>
<li>Title: The Daily WTF</li>
</ul>
<p>Now drag a <a href="http://developer.xojo.com/iostable">Table</a> from the Library onto the View and stretch it to fit the entire layout area. Name the table <strong>ArticleTable</strong>. This Table will be used to display the list of recent articles.</p>
<p>To get the articles, you just have to make the appropriate API call. Looking at the <a href="https://github.com/tdwtf/WtfWebApp/blob/master/Docs/API.md">API docs</a>, there is an API command called /articles/recent which returns a JSON document of the recent articles and related information. This is the actual API call. To see its JSON results, use a tool like <a href="https://luckymarmot.com/paw">Paw</a> (now with <a href="../../../com/xojo/blog/generating-xojo-code-from-paw.html">Xojo extensions</a>) or <a href="../../../com/xojo/blog/test-web-services-with-rest-tester.html">RESTy</a> with this URL (a browser will also show the unformatted JSON):</p>
<p><a href="http://thedailywtf.com/api/articles/recent">http://thedailywtf.com/api/articles/recent</a></p>
<p>If you look at the JSON results, you&#8217;ll see that it returns an array of articles with a &#8220;Title&#8221; entry containing the title of the article and a &#8220;Url&#8221; entry containing the URL of the article.</p>
<p>To call this in the Xojo app, I&#8217;ll use an <a href="http://developer.xojo.com/xojo-net-httpsocket">HTTPSocket</a>. In the Library, drag the item called &#8220;Generic Object&#8221; onto the Layout. It will appear in the Shelf at the bottom. In its Inspector, change the name to <strong>WTFSocket</strong> and set its super to &#8220;Xojo.Net.HTTPSocket&#8221;.</p>
<p>Now add an event handler to the socket, right-&gt;click on the socket, select &#8220;Add To&#8221; and then &#8220;Event Handler&#8221;. Add the PageReceived event handler. In it, put this code to request the articles:</p>
<pre>// Convert the binary Content data to JSON text and then
// parse it to an array.
Dim jsonText As Text = TextEncoding.UTF8.ConvertDataToText(Content)
Dim jsonArray() As Auto = Data.ParseJSON(jsonText)

// Loop through the array and add each article to
// the table.
ArticleTable.AddSection("")
For i As Integer = 0 To jsonArray.Ubound
  Dim article As Dictionary = jsonArray(i)

  Dim cell As iOSTableCellData = ArticleTable.CreateCell
  cell.Text = article.Value("Title")
  cell.Tag = article.Value("Url")

  Dim author As Dictionary = article.Value("Author")
  cell.DetailText = article.Value("DisplayDate") + " by " + author.Value("Name")
  ArticleTable.AddRow(0, cell)
Next</pre>
<p>The URL is being put into the Tag for the cell so that it can be used later to display the article when its row is tapped.</p>
<p>You&#8217;ll also see I&#8217;m also accessing the &#8220;DisplayDate&#8221; value and grabbing the &#8220;Name&#8221; from the &#8220;Author&#8221; object in the JSON.</p>
<p>Now you&#8217;ll want to call the web service. Add the Open event handler to the View with this code:</p>
<pre>// Call the /articles/recent web service
WTFSocket.Send("GET", "http://thedailywtf.com/api/articles/recent")</pre>
<p>Run the project and you&#8217;ll see the list of recent article appear:</p>
<p><img loading="lazy" decoding="async" class="aligncenter" title="WTFArticleList.png" src="https://blog.xojo.com/wp-content/uploads/2016/01/WTFArticleList.pngt1466486449161ampwidth480ampheight742" sizes="auto, (max-width: 480px) 100vw, 480px" alt="WTFArticleList.png" width="480" height="742" /></p>
<p>The final step is to display the article when it is tapped in the list. You&#8217;ll want another View to display the article (Insert-&gt;View). Name the view <strong>ArticleView</strong>. On this View, set the NavigationBarVisible property to ON and drag an HTML Viewer onto it. Make the HTML Viewer fill the entire View layout and name it <strong>ArticleViewer</strong>.</p>
<p>Add a method to ArticleView called <strong>ShowArticle(url As Text)</strong> with this code:</p>
<pre>ArticleViewer.LoadURL(url)</pre>
<p>This method loads the URL into the HTML Viewer and is called when its row is tapped in the list of articles.</p>
<p>Speaking of which, back on View1 add the Action event handler to the table with this code:</p>
<pre>// Get the URL from the tag for the tapped row
Dim url As Text = Me.RowData(section, row).Tag

// Display the article on the new view and show it
Dim v As New ArticleView
v.ShowArticle(url)
PushTo(v)</pre>
<p>Now run the project. You&#8217;ll see the list of article as before. Tap on an article to show the new view with the article.</p>
<p><img loading="lazy" decoding="async" class="aligncenter" title="WTFArticle.png" src="https://blog.xojo.com/wp-content/uploads/2016/01/WTFArticle.pngt1466486449161ampwidth480ampheight742" sizes="auto, (max-width: 480px) 100vw, 480px" alt="WTFArticle.png" width="480" height="742" /></p>
<p>Take a look at the full API to see what other cool features you can add to the app. Here are some suggestions:</p>
<ul>
<li>Display a random article</li>
<li>Display more than the last 8 recent articles</li>
<li>Cache the article contents on the device and use the cache when the article is displayed again</li>
<li>Display articles by month/year</li>
</ul>
<p><!--HubSpot Call-to-Action Code --> <span id="hs-cta-wrapper-7bcc3f87-4442-4a30-90b2-c9264729660a" class="hs-cta-wrapper"> <span id="hs-cta-7bcc3f87-4442-4a30-90b2-c9264729660a" class="hs-cta-node hs-cta-7bcc3f87-4442-4a30-90b2-c9264729660a"><br />
<!-- [if lte IE 8]>


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


<![endif]--> <a href="http://blog.xojo.com/2015/10/01/cats-up-using-httpsocket-with-the-cat-rest-api/" target="_blank" rel="noopener"><img loading="lazy" decoding="async" id="hs-cta-img-7bcc3f87-4442-4a30-90b2-c9264729660a" class="hs-cta-img aligncenter" style="border-width: 0px; margin: 0 auto; display: block; margin-top: 20px; margin-bottom: 20px;" src="https://blog.xojo.com/wp-content/uploads/2016/01/7bcc3f87-4442-4a30-90b2-c9264729660a.png" alt="Use HTTPSocket with Cat REST API" width="432" height="73" align="middle" /></a></span></span> <!-- end HubSpot Call-to-Action Code --></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>My Favorite New Xojo Framework Features</title>
		<link>https://blog.xojo.com/2015/08/26/my-favorite-new-xojo-framework-features/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Wed, 26 Aug 2015 00:00:00 +0000</pubDate>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Xojo Framework]]></category>
		<guid isPermaLink="false">http://blogtemp.xojo.com/2015/08/26/my-favorite-new-xojo-framework-features/</guid>

					<description><![CDATA[Here are some of my favorite features of the Xojo framework.]]></description>
										<content:encoded><![CDATA[<p>The first classes in the new Xojo Framework have been available for all project types since Xojo 2015 Release 2. Here are some of my favorite features.<br>
<span id="more-304"></span></p>
<h2>Text</h2>
<p>The new Text data type is a substitute for String and has the benefit of making encodings easier to work with. Essentially if you use Text, you don&#8217;t have to worry about the encoding. When you get data from an outside source (a file, a database or even a String), you specify the encoding so it can be stored as Text. Once it is in Text, you don&#8217;t worry about the encoding. When you need to send the Text to a file, DB or elsewhere, you convert it to data using whatever encoding is appropriate- usually UTF8.</p>
<p>You can easily use Text with your existing projects as a Text value converts back to a String automatically. For example, you can set a button Caption using a Text variable:</p>
<pre>Dim t As Text = "Hello"
MyButton.Caption = t // converts automatically to String</pre>
<p>If you have a String (such as a property of a UI control) you can easily convert it to Text by calling&nbsp;the ToText method. For example, you store the Caption of a button as Text:</p>
<pre>Dim t As Text = MyButton.Caption.ToText</pre>
<h2>Dictionary</h2>
<p>I prefer <a href="http://developer.xojo.com/xojo-core-dictionary">Xojo.Core.Dictionary</a> because it is has an easy-to-use iterator, making it crazy-simply to loop through the items in&nbsp;the Dictionary:</p>
<pre>Dim myDictionary As New Xojo.Core.Dictionary
myDictionary.Value("Name") = "Bob Roberts"
myDictionary.Value("City") = "Boston"
For Each entry As Xojo.Core.DictionaryEntry In myDictionary
  Dim key As Text = entry.Key
  Dim value As Text = entry.Value
Next</pre>
<p>Xojo.Core.Dictionary can also be case-sensitive which is not even an option&nbsp;with the classic Dicitonary class! You just have to subclass (or use AddHandler) and implement the CompareKeys event handler:</p>
<pre>Dim leftText As Text = lhs
Dim rightText As Text = rhs
Return leftText.Compare(rightText, Text.CompareCaseSensitive)</pre>
<h2>JSON</h2>
<p>In the new framework, <a href="/2015/04/16/newframeworkjson/">JSON is handled by two methods</a> (<a href="http://developer.xojo.com/xojo-data$ParseJSON">Xojo.Data.ParseJSON</a> and <a href="http://developer.xojo.com/xojo-data$GenerateJSON">Xojo.Data.GenerateJSON</a>), typically with Xojo.Core.Dictionary. Creating JSON text from a Dictionary is one line of code:</p>
<pre>Dim jsonText As Text = Xojo.Data.GenerateJSON(myDictionary)</pre>
<p>And converting JSON text to a Dictionary is also one line of code:</p>
<pre>Dim jsonDict As Xojo.Core.Dictionary = Xojo.Data.ParseJSON(jsonText)</pre>
<p>Both of these methods are much faster than using JSONItem in the classic framework.</p>
<h2>HTTPSocket</h2>
<p><a href="http://developer.xojo.com/xojo-net-httpsocket">Xojo.Net.HTTPSocket</a> uses HTTP 1.1. This is a big advantage over the classic HTTPSocket which only supports HTTP 1.0 making it not always compatible with some sites.</p>
<p>I recently did a <a href="http://developer.xojo.com/webinar-httpsocket">webinar that shows how to use HTTPSocket with a variety of web services</a>.</p>
<h2>TextInputStream/TextOutputStream</h2>
<p>Lastly, I often work with Text files which means I have to deal with encodings. The <a href="http://developer.xojo.com/xojo-io-textinputstream">TextInputStream</a> and <a href="http://developer.xojo.com/xojo-io-textoutputstream">TextOutputStream</a> make it easy to deal with encodings because the encoding is part of the method calls.</p>
<p>You can even use these classes with classic FolderItems by first converting them to Xojo.IO.FolderItem. For example, this prompts the user for a file and then opens it using a TextInputStream:</p>
<pre>Dim f As FolderItem = GetOpenFolderItem("")
If f &lt;&gt; Nil Then
  Dim openFile As New Xojo.IO.FolderItem(f.NativePath.ToText)
  Dim input As Xojo.IO.TextInputStream
  input = Xojo.IO.TextInputStream.Open(openFile, Xojo.Core.TextEncoding.UTF8)
End If</pre>
<p>If you have not already, try these new Xojo Framework classes in your projects. You&#8217;ll appreciate it!</p>
<p><!-- end HubSpot Call-to-Action Code --></p>


<p>Update (June 2020):</p>



<p>Since this was posted, there have been many updates to Xojo. In particular you should check out these equivalent API 2.0 features:</p>



<ul class="wp-block-list"><li><a href="https://documentation.xojo.com/api/language/dictionary.html">Dictionary</a> now also has an iterator.</li><li><a href="https://documentation.xojo.com/api/text/json/generatejson.html">GenerateJSON</a> and <a href="https://documentation.xojo.com/api/text/json/parsejson.html">ParseJSON</a>.</li><li><a href="https://documentation.xojo.com/api/networking/urlconnection.html">URLConnection</a></li></ul>



<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Format JSON</title>
		<link>https://blog.xojo.com/2015/08/14/format-json/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Fri, 14 Aug 2015 00:00:00 +0000</pubDate>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[JSON]]></category>
		<guid isPermaLink="false">http://blogtemp.xojo.com/2015/08/14/format-json/</guid>

					<description><![CDATA[I've been working with JSON in the new Xojo framework quite a bit lately and wanted the ability to format the JSON text so it is more readable.]]></description>
										<content:encoded><![CDATA[<p>I&#8217;ve been working with <a href="https://en.wikipedia.org/wiki/JSON" target="_blank" rel="noopener">JSON</a> in the new Xojo framework quite a bit lately and wanted the ability to format the JSON text so it is more readable.</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-1709" src="https://blog.xojo.com/wp-content/uploads/2015/08/JSON.png" alt="JSON" width="501" height="222" /></p>
<p>A little Internet research turned up a <a href="http://www.limilabs.com/blog/json-net-formatter">set of classes for .NET (in C#) that can do this</a>. I took a few minutes to port these three classes over to a single Xojo class that can format JSON for you.</p>
<p><span id="more-272"></span></p>
<ul>
<li><a href="http://files.xojo.com/BlogExamples/FormatJSON.xojo_binary_project.zip">Download JSONFormatter</a></li>
</ul>
<p>To use the class, add it to your project and then add code like this:</p>
<pre>Dim formatter As New JSONFormatter(json)
Dim formattedJSON As Text = formatter.Format</pre>
<p>Here is an example of unformatted JSON:</p>
<pre>{"Crows":{"players":{"Ben":{"position":"1B"},"Ty":{"position":"2B"}}},"Pigeons":{"players":{"Bill":{"position":"1B"},"Tim":{"position":"2B"}}},"Seagulls":{"players":{"Bob":{"position":"1B"},"Tom":{"position":"2B"}}}}</pre>
<p>And what it looks like after being formatted by JSONFormatter:</p>
<pre>{
    "Crows":
    {
        "players":
        {
            "Ben":
            {
                "position":"1B"
            },
            "Ty":
            {
                "position":"2B"
            }
        }
    },
    "Pigeons":
    {
        "players":
        {
            "Bill":
            {
                "position":"1B"
            },
            "Tim":
            {
                "position":"2B"
            }
        }
    },
    "Seagulls":
    {
        "players":
        {
            "Bob":
            {
                "position":"1B"
            },
            "Tom":
            { 
                "position":"2B"
            }
        }
    }
}
</pre>
<p>I hope you find this useful. Want to learn more about using JSON with Xojo? Watch our on-demand JSON webinar, learn to use JSON with Xojo along with slides and a sample project.</p>
<p style="text-align: center;"><!--HubSpot Call-to-Action Code --> <span id="hs-cta-wrapper-4d3c143a-87c8-4155-9c51-dca01de31cbf" class="hs-cta-wrapper"> <span id="hs-cta-4d3c143a-87c8-4155-9c51-dca01de31cbf" class="hs-cta-node hs-cta-4d3c143a-87c8-4155-9c51-dca01de31cbf"><br />
<!-- [if lte IE 8]></p>





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


<![endif]--> <a href="http://developer.xojo.com/webinar-json" target="_blank" rel="noopener"><img loading="lazy" decoding="async" id="hs-cta-img-4d3c143a-87c8-4155-9c51-dca01de31cbf" class="hs-cta-img aligncenter" style="border-width: 0px;" src="https://blog.xojo.com/wp-content/uploads/2015/04/4d3c143a-87c8-4155-9c51-dca01de31cbf.png" alt="Watch Video" width="641" height="107" /></a> </span><script src="https://js.hscta.net/cta/current.js" charset="utf-8">// <![CDATA[
<script type="text/javascript"><![CDATA[ hbspt.cta.load(608515, '4d3c143a-87c8-4155-9c51-dca01de31cbf', {}); // ]]&gt;</script></span><br />
<!-- end HubSpot Call-to-Action Code --></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>XojoTalk 015: Type my password like an animal</title>
		<link>https://blog.xojo.com/2015/07/01/xojotalk-015-type-my-password-like-an-animal/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Wed, 01 Jul 2015 00:00:00 +0000</pubDate>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[XojoTalk]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Games]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Open-Source]]></category>
		<guid isPermaLink="false">http://blogtemp.xojo.com/2015/07/01/xojotalk-015-type-my-password-like-an-animal/</guid>

					<description><![CDATA[XojoTalk 015: Type my password like an animal]]></description>
										<content:encoded><![CDATA[<p>In this episode of XojoTalk, Paul talks with <a href="https://twitter.com/justindelliott">Justin Elliott</a>, IT and Development Manager at <a href="http://www.psu.edu">Penn State University</a>.</p>
<p>Download <a href="http://files.xojo.com/Podcasts/XojoTalk-015.mp3">MP3</a>.</p>
<p><span id="more-225"></span></p>
<p>Show Links</p>
<ul>
<li><a href="http://www.psu.edu">Penn State University</a></li>
<li><a href="http://clc.its.psu.edu/UnivServices/itadmins/mac/blastimageconfig">Blast Image Config</a></li>
<li><a href="http://macadmins.psu.edu">MacAdmins Conference</a></li>
<li><a href="http://developer.xojo.com/xojo-data">Xojo JSON support</a></li>
<li><a href="https://sched.org">Sched.org</a></li>
<li><a href="http://developer.xojo.com/community-open-source-projects">Open-Source Xojo Projects</a></li>
<li><a href="http://www.xojo.com/resources/cloudservices.php">5 Reasons to rely on Cloud services</a></li>
<li><a href="http://developer.xojo.com/webinar-retro-gaming">Git webinars</a></li>
<li><a href="https://github.com/xojo/XojoUnit">XojoUnit</a></li>
<li><a href="https://system76.com">System 76 Linux laptops</a></li>
<li><a href="http://elementary.io">ElementaryOS</a></li>
<li><a href="http://jakobud.com/plan-list.php">JackObud arcade cabinets</a></li>
<li><a href="http://developer.xojo.com/webinar-retro-gaming">Retro game webinar</a></li>
<li><a href="https://itunes.apple.com/us/app/pixel-space-war/id983974668?mt=8">Pixel Space Wars</a></li>
</ul>
<p><!--HubSpot Call-to-Action Code --> <span id="hs-cta-wrapper-32eb9715-5c1c-45a4-9f37-717ffc906d8e" class="hs-cta-wrapper"> <span id="hs-cta-32eb9715-5c1c-45a4-9f37-717ffc906d8e" class="hs-cta-node hs-cta-32eb9715-5c1c-45a4-9f37-717ffc906d8e"><br />
<!-- [if lte IE 8]>


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


<![endif]--> <a href="http://feeds.feedburner.com/xojotalk" target="_blank"><img loading="lazy" decoding="async" id="hs-cta-img-32eb9715-5c1c-45a4-9f37-717ffc906d8e" class="hs-cta-img alignnone" style="border-width: 0px; margin: 0 auto; display: block; margin-top: 20px; margin-bottom: 20px;" src="https://blog.xojo.com/wp-content/uploads/2014/09/32eb9715-5c1c-45a4-9f37-717ffc906d8e.png" alt="Subscribe Podcast" width="622" height="107" align="middle" /></a> </span><script src="https://js.hscta.net/cta/current.js" charset="utf-8">// <![CDATA[
<script type="text/javascript"><![CDATA[ hbspt.cta.load(608515, '32eb9715-5c1c-45a4-9f37-717ffc906d8e', {}); // ]]&gt;</script></span><br />
<!-- end HubSpot Call-to-Action Code --></p>
<p>You can also <a href="https://itunes.apple.com/us/podcast/xojotalk-podcast/id920411434" target="_blank">subscribe on iTunes</a>.</p>
]]></content:encoded>
					
		
		<enclosure url="http://files.xojo.com/Podcasts/XojoTalk-015.mp3" length="31009982" type="audio/mpeg" />

			</item>
		<item>
		<title>Xojo Framework: Working with JSON</title>
		<link>https://blog.xojo.com/2015/04/16/xojo-framework-working-with-json/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Thu, 16 Apr 2015 00:00:00 +0000</pubDate>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Xojo Framework]]></category>
		<guid isPermaLink="false">http://blogtemp.xojo.com/2015/04/16/xojo-framework-working-with-json/</guid>

					<description><![CDATA[Much of the new Xojo framework is available for all project types staring with Xojo 2015r2. The Data namespace includes two methods for dealing with JSON data: GenerateJSON and ParseJSON. This is how they are used in comparison to JSONItem in the old "Classic" framework.]]></description>
										<content:encoded><![CDATA[<p>Much of the new Xojo framework is available for all project types staring with Xojo 2015r2. The Data namespace includes two methods for dealing with JSON data: <a href="http://developer.xojo.com/xojo-data$GenerateJSON">GenerateJSON</a> and <a href="http://developer.xojo.com/xojo-data$ParseJSON">ParseJSON</a>. This is how they are used in comparison to JSONItem in the old &#8220;Classic&#8221; framework.</p>
<p><span id="more-204"></span></p>
<p>In the Classic framework the JSONItem class is used to create, load and output JSON data. With the new &#8220;Xojo&#8221; framework, you simply use a Dictionary, which you can easily populate from JSON data or output to JSON data.</p>
<p>For example, here is some JSON data to use as an example:</p>
<pre>{ "Seagulls":
  { "players":
    { "Bob":{ "position":"1B" },
      "Tom":{ "position":"2B" } }
},
  "Pigeons":
  { "players":
    { "Bill":{ "position":"1B" },
      "Tim":{ "position":"2B" } }
},
  "Crows":
  { "players":
    { "Ben":{ "position":"1B" },
      "Ty":{ "position":"2B" } } }
}</pre>
<p>With the above JSON data pasted into a TextArea, you can load it with just a single line of code:</p>
<pre>Dim league As Dictionary = Xojo.Data.ParseJSON(JSONArea.Text.ToText)</pre>
<p>This is similar to the classic framework, which would look like this:</p>
<pre>Dim league As New JSONItem(JSONArea.Text)</pre>
<p>Looping through the JSON data is also similar. In the Xojo framework, you just iterate through the Dictionary with each JSON section as its own Dictionary:</p>
<pre>Dim teamName, playerName As TextDim team, players, player As Dictionary

For Each t As DictionaryEntry In league
  teamName = t.Key
  team = t.Value
  OutputArea.AppendText(teamName)
  OutputArea.AppendText(EndOfLine)
  players = team.Value("players")
  For Each p As DictionaryEntry In players
    playerName = p.Key
    player = players.Value(playerName)
    OutputArea.AppendText(" " + playerName + " ")
    For Each a As DictionaryEntry In player
      OutputArea.AppendText(a.Value + " ")
    Next
    OutputArea.AppendText(EndOfLine)
  Next
Next</pre>
<p>In the Classic framework, you iterate through the count of items in the JSONItem:</p>
<pre>Dim teamName, playerName As StringDim team, players, player As JSONItem

For i As Integer = 0 To league.Count-1
  teamName = league.Name(i)
  team = league.Value(teamName)
  OutputArea.AppendText(teamName)
  OutputArea.AppendText(EndOfLine)
  players = team.Value("players")
  For p As Integer = 0 To players.Count-1
    playerName = players.Name(p)
    player = players.Value(playerName)
    OutputArea.AppendText(" " + playerName + " ")
    For a As Integer = 0 To player.Count-1
      OutputArea.AppendText(player.Value(player.Name(a)) + " ")
    Next
    OutputArea.AppendText(EndOfLine)
  Next
Next</pre>
<p><span style="line-height: 1.62;">An example project for the above code is <a href="http://files.xojo.com/BlogExamples/JSONTest.xojo_binary_project">here</a>.</span></p>
<p><span style="line-height: 1.62;">To create JSON from a Dictionary, you use the the GenerateJSON method:</span></p>
<pre>Dim d As New Xojo.Core.Dictionary
d.Value("Name") = "Bilbo Baggins"
Dim json As Text = Xojo.Data.GenerateJSON(d)</pre>
<p><span style="line-height: 1.62;">Grab Xojo 2015r2 and start using GenerateJSON and ParseJSON the Xojo framework today!</span></p>
<p>Update (June 2020):</p>
<p>Since this was written, <a href="https://documentation.xojo.com/api/text/json/generatejson.html">GenerateJSON</a> and <a href="https://documentation.xojo.com/api/text/json/parsejson.html">ParseJSON</a> were also added as part of API 2.0.</p>
<p><span style="line-height: 1.62;"><!--HubSpot Call-to-Action Code --> <span id="hs-cta-wrapper-4d3c143a-87c8-4155-9c51-dca01de31cbf" class="hs-cta-wrapper"> <span id="hs-cta-4d3c143a-87c8-4155-9c51-dca01de31cbf" class="hs-cta-node hs-cta-4d3c143a-87c8-4155-9c51-dca01de31cbf"><br />
<!-- [if lte IE 8]>


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


<![endif]--> <a href="http://developer.xojo.com/webinar-json" target="_blank" rel="noopener noreferrer"><img loading="lazy" decoding="async" id="hs-cta-img-4d3c143a-87c8-4155-9c51-dca01de31cbf" class="hs-cta-img aligncenter" style="border-width: 0px;" src="https://blog.xojo.com/wp-content/uploads/2015/04/4d3c143a-87c8-4155-9c51-dca01de31cbf.png" alt="Watch Video" width="641" height="107" /></a></span></span><br />
<!-- end HubSpot Call-to-Action Code --> </span></p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
