Richard Hyde2024-03-17T01:16:09+00:00https://richardhyde.netUpdating GitHubs SSH Key2023-03-28T08:12:11+01:000fc94c2e-524b-4684-b804-e79a5c7284b7<p>Last week <a href="https://github.com">GitHub</a> briefly leaked it’s private RSA ssh host key and <a href="https://github.blog/2023-03-23-we-updated-our-rsa-ssh-host-key/">replaced it with a new one</a>. If you’ve ever cloned a repo from GitHub using the key you’ll get warning that the hosts key has changed and it may have been compromised.</p>
<p>Run the following in a shell to remove the fingerprint of the old key and you’ll be prompted to add fingerprint for the new key next time you access GitHub using ssh.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh-keygen <span class="nt">-R</span> github.com
</code></pre></div></div>
<p>If you want to add the fingerprint of the new public key to your know_hosts file ahead of time you can run the following to fetch it from GitHub (you’ll need the JSON processor [jq[(https://stedolan.github.io/jq/) command line tool installed)</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl <span class="nt">-L</span> https://api.github.com/meta | jq <span class="nt">-r</span> <span class="s1">'.ssh_keys | .[]'</span> | <span class="nb">sed</span> <span class="nt">-e</span> <span class="s1">'s/^/github.com /'</span> <span class="o">>></span> ~/.ssh/known_hosts
</code></pre></div></div>
Vapor SQLite Build Error2022-07-02T11:30:00+01:00415329db-ee73-4d96-91d9-7f5fffd632bb<p>I’ve been playing around with <a href="https://vapor.codes">Vapor</a> for server side swift development. Having installed Swift on a Raspberry Pi and followed the <a href="https://docs.vapor.codes/getting-started/hello-world/">Getting Started</a> guide to install Vapor and great a basic project, with SQLite support, I got the following compile errors running <code class="language-plaintext highlighter-rouge">swift run</code>.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><module-includes>:1:10: note: <span class="k">in </span>file included from <module-includes>:1:
<span class="c">#include "csqlite.h" </span>
^
/home/pi/src/myapi/.build/checkouts/sqlite-nio/Sources/CSQLite/csqlite.h:4:10: error: <span class="s1">'sqlite3.h'</span> file not found
<span class="c">#include <sqlite3.h> </span>
^
/home/pi/src/myapi/.build/checkouts/sqlite-nio/Sources/SQLiteNIO/SQLiteConnection.swift:2:8: error: could not build C module <span class="s1">'CSQLite'</span>
import CSQLite
</code></pre></div></div>
<p>The solution was to install the missing libsqlite3-dev library.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo </span>apt <span class="nb">install </span>libsqlite3-dev
</code></pre></div></div>
Swift on Ubuntu Server 18.04 & 20.04 LTS2020-04-22T17:55:00+01:00C95510FE-FBA9-4D5E-B58D-F86A90347365<p>I setup a <a href="/2020/04/21/ubuntu-18-04-server-vmware-install.html">Ubuntu Server 18.04 LTS</a> VM earlier and this is why. I have some Swift code I want to try running on an Amazon Web Server and needed a playground to get it running.</p>
<p>The <a href="https://swift.org/download/">Swift Download</a> page has a set of instructions on installing Swift on a Ubuntu install so we’ll run through these.</p>
<p><em>Updated 27th April 2020</em>: A few days after writing this post Ubuntu released 20.04 LTS. I’ve gone through these instructions in a Ubuntu Server 20.04 LTS VM, and other than a couple of extra dependancies (see below) the install process is the same.
<!--more--></p>
<h2 id="setup">Setup</h2>
<p>There a couple of things to complete the first time you install Swift on Ubuntu that you don’t need to do each time you update.</p>
<p>Swift has a couple of dependancies which need installing. Depending on your Ubuntu install you may already have these installed but apt-get won’t install anything unless it’s missing so it’s safe to run this even if these packages are already there.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo </span>apt-get <span class="nb">install </span>clang libicu-dev libpython2.7-dev
</code></pre></div></div>
<p>If you’re installing Swift on Ubuntu Server 20.04 LTS there are a couple of extra dependancies required.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo </span>apt-get <span class="nb">install </span>libtinfo5 libncurses5
</code></pre></div></div>
<p>This next step is optional. To ensure that we’re installing what was originally published by Swift.org we need the Swift.org PGP signing keys. This allows us to check the signature of the archive we download against the one Swift.org publishes for the release archive to make sure no-one has tampered with the Swift archive. It’s unlikley if you’re installing from the Swift.org downloads page, but worth running the step as a precaution.</p>
<p>To do this check we need to download and import the Swift PGP signing keys.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>wget <span class="nt">-q</span> <span class="nt">-O</span> - https://swift.org/keys/all-keys.asc | gpg <span class="nt">--import</span> -
</code></pre></div></div>
<h2 id="installing-swift">Installing Swift</h2>
<p>There are a couple of files to download, the Swift release archive (5.2.2 in this case) and the PGP Signature file for checking the archive file.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>wget https://swift.org/builds/swift-5.2.2-release/ubuntu1804/swift-5.2.2-RELEASE/swift-5.2.2-RELEASE-ubuntu18.04.tar.gz
<span class="nv">$ </span>wget https://swift.org/builds/swift-5.2.2-release/ubuntu1804/swift-5.2.2-RELEASE/swift-5.2.2-RELEASE-ubuntu18.04.tar.gz.sig
</code></pre></div></div>
<p>If you want to verify the archive you’ve just downloaded first refresh the Swift PGP keys.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>gpg <span class="nt">--keyserver</span> hkp://pool.sks-keyservers.net <span class="nt">--refresh-keys</span> Swift
</code></pre></div></div>
<p>Then use the signature file to verify the archive.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>gpg <span class="nt">--verify</span> swift-5.2.2-RELEASE-ubuntu18.04.tar.gz.sig
</code></pre></div></div>
<p>If the archive was verified OK then output should contain a “Good Signature” line. If it doesn’t there was an issue with the archive you downloaded. Try downloading it again from another source.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gpg: Good signature from <span class="s2">"Swift 5.x Release Signing Key <swift-infrastructure@swift.org>"</span> <span class="o">[</span>unknown]
</code></pre></div></div>
<p>Having verified the archive we can go ahead and extract it.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">tar</span> <span class="nt">-xzvf</span> swift-5.2.2-RELEASE-ubuntu18.04.tar.gz
</code></pre></div></div>
<p>I keep these releases in the <code class="language-plaintext highlighter-rouge">/opt</code> directory in Ubuntu so once this has finished I move the extracted directory there.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo mv </span>swift-5.2.2-RELEASE-ubuntu18.04 /opt
</code></pre></div></div>
<p>And to make it easier to upgrade to later versions I link <code class="language-plaintext highlighter-rouge">/opt/swift</code> to the new Swift release. By recreating this link I can quickly switch between versions.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo rm</span> /opt/swift
<span class="nb">sudo ln</span> <span class="nt">-s</span> /opt/swift-5.2.2-RELEASE-ubuntu10.04 /opt/swift
</code></pre></div></div>
<p>At this point we should be able to run the Swift interactive shell and get a prompt.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>/opt/swift/usr/bin/swift
Welcome to Swift version 5.2.2 <span class="o">(</span>swift-5.2.2-RELEASE<span class="o">)</span><span class="nb">.</span>
Type :help <span class="k">for </span>assistance.
1> print<span class="o">(</span><span class="s2">"Hello World"</span><span class="o">)</span>
Hello World
2> :quit
</code></pre></div></div>
<p>One last step is to add the <code class="language-plaintext highlighter-rouge">/opt/swift/usr/bin</code> directory to your path. You’ll probably want to add this line to the bottom of your users <code class="language-plaintext highlighter-rouge">.bashrc</code> file, or equivalent depending on your shell, to save you having to run this each time you login.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">export </span><span class="nv">PATH</span><span class="o">=</span>/opt/swift/usr/bin:<span class="k">${</span><span class="nv">PATH</span><span class="k">}</span>
</code></pre></div></div>
<h2 id="hello-world">Hello World!</h2>
<p>Before we finish, having downloaded and installed Swift, let’s use it to compile something. To do this we will need to create a couple directories and files.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">mkdir</span> <span class="nt">-p</span> HelloWorld/Sources/HelloWorld
<span class="nv">$ </span><span class="nb">cd </span>HelloWorld
<span class="nv">$ </span><span class="nb">echo</span> <span class="s2">"print(</span><span class="se">\"</span><span class="s2">Hello World</span><span class="se">\"</span><span class="s2">)"</span> <span class="o">></span> Sources/HelloWorld/main.swift
</code></pre></div></div>
<p>Next we need to create a <code class="language-plaintext highlighter-rouge">Package.swift</code> file to tell the compiler what to build. Put the following in the <code class="language-plaintext highlighter-rouge">Package.swift</code> in the <code class="language-plaintext highlighter-rouge">HelloWorld</code> directory using an editor of your chooising.</p>
<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// swift-tools-version:5.2</span>
<span class="kd">import</span> <span class="kt">PackageDescription</span>
<span class="k">let</span> <span class="nv">package</span> <span class="o">=</span> <span class="kt">Package</span><span class="p">(</span>
<span class="nv">name</span><span class="p">:</span> <span class="s">"HelloWorld"</span><span class="p">,</span>
<span class="nv">products</span><span class="p">:</span> <span class="p">[</span>
<span class="o">.</span><span class="nf">executable</span><span class="p">(</span><span class="nv">name</span><span class="p">:</span> <span class="s">"HelloWorld"</span><span class="p">,</span> <span class="nv">targets</span><span class="p">:</span> <span class="p">[</span><span class="s">"HelloWorld"</span><span class="p">])</span>
<span class="p">],</span>
<span class="nv">targets</span><span class="p">:</span> <span class="p">[</span>
<span class="o">.</span><span class="nf">target</span><span class="p">(</span><span class="nv">name</span><span class="p">:</span> <span class="s">"HelloWorld"</span><span class="p">)</span>
<span class="p">]</span>
<span class="p">)</span>
</code></pre></div></div>
<p>You can then build the test app.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>swift build
<span class="o">[</span>4/4] Linking HelloWorld
</code></pre></div></div>
<p>If everything has worked out correctly you should now have a <code class="language-plaintext highlighter-rouge">HelloWorld</code> executable in the <code class="language-plaintext highlighter-rouge">.build/debug</code> directory we can run.</p>
<pre><code class="language-base">$ .build/debug/HelloWorld
Hello World
</code></pre>
Installing Ubuntu 18.04 & 20.04 LTS Server in VMWare Fusion2020-04-21T14:36:12+01:00327B182A-8526-4194-A6FF-42AC5A6F1B33<p>I just setup a Ubuntu Server 18.04 LTS Virtual Machine on VMWare Fusion on my Macbook and whilst the basic process was just following the default steps but there was a few other things I needed to change to get things working. Hence this post.
<!--more-->
If you need VMWare Fusion you can buy and install it from the <a href="https://www.vmware.com/products/fusion.html">VMWare website</a>. You’ll also need the Ubuntu Server 18.04 LTS ISO which can be found on the <a href="https://ubuntu.com/download/server">Ubuntu Server downloads page</a>.</p>
<p><em>Updated 27th April 2020</em>: A few days after writing this post Ubuntu released 20.04 LTS. I went through the same process using Ubuntu Server 20.04 LTS ISO and the steps are the same.</p>
<h2 id="new-virtual-machine">New Virtual Machine</h2>
<p>Walking through the VMWare Fusion (I’m using version 11.5) “Add Virtual Machine” wizard takes you through creating the Virtual Machine. I stuck with the defaults for the most part, other than changing the name of the VM and ensuring it was created on an exteral SSD I house my VM files on.</p>
<p>So <code class="language-plaintext highlighter-rouge">File -> New...</code> (⌘N) from the VMWare Fusion menu</p>
<p><img src="https://richardhyde.net/assets/2020-04-21 VMWare Fusion Select the Installation Method.png" alt="Select the Installation Method" /></p>
<p>Drag the iso file from Finder into the “Select the Installation Method” dialog</p>
<p><img src="https://richardhyde.net/assets/2020-04-21 VMWare Fusion Create a New Virtual Machine.png" alt="Create a New Virtual Machine" /></p>
<p>Hit the “Contiune” button and enter a password, it doesn’t matter what as it will be ignored by the Ubuntu Server installation which will add a user for you as part of the setup process, then continue some more.</p>
<p><img src="https://richardhyde.net/assets/2020-04-21 VMWare Fusion Linux Easy Install.png" alt="Enter a Password" /></p>
<p>Before we boot the VM and start the Ubuntu Server Installation process we need to change the Network Adaptor for the VM. So instead of clicking “Finish” button click the “Customize Settings” button and save the VM.</p>
<p><img src="https://richardhyde.net/assets/2020-04-21 VMWare Fusion Finish.png" alt="Finish" /></p>
<p>Then in the VMWare Fusion menu choose the <code class="language-plaintext highlighter-rouge">Virtual Machine -> Network Adapter -> Bridged (Autodetect)</code> option.</p>
<p>Now you can start the new VM.</p>
<h2 id="ubuntu-server-1804-lts-setup">Ubuntu Server 18.04 LTS Setup</h2>
<p>Once the VM has booted up you’ll need to select your language.</p>
<p><img src="/assets/2020-04-21 Ubuntu Server Select Language.png" alt="Language Selection" /></p>
<p>Configure your keyboard. The “English (UK) - English (UK, Macintosh)” layout mostly works for my Macbook and Apple Wireless Keyboards.</p>
<p><img src="https://richardhyde.net/assets/2020-04-21 Ubuntu Server Keyboard Configuration.png" alt="Keyboard Configuration" /></p>
<p>You’ll want to check the network adapter is configured for DHCP, so select the <code class="language-plaintext highlighter-rouge">ens33</code> adapter (in this case), and select <code class="language-plaintext highlighter-rouge">IPv4</code> and <code class="language-plaintext highlighter-rouge">Automatic (DHCP)</code> options.</p>
<p><img src="https://richardhyde.net/assets/2020-04-21 Ubuntu Server Network Connections IPv4 DHCP.png" alt="Network Connections" /></p>
<p>I didn’t need to setup a proxy.</p>
<p><img src="https://richardhyde.net/assets/2020-04-21 Ubuntu Server Configure Proxy.png" alt="Configure Proxy" /></p>
<p>Nor did I change Ubuntu archive mirror to use.</p>
<p><img src="https://richardhyde.net/assets/2020-04-21 Ubuntu Server Configure Ubuntu Archive Mirror.png" alt="Configure Ubuntu Archive Mirror" /></p>
<p>Now we go through a few steps to setup the Filesystem. These were all the defaults.</p>
<p><img src="https://richardhyde.net/assets/2020-04-21 Ubuntu Server Filesystem Setup.png" alt="Filesystem Setup" /></p>
<p><img src="https://richardhyde.net/assets/2020-04-21 Ubuntu Server Filesystem Setup 2.png" alt="Filesystem Setup" /></p>
<p><img src="https://richardhyde.net/assets/2020-04-21 Ubuntu Server Filesystem Setup 3.png" alt="Filesystem Setup" /></p>
<p><img src="https://richardhyde.net/assets/2020-04-21 Ubuntu Server Filesystem Setup 4.png" alt="Filesystem Setup" /></p>
<p>Details of your user and name your Ubuntu Server.</p>
<p><img src="https://richardhyde.net/assets/2020-04-21 Ubuntu Server Profile Setup.png" alt="Profile Setup" /></p>
<p>I choose to install OpenSSH at this point.</p>
<p><img src="https://richardhyde.net/assets/2020-04-21 Ubuntu Server SSH Setup.png" alt="SSH Setup" /></p>
<p>You can select any Snaps you want installing here. I went for a vanilla server install.</p>
<p><img src="https://richardhyde.net/assets/2020-04-21 Ubuntu Server Featured Server Snaps.png" alt="Featured Server Snaps" /></p>
<p>The installation begins.</p>
<p><img src="https://richardhyde.net/assets/2020-04-21 Ubuntu Server Installing System.png" alt="Installing System" /></p>
<p>Once the installation has finished you can reboot.</p>
<p><img src="https://richardhyde.net/assets/2020-04-21 Ubuntu Server Installation Complete.png" alt="Installation Complete!" /></p>
<h2 id="all-done">All Done</h2>
<p>That’s it. You should now have a Ubuntu Server VM running ready to install whatever you need on it.</p>
Issue Box Dev Diary #32019-05-24T17:56:30+01:000c4c7f95-524b-49cf-bcc5-7833684e3f02<p>Major achievement to end the week, there are issues in the issues app! Well the basic details of them anyway. There’s still a lot to sync up yet. Each issue can have comments and attachments which need syncing, along with versions, users, milestones and components to which an issue can be assigned. These all need objects creating in the data store and methods written to pull the information from the REST apis., and then I need to turn around and write methods to put any changes made back into Bitbucket.</p>
<p>Also lacking at this point is any way of seeing the issues in the app. That will be something to work on over the weekend. By Monday I hope to have atleast a list page showing the issues for a project. Screenshots to follow.</p>
Issue Box Dev Diary #22019-05-22T17:43:30+01:0051734956-65CA-4D13-BC0A-026D2F24D81F<p>Spent yesterday and today setting up the initial UI storyboards, Json mapping structures and lots (and lots) of test cases.</p>
<p>I’ve got the point where you can navigate through to the accounts settings screen and add a new Bitbucket account into the system, with a popup web view to prompt for the user authroisation, ready to starting pulling in the repositories and issues through.</p>
<p><img src="https://richardhyde.net/assets/2019-05-22-Issue-Box-Screenshot-1.png" alt="Adding a Bitbucket account" class="media" /></p>
Issue Box Dev Diary #12019-05-20T21:10:27+01:002A04CFD9-5082-4782-8EAE-1A5E88B49E32<p>I started work on a new iOS today I’m calling Issue Box as a working title, it may change before release. It’s designed to allow you to manage software issues logged across projects in <a href="https://www.bitbucket.org">Bitbucket</a>, <a href="https://www.github.com">Github</a> and <a href="https://www.jira.com">Jira</a>.</p>
<p>Not much to see at the much to see at the moment. Today I’ve been working on getting OAuth support for Bitbucket (as that’s the service I use) and initial data storage layouts for account details.</p>
<p>I’ll post more details and some screenshots as things start to come together.</p>
Robotic Bees Arrive at the ISS2019-04-20T12:25:02+01:00BEE7589E-9187-4B3C-B37B-82479AF35275<div class="jekyll-twitter-plugin"><blockquote class="twitter-tweet"><p lang="en" dir="ltr">Special delivery! <br /><br />Our flying robotic “bees” arrived earlier today at the <a href="https://twitter.com/Space_Station?ref_src=twsrc%5Etfw">@Space_Station</a>. If you haven’t heard about our Astrobee robots 🤖, here’s what all the buzz is about: <a href="https://t.co/exs00mMNcB">https://t.co/exs00mMNcB</a> <a href="https://t.co/nPhOYGTLwN">pic.twitter.com/nPhOYGTLwN</a></p>— NASA Ames (@NASAAmes) <a href="https://twitter.com/NASAAmes/status/1119363315124150272?ref_src=twsrc%5Etfw">April 19, 2019</a></blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</div>
Let's Encrypt Certificates2019-04-19T13:48:10+01:003D384822-80D9-4312-AE8F-424839F3ADD0<p>The <a href="https://letsencrypt.org">Let’s Encrypt</a> project generates free SSL Certificates for websites to allow encrypted traffic between the web server and browser. The current batch of browsers are highlighting unencrypted (non-HTTPS) sites as a possible security risk so setting up the certificates stops the site being flagged unnecessarily.
<!--more-->
I used the following commands, taken from <a href="https://webnlinux.com/install-letsencrypt-ssl-cert-on-aws-ec2-ubuntu-instance/">here</a>, to add the certificates to this website.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get <span class="nb">install </span>python-certbot-apache
<span class="nb">sudo </span>certbot <span class="nt">--apache</span> <span class="nt">-d</span> richardhyde.net <span class="nt">-d</span> www.richardhyde.net
</code></pre></div></div>
<p>I then added this line to roots crontab renew the certificate at 7am and 7pm each day. This seems a bit overkill as the certificates are valid for 30 days but twice a day seems to be the recommendation.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>* 7,19 * * * /usr/bin/certbot -q renew
</code></pre></div></div>
New Reminder Using JXA2019-04-16T15:31:26+01:0090D14B24-BE87-48A4-961B-AF17BB531DEF<p>Here is a quick code snippet for creating new Reminders in a specific list using JavaScript for Automation (JXA) in macOS.</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">reminders</span> <span class="o">=</span> <span class="nx">Application</span><span class="p">(</span><span class="dl">"</span><span class="s2">Reminders</span><span class="dl">"</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">newReminder</span> <span class="o">=</span> <span class="nx">reminders</span><span class="p">.</span><span class="nx">Reminder</span><span class="p">({</span> <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Title for reminder</span><span class="dl">"</span><span class="p">,</span> <span class="na">body</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Notes for the reminder</span><span class="dl">"</span><span class="p">});</span>
<span class="nx">reminders</span><span class="p">.</span><span class="nx">lists</span><span class="p">.</span><span class="nx">byName</span><span class="p">(</span><span class="dl">"</span><span class="s2">List Name</span><span class="dl">"</span><span class="p">).</span><span class="nx">reminders</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">newReminder</span><span class="p">);</span>
</code></pre></div></div>
Adding Custom Import File Types2019-02-08T12:55:41+00:0032C87488-8B4B-4120-8373-284068B4CF44<p>I needed to import an OPML (Outline Processor Markup Language) file from with-in an iOS app. The <a href="htttps://en.wikipedia.org/wiki/OPML">OPML format</a> is a XML format used for storing <a href="https://en.wikipedia.org/wiki/Outline_(list)">outlines</a> but is also commonly used to share lists of subscriptions between RSS feed readers and podcast players.
<!--more-->
The problem is that the OPML extension is not one of the standard UTIs (Universal Type Identifiers) <a href="https://developer.apple.com/library/archive/documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html">supported by Apple</a> so files with the OMPL extension are greyed out in the file browser.</p>
<p><img src="https://richardhyde.net/assets/2019-02-08-Document-Picker-OPML-Disabled.JPEG" alt="Disabled OPML file in the document picker" class="media" /></p>
<p>To get files to be recognised I needed to define the OPML UTI in the “Imported Type UTIs” for the project. Within Xcode (I’m using Xcode 10.1 so things may be in different places in other versions) there are two ways of doing this, with through the project settings GUI or be adding the entries to the applications Info.plist.</p>
<p><img src="https://richardhyde.net/assets/2019-02-08-OPML-File-Import-Settings.png" alt="OPML File Import Settings" class="media" /></p>
<p>Using these settings in the info tab of the project settings creates the following entries in the Info.plist file. The icon came from <a href="https://www.opmlicons.com">OPML Icon project</a>.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.xml</string>
</array>
<key>UTTypeDescription</key>
<string>OPML File</string>
<key>UTTypeIconFiles</key>
<array>
<string>opml-icon-128x128</string>
</array>
<key>UTTypeIdentifier</key>
<string>public.opml</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>opml</string>
</array>
</dict>
</dict>
</array>
</code></pre></div></div>
<p>The “Conforms To” field needs to be one of the UTIs Apple already recognises. In this case as the OPML uses XML I used the public.xml UTI. With these settings in the project I changed the document types parameter of my UIDocumentPickerViewController initialiser to include the new public.opml document type and the opml files where then accessable from my app.</p>
<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">documentPicker</span> <span class="o">=</span> <span class="kt">UIDocumentPickerViewController</span><span class="p">(</span><span class="nv">documentTypes</span><span class="p">:</span> <span class="p">[</span><span class="kd">public</span><span class="o">.</span><span class="n">opml</span><span class="p">],</span> <span class="nv">in</span><span class="p">:</span> <span class="kt">UIDocumentPickerMode</span><span class="o">.</span><span class="kd">import</span><span class="p">)</span>
</code></pre></div></div>
<p><img src="https://richardhyde.net/assets/2019-02-12-Document-Picker-OPML-Enabled.jpeg" alt="Enabled OPML file in the document picker" class="media" /></p>
iPad Pro 12.9" Unboxing2018-11-07T12:20:46+00:00F7135F31-C06B-475C-9C31-0D37D6FBC530<p>My new iPad Pro 12.9” just arrived along with the new Keyboard Folio case, so here are a few pictures of them in their boxes. I’ll post some side-by-side shots with the old one, along with some first impressions once I’ve had a chance to set it up and play with it for a bit.
<!--more--></p>
<h2 id="apple-ipad-pro-129">Apple iPad Pro 12.9”</h2>
<p><img src="/assets/2018-11-07-iPad-Pro-12.9”-Unboxing-1.jpeg" alt="Box Art" /> <img src="/assets/2018-11-07-iPad-Pro-12.9”-Unboxing-3.jpeg" alt="iPad takes up all of the box" /> <img src="/assets/2018-11-07-iPad-Pro-12.9”-Unboxing-2.jpeg" alt="Documentation hidden under the iPad" /> <img src="/assets/2018-11-07-iPad-Pro-12.9”-Unboxing-4.jpeg" alt="USB-C cable and Charger hidden under the documentation" /></p>
<h2 id="apple-smart-keyboard-folio-case">Apple Smart Keyboard Folio Case</h2>
<p><img src="/assets/2018-11-07-Smart-Keyboard-Folio-Case-1.jpeg" alt="Box Front" />
<img src="/assets/2018-11-07-Smart-Keyboard-Folio-Case-3.jpeg" alt="Just the keyboard case in there" />
<img src="/assets/2018-11-07-Smart-Keyboard-Folio-Case-2.jpeg" alt="Smart Keyboard Folio Case Layed Flat" /></p>
Jurassic Bark2018-11-06T10:00:39+00:00672049A9-8BF3-4A19-B951-F117BE1B17AA<div class="jekyll-twitter-plugin"><blockquote class="twitter-tweet"><p lang="en" dir="ltr">Jurassic Bark 🦖 <a href="https://t.co/Homro9aR42">pic.twitter.com/Homro9aR42</a></p>— Marshall Julius 🚀 (@MarshallJulius) <a href="https://twitter.com/MarshallJulius/status/1059382707996778497?ref_src=twsrc%5Etfw">November 5, 2018</a></blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</div>
New AirPods on the Horizon2018-11-05T20:39:16+00:00E8B81934-D57D-4667-9E8B-959CD44E25EB<p>It looks line new AirPods could near to being released. According to reports two new models of AirPods have been certified by the Bluetooth SIG (Special Interest Group) which they need to have before being released.
<!--more-->
Rumours are these will have Bluetooth 5 support which would allow for longer battery life and better connectivity, “Hey Siri” support, and that the case would support QI wireless charging. It could be that the AirPods would be available with and without the wireless charging case which could explain the two model numbers.</p>
<p>No news as to when they are expected to be available, but my guess is that they would be released at the same time as the AirPower charing matt which Apple announced in September 2017 but has been delayed since. Both of these may be released in time for the holiday period, or could be held until early next year.</p>
<p><a href="https://9to5mac.com/2018/11/05/new-airpods-update-bluetooth-sig-certification/">9to5Mac</a></p>
watchOS 5.1.1 Update Available2018-11-05T20:33:16+00:002F89962A-5DBC-429E-A977-E63F0777E58F<p>Apple have release watchOS 5.1.1 update after pulling the watchOS 5.1 update released last week due to some Series 4 appleWatches were bricked whilst installing the update. I think I’ll still wait until tomorrow to update mine just in case.</p>
<p><a href="https://9to5mac.com/2018/11/05/watchos-5-1-1-apple-watch-bricking-fix/">9to5Mac</a></p>
Live Listening with AirPods and iOS 122018-11-05T11:30:45+00:004CCD8874-06C3-434E-A8CC-05EA12E4F343<p><a href="https://www.macrumors.com/how-to/use-live-listen-feature-with-airpods-ios-12/">MacRumors</a> have an article on how to setup Live Listen with AirPods. Live Listen has been in iOS since 2014 and allows your iOS device to be used as microphone for compatible hearing aids but with iOS 12 the feature works with AirPods as well.</p>
<p>Whilst this might not seem that useful if you’re not hard of hearing, but as long as your AirPods are connected to your iPhone you can listening in to whatever is going on where your iPhone is.</p>
Heavy Lifting Tiny Drones2018-10-28T17:33:12+00:005e02bb87-0a36-44cb-9b46-aa82fc58506e<p>These tiny drones can lift 40 times their own weight and open doors.</p>
<p><a href="https://www.engadget.com/2018/10/27/flycrotugs-gripping-lifting-drones-stanford-epfl/">Via Engadget</a></p>
<div class="video"><figure><iframe width="640" height="480" src="//www.youtube.com/embed/FdmS_89mVqY" frameborder="0" allowfullscreen=""></iframe></figure></div>