<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Video on blog.iankulin.com</title><link>https://blog.iankulin.com/tags/video/</link><description>Recent content in Video on blog.iankulin.com</description><generator>Hugo</generator><language>en-AU</language><lastBuildDate>Mon, 05 Feb 2024 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.iankulin.com/tags/video/index.xml" rel="self" type="application/rss+xml"/><item><title>Web Development Overview</title><link>https://blog.iankulin.com/web-development-overview/</link><pubDate>Mon, 05 Feb 2024 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/web-development-overview/</guid><description>&lt;p&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2024-01-27-at-1.00.35-pm.jpg" alt=""&gt;&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t often just link to someone else&amp;rsquo;s content, but I was really impressed with &lt;a href="https://www.traversymedia.com/"&gt;Brad Traversy&lt;/a&gt;&amp;rsquo;s &amp;ldquo;Web Development In 2024 - A Practical Guide&amp;rdquo; video. Apparently he does these every year - it&amp;rsquo;s just a really comprehensive overview of Web Development pitched at beginners.&lt;/p&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
 &lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/8sXRyHI3bLw?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
 &lt;/div&gt;
</description></item><item><title>Complicating the Temperature API</title><link>https://blog.iankulin.com/complicating-the-temperature-api/</link><pubDate>Wed, 28 Jun 2023 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/complicating-the-temperature-api/</guid><description>&lt;p&gt;I&amp;rsquo;ve been slammed with other work, so my web dev learning has fallen well behind. Luckily, the YouTube procrastination algorithm noticed this and suggested I watch a video from &lt;a href="https://www.youtube.com/@codewithcon"&gt;CodeWithCon&lt;/a&gt; titled &lt;a href="https://www.youtube.com/watch?v=KNa-wMpry00&amp;amp;list=PLkJHe6eU_tzeoe7vKUEa4MrS74CpVEwdI&amp;amp;index=3&amp;amp;t=305s"&gt;Learn Backend in 10 MINUTES&lt;/a&gt;.&lt;/p&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
 &lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/KNa-wMpry00?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
 &lt;/div&gt;

&lt;p&gt;Since I was watching a video of a guy learning to land a C152 at St Baths (a skill I do &lt;em&gt;not&lt;/em&gt; need) at the time, it was hard to argue with myself that I didn&amp;rsquo;t have ten minutes to learn all of backend programming.&lt;/p&gt;
&lt;p&gt;I mean, &lt;em&gt;all&lt;/em&gt; of backend programming in 10 minutes is a big claim, but the video did do a surprising good job of simple REST APIs in &lt;a href="https://nodejs.org/en"&gt;Node&lt;/a&gt; using the &lt;a href="http://expressjs.com/"&gt;Express&lt;/a&gt; framework.&lt;/p&gt;
&lt;p&gt;I abandoned iOS programming a year ago when I started to think about the sort of applications I wanted to develop, and saw they would need to run against cloud databases, and so I was going to have to learn backend web dev at some stage anyway, and if so, learning that, then writing the front-ends for web seemed like a lower friction, and wider audience approach.&lt;/p&gt;
&lt;p&gt;I have &lt;em&gt;sort&lt;/em&gt; of created an API to solve my &lt;a href="https://blog.iankulin.com/outside-temperature-from-an-api-in-a-shell-script/"&gt;temperature logging problem&lt;/a&gt;. A Python script runs as a cron job every 5 minutes on a VPS, calls a weather API, parses the json and drops the values I want into a text file on an NGINX server which can be called with a straightforward GET.&lt;/p&gt;
&lt;p&gt;While that was great to learn a bit of Python, it&amp;rsquo;s not pretty, or standard. It does solve the problem I intended (I wanted that weather data for three servers running at home, but didn&amp;rsquo;t want to hammer the weather API I was using for free) it has a few other problems. As the cron job on the VPS runs each five minutes, the data there can be up to five minutes behind the API, and since the cron jobs on my servers are running on the same five minute intervals, and the call to the Australian VPS is quicker than the API call to the US based API, I&amp;rsquo;m always returning the VPS data from five minutes ago - so now my data is up to ten minutes old.&lt;/p&gt;
&lt;p&gt;Does that matter for this application? No, but the whole exercise was for learning, and this is a good enough reason to improve it my making it even more unnecessarily complicated.&lt;/p&gt;
&lt;p&gt;I think my new system will be that the homelab servers will still poll the VPS, but the VPS will be a Node.js endpoint. When it receives a GET from one of the servers, it will check the age of it&amp;rsquo;s current weather data. If it&amp;rsquo;s less than a minute, it will return that, if it&amp;rsquo;s older than a minute, it will call the weather API, store that and return it.&lt;/p&gt;
&lt;img src="https://blog.iankulin.com/images/20230624-weather.drawio-1.png" width="512" alt=""&gt;
&lt;p&gt;Apart from reducing the latency of the outside temperature data, this has a couple of other benefits. The first is that my VPS won&amp;rsquo;t go on for ever requesting the weather API data after I&amp;rsquo;ve reloaded the operating system on the home servers and completely forgotten about this project. The second is that the temperatures in the data I&amp;rsquo;m getting back look like they only change every 20 minutes, so probably they are stale before I ever get them from Open Weather. There are live weather station web pages that I could scrape for better data, so doing things in node on the VPS leaves a good option open for that future improvement.&lt;/p&gt;
&lt;p&gt;To chunk the project down to really small bite sizes, I&amp;rsquo;ll to it in two parts.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The first will just be to replicate the current system - return a text file when receiving a GET - in Node. That way I will have dealt with the issue of running Node behind NGINX on the VPS.&lt;/li&gt;
&lt;li&gt;The second part will be to expand that to call the weather API from inside the Node program when it&amp;rsquo;s needed.&lt;/li&gt;
&lt;li&gt;A possible third part would be to convert it all to JSON instead of text, and then deal with that in the Python scripts running on the servers.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That&amp;rsquo;s the plan.&lt;/p&gt;</description></item><item><title>CSS for Beginners</title><link>https://blog.iankulin.com/css-for-beginners/</link><pubDate>Thu, 15 Dec 2022 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/css-for-beginners/</guid><description>&lt;p&gt;I mentioned a couple of days ago that the ZTM webdev course was skipping forwards too quick and that it would need to be supplemented. For CSS, I think the supplement for me is going to be this &lt;a href="https://www.youtube.com/playlist?list=PL0Zuz27SZ-6Mx9fd9elt80G1bPcySmWit"&gt;series&lt;/a&gt; from Dave Gray.&lt;/p&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
 &lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/0W6qz0-aDaM?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
 &lt;/div&gt;
</description></item><item><title>Towards MVVM</title><link>https://blog.iankulin.com/towards-mvvm/</link><pubDate>Sat, 03 Dec 2022 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/towards-mvvm/</guid><description>&lt;p&gt;On one of the more mediocre &lt;a href="https://firesideswift.fireside.fm/96"&gt;episodes of Fireside Swift&lt;/a&gt;, McSwiftface and Zach talk about the &lt;a href="https://en.wikipedia.org/wiki/SOLID"&gt;SOLID principles&lt;/a&gt; of class design, although I don&amp;rsquo;t hold the principles as the article of religious fervour that many interviewers apparently do, they are a useful touchstone for considering class quality. OOP had been in swing (in a commercial way) for a few years by then - I was writing in Delphi and C++. The spaghetti code era was a long way behind us and the idea of separation of responsibilities was well established.&lt;/p&gt;
&lt;p&gt;I have been thinking about architecture a bit anyway - the introduction of Core Data into the &lt;a href="https://www.hackingwithswift.com/100/swiftui"&gt;#100Day&lt;/a&gt; apps I&amp;rsquo;m up to (day 63) means that there&amp;rsquo;s complicated looking code scattered around my views. In the &lt;a href="https://cs193p.sites.stanford.edu/"&gt;cs193p lectures&lt;/a&gt;, MVVM is right near the start, and I made &lt;a href="https://blog.iankulin.com/tags/mvvm/"&gt;some early forays&lt;/a&gt; into it, but so far no talk of architecture in 100Days (although I know it&amp;rsquo;s coming soon.&lt;/p&gt;
&lt;p&gt;I have certainly had the experience before of needing a layer between my apps and the database tech so they can be swapped out, and it&amp;rsquo;s basically a reflex to me to always wrap any commercial external code I&amp;rsquo;m introducing in any reasonable size program to abstract it a bit and make the (likely) task of having to replace it in the future a lot easier.&lt;/p&gt;
&lt;p&gt;Once again, YouTube serves me up a timely video.&lt;/p&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
 &lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/ehV2gp5uVhs?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
 &lt;/div&gt;

&lt;p&gt;When I watch this, I can see why Paul Hudson might have left it for later in the course. There is a lot of complexity. It&amp;rsquo;s not simple code, it&amp;rsquo;s scalable code. This is good for real life apps, but it does not follow that it&amp;rsquo;s good for learning programming.&lt;/p&gt;</description></item><item><title>Calculator</title><link>https://blog.iankulin.com/calculator/</link><pubDate>Thu, 29 Sep 2022 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/calculator/</guid><description>&lt;p&gt;The app I&amp;rsquo;m working on currently (for multiplication tables practice) has a number type keypad and display a bit like a calculator - but for entering the answers. It&amp;rsquo;s been quite fun to think through all the little problems to make it work how you&amp;rsquo;d expect, so I was quite interested to watch an iOS Academy video where Afraz Siddiqui builds a partially finished SwiftUI version of the iOS Calculator app.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=cMde7jhQlZI"&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2022-09-25-at-2.42.34-pm.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It is a great example for beginners to see the power of building views quickly in SwiftUI, but the most fun part for me was thinking of all the edge cases that would hadn&amp;rsquo;t been dealt with in his quick build out of the logic (which wasn&amp;rsquo;t the point of the video).&lt;/p&gt;
&lt;p&gt;A couple of times I&amp;rsquo;ve thought about building copies of existing Apple iOS apps. I think part of the appeal is that the design work is done for me, so I&amp;rsquo;m just thinking about under the hood. Long term, I need to know more about design and to be better at it - I bet there&amp;rsquo;s a &lt;a href="https://designcode.io/ui-design"&gt;Meng To&lt;/a&gt; course that would be a good starting point.&lt;/p&gt;</description></item><item><title>Gitting up to date</title><link>https://blog.iankulin.com/gitting-up-to-date/</link><pubDate>Tue, 27 Sep 2022 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/gitting-up-to-date/</guid><description>&lt;p&gt;I&amp;rsquo;ve started the habit of branching my code for each feature or batches of features. This is not really needed, I&amp;rsquo;ve developing solo, and the code on &lt;code&gt;main&lt;/code&gt; is not in production. I could just go on committing, but part of my process is about becoming competent with git.&lt;/p&gt;
&lt;p&gt;There are a couple of git commands (&lt;code&gt;merge&lt;/code&gt; and &lt;code&gt;rebase&lt;/code&gt;) that mush code between branches together in different ways. The video below (from &lt;a href="https://www.udemy.com/user/manuel-lorenz/"&gt;Manuel Lorenz&lt;/a&gt; at &lt;a href="https://academind.com/"&gt;Academind&lt;/a&gt;) is a particularly clear look at these two commands.&lt;/p&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
 &lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/CRlGDDprdOQ?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
 &lt;/div&gt;

&lt;p&gt;The discussion that follows is essentially just a re-hash of the video above, so if you think you&amp;rsquo;ve got it, you can leave now!&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the situation we start with. A &amp;ldquo;feature&amp;rdquo; branch was created at the point in time that the most recent commit on the master branch was &amp;ldquo;m2&amp;rdquo;. A couple of commits have been made to the feature branch, but meanwhile a further commit has been made on the master branch:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2022-09-24-at-7.00.08-pm.jpg" alt=""&gt;&lt;/p&gt;
&lt;p&gt;So, what are the options now? (this is just a rehash of the video above in my words, so if you already watched that, you may leave :- ) I&amp;rsquo;m going to use &amp;ldquo;master&amp;rdquo; in my discussions here since that&amp;rsquo;s what Manuel uses, but if you&amp;rsquo;re new to git and you&amp;rsquo;ve only ever seen &amp;ldquo;main&amp;rdquo; - they are just different names for the default branch, &amp;ldquo;main&amp;rdquo; is the current (and slightly better) preference for that name.&lt;/p&gt;
&lt;h3 id="merge"&gt;Merge&lt;/h3&gt;
&lt;p&gt;We could checkout the master branch, and merge feature into it with&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git merge feature&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;That works, and our commit history for the master branch will look like this:&lt;/p&gt;
&lt;p&gt;M1 - M2 - F1 - F2 - M3 - Merge&lt;/p&gt;
&lt;h3 id="squash"&gt;Squash&lt;/h3&gt;
&lt;p&gt;To bundle up the feature branch and bring it across to master, we can (from the master branch) do:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git merge --squash feature&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;That add all the feature changes to the current branch, but they&amp;rsquo;re not committed yet, so we&amp;rsquo;ll also:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git commit -m &amp;quot;add feature&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The history of the master branch now will be:&lt;/p&gt;
&lt;p&gt;M1 - M2 - M3 - add feature&lt;/p&gt;
&lt;p&gt;So this is sort of neater, instead of a chronological history in the commits, we&amp;rsquo;re conceptually saying the feature work was all done in a single commit after the M3 change. But&amp;hellip; what if we wanted to keep the feature commit history?&lt;/p&gt;
&lt;h3 id="rebase"&gt;Rebase&lt;/h3&gt;
&lt;p&gt;Just to recap, although our master branch is up to m3, the feature branch was &lt;em&gt;based&lt;/em&gt; off m2. So if we had a look at the history of the feature branch (using git log) it looks like this:&lt;/p&gt;
&lt;p&gt;M2 - F1 - F2&lt;/p&gt;
&lt;p&gt;Rebasing it will look at the changes in feature then apply them to the current m3 commit in master. If we change to the feature branch and enter:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git rebase master&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Now the feature history will be&lt;/p&gt;
&lt;p&gt;M1 - M2 - M3 - F1 - F2&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s sort of cool and all, basically the code in the feature branch is in the state that master would be after we&amp;rsquo;ve joined them back up, so we can go ahead and test and so on. But we haven&amp;rsquo;t actually joined up feature and master yet. To do that, we could to checkout the master branch, and rebase it from feature with:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git rebase feature&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Then master will have the same history as feature: M1 - M2 - M3 - F1 - F2 That can just be committed and we&amp;rsquo;re good to go. Since the whole commit history is now in the master branch its fine to go ahead and delete the feature branch.&lt;/p&gt;
&lt;h3 id="gotcha"&gt;Gotcha&lt;/h3&gt;
&lt;p&gt;If you&amp;rsquo;re working in a team around a shared repository, it makes a lot of sense to rebase your local project from the current main/master in the shared repo. That way you can test for any problems your code might have with the current version, but, it&amp;rsquo;s bad form to rebase any commits that get pushed up. A good explanation for why this is can be found in the &lt;a href="https://git-scm.com/book/en/v2/Git-Branching-Rebasing"&gt;git docs&lt;/a&gt; - scroll down to &amp;ldquo;the perils of rebasing&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Instead what we should have done in the example above if we were planning on pushing the master would have been to rebase our feature branch as we did, but then change to the master branch and merge the feature branch in with&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git merge feature&lt;/code&gt;&lt;/p&gt;</description></item><item><title>iOS Academy</title><link>https://blog.iankulin.com/ios-academy-2/</link><pubDate>Mon, 26 Sep 2022 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/ios-academy-2/</guid><description>&lt;p&gt;A YouTube channel worth subscribing to is &lt;a href="https://www.linkedin.com/in/afrazsiddiqui"&gt;Afraz Siddiqui&amp;rsquo;s&lt;/a&gt; &lt;a href="https://www.youtube.com/c/iOSAcademy/videos"&gt;iOS Academy&lt;/a&gt;. He does a great videos on iOS development. My favouriets might be the shorter focussed ones, like this one on the new SwiftUI chart views.&lt;/p&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
 &lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/KVz_I10R-wA?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
 &lt;/div&gt;
</description></item><item><title>Before SwiftUI</title><link>https://blog.iankulin.com/before-swiftui/</link><pubDate>Wed, 14 Sep 2022 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/before-swiftui/</guid><description>&lt;p&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2022-09-10-at-9.28.24-am.jpg" alt=""&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m on Day 26 of 100 Days, and didn&amp;rsquo;t grok the dates on my first read through, so I&amp;rsquo;ve read a couple of other explanations and sat down with a coffee and thought I&amp;rsquo;d see what YouTube had for me on the subject. I seen a few great &lt;a href="https://www.youtube.com/c/iOSAcademy/videos"&gt;iOS Academy&lt;/a&gt; videos, so &lt;a href="https://www.youtube.com/watch?v=HSFTzcYzuEQ"&gt;this one&lt;/a&gt; seemed like a good choice.&lt;/p&gt;
&lt;p&gt;I haven&amp;rsquo;t seen enough to say if it is a good or great explanation of dates, calendars and date components in Swift yet, but man, getting to the stage of writing useful code when using storyboards and UIKit takes a while! It&amp;rsquo;s literally 3:42 in to the video before there&amp;rsquo;s enough infrastructure done for &amp;ldquo;hello world&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Takeaways: (1) Watching the launch of SwiftUI must have been mind-blowing. (2) I super appreciate the existence of Playgrounds for learning Swift.&lt;/p&gt;</description></item><item><title>Sometimes the Gold is in the Comments</title><link>https://blog.iankulin.com/sometimes-the-gold-is-in-the-comments/</link><pubDate>Tue, 23 Aug 2022 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/sometimes-the-gold-is-in-the-comments/</guid><description>&lt;p&gt;I&amp;rsquo;m still not 100% clear on @ObservedObject v @StateObject. So when YouTube offered up this video, in which Paul promises during the intro that I&amp;rsquo;ll understand the data bindings by the end, I thought it would be the video for me.&lt;/p&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
 &lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/stSB04C4iS4?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
 &lt;/div&gt;

&lt;p&gt;I guess I should really have twigged that I&amp;rsquo;d never heard of @ObjectBinding, but I pushed on to the 12 minute mark when he imports the &lt;em&gt;Combine&lt;/em&gt; framework. Hang on, what&amp;rsquo;s that?&lt;/p&gt;
&lt;p&gt;Checking out the comments, it all becomes clear.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2022-08-14-at-8.26.59-pm.jpg" alt=""&gt;&lt;/p&gt;
&lt;p&gt;Sadly, it&amp;rsquo;s a page down in the comments, when it&amp;rsquo;d be great to be pinned to the top.&lt;/p&gt;
&lt;p&gt;When we&amp;rsquo;re publishing content in a tech field that&amp;rsquo;s changing, there probably is probably some benefit to tagging it with versions - for example, my post on git is sort of useful now, but in three years? Who knows. Like this video of Paul&amp;rsquo;s it may be unhelpful and confusing.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll put some thought into how I might do that. Going back and updating things is probably not realistic (this is certainly the case for twostraws&amp;rsquo; videos - he&amp;rsquo;s prolific), but branding content with the versions of things might be. Wordpress dates content at the bottom of the post (on my current theme) so that would give some future traveler some chance, but the more novice they are (and currently my understanding of these topics is only helpful for novices) the less likely they are to be equipped to translate the date into the likelihood of the content being outdated. Perhaps I can use tags somehow. I&amp;rsquo;ll think about it.&lt;/p&gt;</description></item><item><title>CSS Intro</title><link>https://blog.iankulin.com/css-intro/</link><pubDate>Thu, 18 Aug 2022 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/css-intro/</guid><description>&lt;p&gt;When I wrote my last commercial HTML (in 1996 lol) I&amp;rsquo;m pretty sure there was no CSS. It was the land of textured backgrounds, blinking scrolling text, &amp;ldquo;under construction&amp;rdquo; gifs, and links to &lt;a href="https://en.wikipedia.org/wiki/Gopher_(protocol)"&gt;gopher&lt;/a&gt; URLs were not uncommon. So this is an area I need to update my skills a little just to carry on a coherent conversation in the developer world.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve bumped into a couple of &lt;a href="https://www.techwithtim.net/"&gt;Tech With Tim&lt;/a&gt; &lt;a href="https://www.youtube.com/c/TechWithTim/videos"&gt;videos&lt;/a&gt; recently, and I really liked his CSS intro for &amp;ldquo;Non-web developers&amp;rdquo;.&lt;/p&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
 &lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/ZzoAu4VPyho?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
 &lt;/div&gt;
</description></item><item><title>iOS Academy</title><link>https://blog.iankulin.com/ios-academy/</link><pubDate>Mon, 08 Aug 2022 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/ios-academy/</guid><description>&lt;p&gt;I seem to consume a lot of &lt;a href="https://iosacademy.io/"&gt;iOS Academy&lt;/a&gt; videos with great, short (&amp;lt; 10 minute) explanations of various Swift iOS programming topics - particularly little UI topics, like this one on the Grid View.&lt;/p&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
 &lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/A3jOHj9erQ4?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
 &lt;/div&gt;

&lt;p&gt;I really appreciate the generous content provision in the Swift and iOS development community. Perhaps this is the same for lots of technologies, but for someone who started programming pre-internet, it&amp;rsquo;s a stark difference to how I used to learn - so many magazines, and so many 2&amp;quot; thick books.&lt;/p&gt;</description></item><item><title>MVVM Explained</title><link>https://blog.iankulin.com/mvvm-explained/</link><pubDate>Sun, 07 Aug 2022 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/mvvm-explained/</guid><description>&lt;p&gt;The first nine minutes of &lt;a href="https://www.youtube.com/watch?v=sLHVxnRS75w"&gt;this video&lt;/a&gt; from &lt;a href="https://twitter.com/Its_Macco"&gt;Emmanuel Okwara&lt;/a&gt; finally gave me a clear understanding of the difference between MVC and MVVM.&lt;/p&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
 &lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/sLHVxnRS75w?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
 &lt;/div&gt;

&lt;p&gt;In both MVC and MVVM the data &amp;amp; logic (Model) are separated from the part that the user interacts (View). Usually the View is a screen with controls and so on, but that&amp;rsquo;s not compulsory - for example a voice mail app interface would be all audio and DTMF. The point is that in both, the user interface (view) does not mess directly with the data (model) - it has to go through some sort of gatekeeper.&lt;/p&gt;
&lt;p&gt;The new understanding I got from Emmanuel is that in MVVM, the View Model does not know what is in the View. It does not alter the view, just broadcasts that there&amp;rsquo;s been a change and lets the view go ahead and update itself. It makes sense that this would be the paradigm for SwiftUI&amp;rsquo;s declarative interface style, and is also (I imagine but actually have no idea) the basis for React.js&lt;/p&gt;
&lt;p&gt;One thing Emmanuel mentions that I&amp;rsquo;m not clear on is that each View will have it&amp;rsquo;s own View Controller. Currently all my tiny apps have had one view in the SwiftUI sense. I have pulled out sub views, and some have had views within views - for example with the Navigation View. So I guess my question would be, &amp;ldquo;What constitutes a View in MVVM?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;I noped out at the nine minute mark as soon as Interface Builder showed it&amp;rsquo;s face. I&amp;rsquo;m an iOS15 SwiftUI baby - I will, eventually, need to learn the old magic, but competence developing iOS apps using SwiftUI current methods is the MVP.&lt;/p&gt;
&lt;p&gt;With this understanding, and having finished lecture 4 from the cs193p series, I think a good project for today would be the simplest possible MVVM app with the correct separations and bindings.&lt;/p&gt;</description></item><item><title>Xcode Tour</title><link>https://blog.iankulin.com/xcode-tour/</link><pubDate>Sun, 24 Jul 2022 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/xcode-tour/</guid><description>&lt;p&gt;If you need a solid tour of the basics plus of Xcode, this is a great video from Karin Prater. Its the first video in her &amp;ldquo;Design-oriented course on SwiftUI&amp;rdquo;.&lt;/p&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
 &lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/EDHl1r5vw6Q?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
 &lt;/div&gt;
</description></item><item><title>Gitting Started</title><link>https://blog.iankulin.com/gitting-started/</link><pubDate>Wed, 13 Jul 2022 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/gitting-started/</guid><description>&lt;p&gt;One of my early goals was to get in the habit of using version control with Git/Github, and I&amp;rsquo;ve got that sorted out today. My source was this excellent, very clear video from &lt;a href="https://www.youtube.com/channel/UCxA99Yr6P_tZF9_BgtMGAWA"&gt;Gwen Faraday&lt;/a&gt;. I highly recommend it if you are just starting.&lt;/p&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
 &lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/RGOj5yH7evk?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
 &lt;/div&gt;

&lt;p&gt;It possibly helped that I&amp;rsquo;m also on mac, so I didn&amp;rsquo;t have to deal with the &amp;ldquo;or however that&amp;rsquo;s done on your system&amp;rdquo; type problems. Also, where things didn&amp;rsquo;t work as expected, the explanation about what was being done was clear enough that the problem was solvable. For example, the push command Gwen used was:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git push origin master
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;but GitHub had defaulted my initial branch to &amp;ldquo;main&amp;rdquo; rather than &amp;ldquo;master&amp;rdquo;. Easily fixed since she immediately explained what both of those modifiers were. The only other tiny bit of troubleshooting was that my git global config wasn&amp;rsquo;t set up, so my commit was followed by a big message pointing out that my real email address wasn&amp;rsquo;t used for the commit:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Committer: User Name &amp;lt;username@Ians-MacBook-Pro.local&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Your name and email address were configured automatically based
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;on your username and hostname. Please check that they are accurate.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;You can suppress this message by setting them explicitly. Run the
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;following command and follow the instructions in your editor to edit
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;your configuration file:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; git config --global --edit
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;After doing this, you may fix the identity used for this commit with:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; git commit --amend --reset-author
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It didn&amp;rsquo;t make any difference - the file I&amp;rsquo;d created locally pushed up to the GitHub repo just fine. When I did follow those instructions to edit the file, I suddenly needed to know how to use Vim (hint: &amp;ldquo;i&amp;rdquo; to go into insert mode for editing, then &amp;ldquo;:&amp;rdquo; for command mode and &amp;ldquo;x&amp;rdquo; to exit and save).&lt;/p&gt;
&lt;p&gt;The only real complexity in the whole process was generating the SSH key and saving that on GitHub to allow the push from your local directory up to the GitHub repository.&lt;/p&gt;
&lt;p&gt;Ignoring that, the process was:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Creating the repository via on GitHub&lt;/li&gt;
&lt;li&gt;Using &lt;code&gt;git clone&lt;/code&gt; to download the repository to the local machine and set it up for tracking in git&lt;/li&gt;
&lt;li&gt;Edit/create the files, however. Gwen used Visual Studio code, I used my tools&lt;/li&gt;
&lt;li&gt;Check status with &lt;code&gt;git status&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git add .&lt;/code&gt; to stage the new files and freshly edited files&lt;/li&gt;
&lt;li&gt;Commit those changes with &lt;code&gt;git commit -m &amp;quot;commit title&amp;quot; -m &amp;quot;description&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Then push them up to GitHub with &lt;code&gt;git push origin main&lt;/code&gt; where &amp;ldquo;main&amp;rdquo; is the branch name.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All of that was by about the 25 minute mark in the video, and is probably enough for me to go away and get some practice with. The rest covers getting an already established local git repository to GitHub, branching, forking, undoing.&lt;/p&gt;</description></item></channel></rss>