<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Code on dev.endevour</title><link>https://devendevour.iankulin.com/tags/code/</link><description>Recent content in Code on dev.endevour</description><generator>Hugo</generator><language>en-AU</language><lastBuildDate>Mon, 01 Jul 2024 00:00:00 +0000</lastBuildDate><atom:link href="https://devendevour.iankulin.com/tags/code/index.xml" rel="self" type="application/rss+xml"/><item><title>Using LLMs for coding</title><link>https://devendevour.iankulin.com/using-llms-for-coding/</link><pubDate>Mon, 01 Jul 2024 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/using-llms-for-coding/</guid><description>&lt;p&gt;&lt;a href="https://madmuseum.org/events/ghost-shell" target="_blank" rel="noopener"&gt;&lt;img src="https://devendevour.iankulin.com/images/ghost-in-the-shell_07.jpg" alt="Ghost in the Shell
© Manga Entertainment 1996
" class="img-responsive"&gt; &lt;/a&gt; &lt;/p&gt;
&lt;p&gt;This post looks at the context for some of my thinking about AI for supporting software development, and where I&amp;rsquo;ve landed on it for the time being.&lt;/p&gt;
&lt;h3 id="the-landscape"&gt;The landscape&lt;/h3&gt; &lt;p&gt;I &lt;a href="https://devendevour.iankulin.com/chatgpts-code-writing/"&gt;briefly wrote about ChatGPT&amp;rsquo;s&lt;/a&gt; coding ability at the end of 2022. The wide availability of this tool marked the beginning of what I think can fairly be described as a revolution. The controversies that have crystalised since have not dampened my amazement of this step forward in what compute can do, especially around natural language processing.&lt;/p&gt;</description></item><item><title>Copying Objects in JS</title><link>https://devendevour.iankulin.com/copying-objects-in-js/</link><pubDate>Mon, 15 Jan 2024 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/copying-objects-in-js/</guid><description>&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/nullgrim_three_ominous_mechanical_cyber_demon_sisters_asajj_ven_1eaa87e3-99a8-4c4a-9bc0-ec8fb807caad.jpg" alt="" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve paid for a month of Mosh to do his &lt;a href="https://codewithmosh.com/p/ultimate-react-part1" target="_blank" rel="noopener"&gt;React 18 course&lt;/a&gt; , and one of the things he makes a big deal about is not to go too deep with nested objects for your state. As soon as you start to update them it becomes apparent why.&lt;/p&gt;
&lt;p&gt;Because of the way state works in React, if we need to update part of an object it has to be deep copied, the changes applied to this copy, then that new copy passed back to React to replace the previous version. So, how we copy objects becomes a matter of particular interest.&lt;/p&gt;</description></item><item><title>Concurrency and channels in Go</title><link>https://devendevour.iankulin.com/concurrency-and-channels-in-go/</link><pubDate>Tue, 12 Dec 2023 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/concurrency-and-channels-in-go/</guid><description>&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/portal-logo.jpg" alt="" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;In the long ago times, I&amp;rsquo;d done several years of commercial programming before I ever had to worry about dealing with multiple things happening at the same time. Perhaps because of the rarity of this problem, doing it in traditional languages was not always elegant.&lt;/p&gt;
&lt;p&gt;In the modern world of everything happening on the network, and systems being build out of micro-services and APIs, the beginning programmer probably has to deal with this stuff in Programming 102. Luckily, modern languages have these considerations built in, and one language with a particular reputation for that is Go.&lt;/p&gt;</description></item><item><title>Clean code</title><link>https://devendevour.iankulin.com/clean-code/</link><pubDate>Fri, 09 Dec 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/clean-code/</guid><description>&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/young-woman-cleaning-a-computer-painting.jpg" alt="young woman cleaning a computer, painting - stable diffusion" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been listening to the &lt;a href="https://www.youtube.com/watch?v=YVrHPCZnC50" target="_blank" rel="noopener"&gt;latest episode of the Empower Apps&lt;/a&gt; podcast, this one with &lt;a href="https://twitter.com/Jilsco9" target="_blank" rel="noopener"&gt;Jill Scott&lt;/a&gt; talking about &amp;ldquo;Humane&amp;rdquo; development - in the sense of being humane to whoever (probably you) is going to be reading this code in the future. It helped me clarify my thoughts about a couple of things.&lt;/p&gt;
&lt;p&gt;None of these ideas are particularly new or groundbreaking, and although I think of them as my personal style, they are very common, and in Swift could be regarded as part of the culture. Some of these concepts support each other, some represent a trade off between two opposing ideas that require us to make a choice.&lt;/p&gt;</description></item><item><title>ImageRenderer()</title><link>https://devendevour.iankulin.com/imagerenderer/</link><pubDate>Thu, 08 Dec 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/imagerenderer/</guid><description>&lt;p&gt;&lt;a href="https://developer.apple.com/documentation/swiftui/imagerenderer" target="_blank" rel="noopener"&gt;ImageRenderer&lt;/a&gt; () is a SwiftUI class that creates an image from a view. You just initialize it with the view, then extract a cgImage (Core Graphics) or uiImage that can be cast to a SwiftUI Image.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll need a view to work with, so here it is; a crude version of my behaviour ticket.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-swift" data-lang="swift"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;TicketView&lt;/span&gt;: View {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; body: some View {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ZStack {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Color(.cyan)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .frame(width: &lt;span style="color:#ae81ff"&gt;300&lt;/span&gt;, height: &lt;span style="color:#ae81ff"&gt;350&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; VStack {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Text(&lt;span style="color:#e6db74"&gt;&amp;#34;Fred Bloggs&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .font(.largeTitle)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Text(&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; HStack {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Text(&lt;span style="color:#e6db74"&gt;&amp;#34;Putting rubbish in the bin&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Image(systemName: &lt;span style="color:#e6db74"&gt;&amp;#34;trash&amp;#34;&lt;/span&gt;)
&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; .foregroundColor(.purple)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Text(&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Text(&lt;span style="color:#e6db74"&gt;&amp;#34;Green Faction&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Text(&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Text(&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Text(&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;\(&lt;/span&gt;Date&lt;span style="color:#e6db74"&gt;()&lt;/span&gt;.formatted&lt;span style="color:#e6db74"&gt;())&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;)
&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; }
&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;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here it is, with a couple of buttons underneath:&lt;/p&gt;</description></item><item><title>Ticket to ride</title><link>https://devendevour.iankulin.com/ticket-to-ride/</link><pubDate>Mon, 05 Dec 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/ticket-to-ride/</guid><description>&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/superman-crashing-into-a-train-cartoon-2.jpg" alt="superman crashing into a train, cartoon - Stable Diffusion" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;A &lt;a href="https://devendevour.iankulin.com/project-based-learning/"&gt;couple of days ago&lt;/a&gt; I was lauding the learning benefits of writing your own projects over completing tutorial projects - since your own projects push your boundaries further. Of course, its also the case that the project requirements might so completely exceed your current ability that it grinds to a halt. That&amp;rsquo;s the case with my &lt;a href="https://devendevour.iankulin.com/tickets-on-myself/"&gt;behaviour ticket app&lt;/a&gt; .&lt;/p&gt;
&lt;p&gt;The part of the app for collecting the data is pretty much done and how I imagined it, but the output needs to be pretty tickets that can be printed on paper. I managed to write the ticket data to a CSV file and export that to the files app with a .fileExporter, but really what I wanted is to have one of those share screens where you can chose to AirDrop, Print etc, and for the tickets to have been rendered to a PDF or series of images to be shared. That will have to wait. I&amp;rsquo;m just up to a bit in the #100Days about writing images so I&amp;rsquo;ll push on with that for a bit and come back to my app.&lt;/p&gt;</description></item><item><title>FriendFace 61 Feedback</title><link>https://devendevour.iankulin.com/friendface-61-feedback/</link><pubDate>Sat, 26 Nov 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/friendface-61-feedback/</guid><description>&lt;p&gt;As usual after a challenge, I compare my efforts to Paul&amp;rsquo;s model solution. Just to quickly recap the app, it sucks up some data (Users who have multiple friends) and displays it. The change in this challenge was to convert it to add that data to a Core Data store so that if a future network error prevented accessing new data, it could still display the old.&lt;/p&gt;
&lt;h4 id="merge-policy"&gt;Merge Policy&lt;/h4&gt; &lt;p&gt;The first difference is that Paul adds a merge policy. A Merge policy tells Core how to deal with any constraints defined in the data model. In this app, I&amp;rsquo;d defined the CachedUser.id as a constraint. The purpose of this is that under normal conditions the app would be picking up mostly the same data each time it started up. We don&amp;rsquo;t want scabs of duplicate data, so constraining users based on their unique id is smart.&lt;/p&gt;</description></item><item><title>61 Done</title><link>https://devendevour.iankulin.com/61-done/</link><pubDate>Fri, 25 Nov 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/61-done/</guid><description>&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/green_tick.svg_.png" alt="" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;I think I&amp;rsquo;ve finally completed the minimum work for Day 61 of &lt;a href="https://www.hackingwithswift.com/100/swiftui/61" target="_blank" rel="noopener"&gt;#100DaysOfSwiftUI&lt;/a&gt; . The task was to suck up some data in JSON, decode it. back it up into a Core Data graph then display the data from the Core Data.&lt;/p&gt;
&lt;p&gt;I got stuck on dealing with the one:many relationship and had to revisit that from a different source to get my head around it, after that it was straightforward. Other small problem I ran into was that I created the id in the CachedUser as a UUID from (newly formed) habit. Then when I went to copy it in from the JSON version, it wouldn&amp;rsquo;t let me. When I realised my mistake and changed it in the data model, I still could not figure out why it wasn&amp;rsquo;t working - but of course I hadn&amp;rsquo;t regenerated the code for the ManagedObject. I just had to change the property type in the already generated code from UUID to string and I was back in business.&lt;/p&gt;</description></item><item><title>Core Data basics - Part Two</title><link>https://devendevour.iankulin.com/core-data-basics-part-two/</link><pubDate>Wed, 23 Nov 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/core-data-basics-part-two/</guid><description>&lt;p&gt;Yesterday I roughed out a master/detail app with a list of gardens, and for each garden a detail screen including some plants. It used arrays of structs for the data. Today I&amp;rsquo;m going to convert that app to use Core Data, and explain my understanding of each step. This won&amp;rsquo;t be the entire app - I&amp;rsquo;m going to include the plants in my data structure, but not actually use them in this version. I&amp;rsquo;ll save that 1:many relationship stuff for another post.&lt;/p&gt;</description></item><item><title>Core Data basics - Part One</title><link>https://devendevour.iankulin.com/core-data-basics-part-one/</link><pubDate>Tue, 22 Nov 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/core-data-basics-part-one/</guid><description>&lt;p&gt;To help me get clear on the Core Data basics (&lt;a href="https://devendevour.iankulin.com/tough-day/"&gt;so I can master one of the #100Days challenges&lt;/a&gt; ), I&amp;rsquo;ll write a simple master/detail app with arrays of structs, then convert it to Core Data listing out of the steps. Almost everything I know about Core Data, I learned from Paul Hudson&amp;rsquo;s &lt;a href="https://www.hackingwithswift.com/100/swiftui" target="_blank" rel="noopener"&gt;100 Days of SwiftUI&lt;/a&gt; course - of which I&amp;rsquo;m up to day 61. So shout out to him. I highly recommend that course, and most of the code you&amp;rsquo;ll see in this post is either inspired by, or directly copied from 100 Days, except of course the errors - those are mine. This post - Part One - just describes the app and shows the struct/array version.&lt;/p&gt;</description></item><item><title>FriendFace Feedback</title><link>https://devendevour.iankulin.com/friendface-feedback/</link><pubDate>Tue, 15 Nov 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/friendface-feedback/</guid><description>&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/screen-shot-2022-11-12-at-4.38.24-pm.jpg" alt="" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;After each app, I use my HackingWithSwift+ membership to view Paul&amp;rsquo;s version of the app as a way to judge my performance. Yesterday&amp;rsquo;s app was &amp;ldquo;&lt;a href="https://www.hackingwithswift.com/guide/ios-swiftui/5/3/challenge" target="_blank" rel="noopener"&gt;FriendFace&lt;/a&gt; &amp;rdquo; - download some JSON of a number of people (including their friends) and display it.&lt;/p&gt;
&lt;h4 id="uuid"&gt;UUID&lt;/h4&gt; &lt;p&gt;In my struct, I&amp;rsquo;d just specified the User.id as a string, Paul uses UUID - this makes no difference to the app as it stands, but is much better if we ever needed to add users.&lt;/p&gt;</description></item><item><title>FriendFace</title><link>https://devendevour.iankulin.com/friendface/</link><pubDate>Mon, 14 Nov 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/friendface/</guid><description>&lt;p&gt;The &lt;a href="https://www.hackingwithswift.com/guide/ios-swiftui/5/3/challenge" target="_blank" rel="noopener"&gt;Day 60 Milestone&lt;/a&gt; is a demo app that vacuums up some JSON and displays it in a list in a NavigationView that links to a details page. Nothing super strenuous, the steps were something like this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Download the JSON and have a look at the structure. Firefox has a simple JSON viewer built in, so it was straightforward to see this is an array of users, which along with some (mostly string) properties contains an array of tag strings, and another array of friends.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/screen-shot-2022-11-12-at-3.23.28-pm.jpg" alt="" class="img-responsive"&gt; &lt;/p&gt;</description></item><item><title>Project 12 Challenges</title><link>https://devendevour.iankulin.com/project-12-challenges/</link><pubDate>Thu, 10 Nov 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/project-12-challenges/</guid><description>&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/adelandco.jpg" alt="taylor swift with ed sheeran and adel, watercolor painting - Stable Diffusion" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;Project 12 was a series of code tutorials around developing CoreData concepts rather than a real app, but the &lt;a href="https://www.hackingwithswift.com/books/ios-swiftui/core-data-wrap-up" target="_blank" rel="noopener"&gt;challenges&lt;/a&gt; are based on a very small app that uses a subview to allow dynamic (ie changeable at runtime) filtering of a list of data. The reason this would be tricky is that the @FetchRequest is a property of a view - and therefore mutable. The trick is to have a subview to build that part of the view, and to pass parameters into it which build the fetchrequest using an underscore.&lt;/p&gt;</description></item><item><title>Bookworm Challenges</title><link>https://devendevour.iankulin.com/bookworm-challenges/</link><pubDate>Sun, 06 Nov 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/bookworm-challenges/</guid><description>&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/cartoon-worm-on-a-book.jpg" alt="cartoon worm on a book - Stable Diffusion" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;Another set of challenges for a &lt;a href="https://www.hackingwithswift.com/100/swiftui" target="_blank" rel="noopener"&gt;#100DaysofSwiftUI&lt;/a&gt; tutorial app. Project 11 was a book tracking app - the big new thing was using CoreData. Here&amp;rsquo;s the &lt;a href="https://www.hackingwithswift.com/books/ios-swiftui/bookworm-wrap-up" target="_blank" rel="noopener"&gt;challenges for it&lt;/a&gt; .&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Right now it’s possible to select no title, author, or genre for books, which causes a problem for the detail view. Please fix this, either by forcing defaults, validating the form, or showing a default picture for unknown genres – you can choose.&lt;/em&gt;&lt;/p&gt;</description></item><item><title>@Binding - data between views</title><link>https://devendevour.iankulin.com/binding-data-between-views/</link><pubDate>Sat, 05 Nov 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/binding-data-between-views/</guid><description>&lt;p&gt;In C world, if we want to pass a parameter down into a functional call, and allow the receiving function to change it&amp;rsquo;s value, we&amp;rsquo;d pass a pointer to the variable. Something like this:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;

void increment(int* b) {
 *b=*b+1;
}

int main() {
 int a = 5;
 increment(&amp;amp;a);
 printf(&amp;#34;%d&amp;#34;, a);
 return 0;
}

// prints &amp;#39;6&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For youngsters, what&amp;rsquo;s happening is that we&amp;rsquo;ve set the value of a to 5, then passed the memory &lt;em&gt;address&lt;/em&gt; of a into the increment() function. That&amp;rsquo;s what the @a means.&lt;/p&gt;</description></item><item><title>Codable &amp;amp; JSON</title><link>https://devendevour.iankulin.com/codable-json/</link><pubDate>Sun, 30 Oct 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/codable-json/</guid><description>&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/encryption-machine-comic-27970-.jpg" alt="encryption machine, comic 27970 - Stable Diffusion" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;If we mark a type with the protocol &lt;em&gt;Codable&lt;/em&gt;, we&amp;rsquo;re specifying that this type has the capability of having it&amp;rsquo;s properties encoded to some format, and decoded back again.&lt;/p&gt;
&lt;p&gt;So far in the #100Days this has been used to write and read data in UserDefaults, and to encode an object to send it as a URLRequest, then receive data back and create a new object from it. It&amp;rsquo;s a handy, powerful feature baked into Swift that just requires the developer to ensure any types that need this functionality comply with the &lt;em&gt;Encodable&lt;/em&gt; and &lt;em&gt;Decodable&lt;/em&gt; protocols that make up the Codable.&lt;/p&gt;</description></item><item><title>Day 47 - Habits App</title><link>https://devendevour.iankulin.com/day-47-habits-app/</link><pubDate>Thu, 27 Oct 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/day-47-habits-app/</guid><description>&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/tgirl-3.jpg" alt="pretty! woman holding a bag of trash, Artstation - Stable Diffusion" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been mucking around with the Habits app too long - it&amp;rsquo;s started to look like procrastination. It already meets the &lt;a href="https://www.hackingwithswift.com/100/swiftui/47" target="_blank" rel="noopener"&gt;specification&lt;/a&gt; , so I&amp;rsquo;m calling it an MVP and moving on.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/IanKulin/Habitual" target="_blank" rel="noopener"&gt;&lt;img src="https://devendevour.iankulin.com/images/github-mark-32px.png" alt="" class="img-responsive"&gt; &lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/img_3110.png" alt="" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;This is the first app of mine I&amp;rsquo;ve loaded onto my phone and started using, and there are a couple of things I&amp;rsquo;d like to do with it. It currently just lets you specify how many days between an activity repeating - so if you say you should go to the gym every second day, and you complete that activity on Monday, &amp;ldquo;Gym&amp;rdquo; will make it&amp;rsquo;s way to the top of the list on Wednesday. While it&amp;rsquo;s waiting in the list for Wednesday to come around, it will show the &amp;ldquo;Due&amp;rdquo; time as being exactly 48 hours after you last pressed &amp;ldquo;done&amp;rdquo; on it. But if the habit you want is to go to the gym after work at 6:00pm that&amp;rsquo;s when you want it to be due. I&amp;rsquo;d like that.&lt;/p&gt;</description></item><item><title>Updating stored JSON due to a struct change</title><link>https://devendevour.iankulin.com/updating-stored-json-due-to-a-struct-change/</link><pubDate>Tue, 25 Oct 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/updating-stored-json-due-to-a-struct-change/</guid><description>&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/jason-modern-art.jpg" alt="Jason Modern Art - Stable Diffusion" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;I mentioned yesterday &amp;ldquo;&lt;em&gt;I could use a renamed old version of my struct to load the existing data, and convert it across to the new model.&lt;/em&gt;&amp;rdquo;. Since I&amp;rsquo;ve been testing the app on my phone, and using plausible data, it was going to be painful enough to lose it that I thought I should go through those steps.&lt;/p&gt;
&lt;p&gt;First, I make a copy of the old struct, and renamed it with the app version number that used it. No need to bring all the computed properties into this struct, just the bits that get encoded into the JSON.&lt;/p&gt;</description></item><item><title>JSON encode/decode</title><link>https://devendevour.iankulin.com/json-encode-decode/</link><pubDate>Mon, 24 Oct 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/json-encode-decode/</guid><description>&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/img_3110.png" alt="Screenshop of Habits app" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;As usual, I&amp;rsquo;m spending way more time on the apps written from scratch in the &lt;a href="https://www.hackingwithswift.com/guide/ios-swiftui/4/3/challenge" target="_blank" rel="noopener"&gt;100Days series&lt;/a&gt; . The Habit tracking app I&amp;rsquo;m working on has been good practice, especially of the architecture of the simple &lt;a href="https://devendevour.iankulin.com/list-apps/"&gt;list based app&lt;/a&gt; .&lt;/p&gt;
&lt;p&gt;My version has a couple of refinements I quite like. I&amp;rsquo;m using a checkmark in a rectangle as the button to mark that activity as done, and I&amp;rsquo;ve added a nice fade to the checkmark as time goes on to represent the percentage of time from when it is done until it becomes due again.&lt;/p&gt;</description></item><item><title>Refreshing SwiftUI Views</title><link>https://devendevour.iankulin.com/refreshing-swiftui-views/</link><pubDate>Sun, 23 Oct 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/refreshing-swiftui-views/</guid><description>&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/refreshing-view-rococo.jpg" alt="refreshing view, Rococo - Stable Diffusion" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;SwiftUI does some property wrapper magic to (very efficiently) refresh your views, but what if you want to force a refresh for some reason? Here&amp;rsquo;s the techniques I&amp;rsquo;m currently using to do that.&lt;/p&gt;
&lt;p&gt;The tricks are below, but just so you can see them in context, here&amp;rsquo;s the sample app we&amp;rsquo;re working on. It&amp;rsquo;s a list of cars so you can keep track of how many of each kind you own. Here&amp;rsquo;s our data:&lt;/p&gt;</description></item><item><title>You need to enjoy puzzles</title><link>https://devendevour.iankulin.com/you-need-to-enjoy-puzzles/</link><pubDate>Sat, 22 Oct 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/you-need-to-enjoy-puzzles/</guid><description>&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/frustration.jpg" alt="frustrated worker, painting - Stable Diffusion" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m writing the Habits &lt;a href="https://devendevour.iankulin.com/list-apps/"&gt;list based app&lt;/a&gt; from #100Days and had a working MVP, then for some reason, decided to refactor by changing the subview I&amp;rsquo;d written as a function, into a struct. Some time later, I discovered that my list items were not updating correctly, so detective time.&lt;/p&gt;
&lt;p&gt;I talked a little bit about the architecture yesterday - the item is a struct, and there&amp;rsquo;s a class containing an array of the items. Something like this:&lt;/p&gt;</description></item><item><title>Drawing Feedback</title><link>https://devendevour.iankulin.com/drawing-feedback/</link><pubDate>Wed, 19 Oct 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/drawing-feedback/</guid><description>&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/hedylamarrstandinginfront_52901467.jpg" alt="Hedy Lamarr standing in front of a drawing, Kuvshinov Ilya - Stable Diffusion" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the summary of my learning from comparing &lt;a href="https://devendevour.iankulin.com/project-9-drawing/"&gt;my efforts&lt;/a&gt; with Paul&amp;rsquo;s solutions to the Project Nine challenges from &lt;a href="https://www.hackingwithswift.com/books/ios-swiftui/drawing-wrap-up" target="_blank" rel="noopener"&gt;Day 46&lt;/a&gt; of his &lt;a href="https://www.hackingwithswift.com/100/swiftui" target="_blank" rel="noopener"&gt;100 Days of SwiftUI course&lt;/a&gt; .&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Create an &lt;code&gt;Arrow&lt;/code&gt; shape – having it point straight up is fine. This could be a rectangle/triangle-style arrow, or perhaps three lines, or maybe something else depending on what kind of arrow you want to draw.&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Project 9 - Drawing</title><link>https://devendevour.iankulin.com/project-9-drawing/</link><pubDate>Tue, 18 Oct 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/project-9-drawing/</guid><description>&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/screen-shot-2022-10-16-at-12.17.46-pm.jpg" alt="Screenshot of Xcode and the preview showing some fancy graphics" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;These few days of &lt;a href="https://www.hackingwithswift.com/100/swiftui/43" target="_blank" rel="noopener"&gt;#100DaysOfSwiftUI&lt;/a&gt; we made some pretty shapes by playing around with some of the SwiftUI systems for drawing on the screen, including paths, shapes, transformations, ImagePaint, drawingGroup() to use Metal rendering, blurs, blend modes and using animatableData for animating - which I think is the solution to an animation problem in my TimesTable app I hadn&amp;rsquo;t been able to solve yet.&lt;/p&gt;</description></item><item><title>Moonshot Feedback</title><link>https://devendevour.iankulin.com/moonshot-feedback/</link><pubDate>Sat, 15 Oct 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/moonshot-feedback/</guid><description>&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/girl-with-a-headset-in-a-space-command-center-kuvshinov-ilya-mitsumayo.jpg" alt="Girl with a headset in a space command center, Kuvshinov Ilya, Mitsumayo - Stable Diffusion" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve watched Paul&amp;rsquo;s solution to the &lt;a href="https://www.hackingwithswift.com/books/ios-swiftui/moonshot-wrap-up" target="_blank" rel="noopener"&gt;Moonshot challenges&lt;/a&gt; (the solutions are one of the perks of being a Hacking With Swift subscriber). When I&amp;rsquo;m solo learning like this its one of the few ways I can get any feedback on my coding, so I highly value it, and usually write one of these posts as a way to ensure I reflect on it.&lt;/p&gt;</description></item><item><title>Moonshot Challenges</title><link>https://devendevour.iankulin.com/moonshot-challenges/</link><pubDate>Fri, 14 Oct 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/moonshot-challenges/</guid><description>&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/screen-shot-2022-10-09-at-2.00.26-pm.png" alt="" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;Another few coding challenges at the end of a tutorial app in the &lt;a href="https://www.hackingwithswift.com/books/ios-swiftui/moonshot-wrap-up" target="_blank" rel="noopener"&gt;100 Days of SwiftUI&lt;/a&gt; course. The app is a sort of information app - composed of navigation views going down into more detail about the Apollo space missions. The most exciting revelation for me was how straightforward it is to pull JSON into your apps data structures.&lt;/p&gt;
&lt;h4 id="challenge-1"&gt;Challenge 1&lt;/h4&gt; &lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Add the launch date to &lt;code&gt;MissionView&lt;/code&gt;, below the mission badge. You might choose to format this differently given that more space is available, but it’s down to you.&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Using Swift's map</title><link>https://devendevour.iankulin.com/using-swifts-map/</link><pubDate>Thu, 13 Oct 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/using-swifts-map/</guid><description>&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/untitled-2.jpg" alt="&amp;ldquo;map, moon, transformation&amp;rdquo; - Stable Diffusion" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;In &lt;a href="https://www.hackingwithswift.com/100/swiftui/39" target="_blank" rel="noopener"&gt;Day 39&amp;rsquo;&lt;/a&gt; s Moonshot tutorial app, Paul uses &lt;a href="https://developer.apple.com/documentation/swift/array/map%5c%28_:%5c%29-87c4d" target="_blank" rel="noopener"&gt;&lt;code&gt;.map&lt;/code&gt;&lt;/a&gt; on an array without much comment about what&amp;rsquo;s going on. I assume this might be a common concept in modern languages, but it was new to me.&lt;/p&gt;
&lt;p&gt;First, here&amp;rsquo;s Paul&amp;rsquo;s code&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-swift" data-lang="swift"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;init&lt;/span&gt;(mission: Mission, astronauts: [String: Astronaut]) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;self&lt;/span&gt;.mission = mission
&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; &lt;span style="color:#66d9ef"&gt;self&lt;/span&gt;.crew = mission.crew.map { member &lt;span style="color:#66d9ef"&gt;in&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; astronaut = astronauts[member.name] {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; CrewMember(role: member.role, astronaut: astronaut)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; fatalError(&lt;span style="color:#e6db74"&gt;&amp;#34;Missing &lt;/span&gt;&lt;span style="color:#e6db74"&gt;\(&lt;/span&gt;member.name&lt;span style="color:#e6db74"&gt;)&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;)
&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; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;Mission&lt;/code&gt; here contains an array of &lt;code&gt;crew&lt;/code&gt; which is a struct with two strings, one of them being &lt;code&gt;name&lt;/code&gt;, but &lt;code&gt;self.crew&lt;/code&gt; (which belongs to the view we&amp;rsquo;re in) is an array of &lt;code&gt;CrewMember&lt;/code&gt; which is a struct with a &lt;code&gt;role: String&lt;/code&gt; and another struct &lt;code&gt;astronaut&lt;/code&gt;. That sounds confusing, but essentially, an array of one type is being processed to return an array of another type where there&amp;rsquo;s a 1:1 relationship between the elements of each array.&lt;/p&gt;</description></item><item><title>iExpense Feedback</title><link>https://devendevour.iankulin.com/iexpense-feedback/</link><pubDate>Wed, 12 Oct 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/iexpense-feedback/</guid><description>&lt;p&gt;I finally got around to looking at Paul&amp;rsquo;s solutions for the &lt;a href="https://devendevour.iankulin.com/iexpense-challenges/"&gt;iExpense challenges&lt;/a&gt; .&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Use the user’s preferred currency, rather than always using US dollars.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Same approach as me,&lt;/p&gt;
&lt;p&gt;&lt;code&gt;.currency(code: Locale.current.currency?.identifier ?? &amp;quot;USD&amp;quot;)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;except that he does the work in a local variable which is a bit neater. Since it appears in two places - the display view and the view for adding an expense, this would mean duplicating it, making it global (not rare for user default type settings) or passing it down through the view hierarchy. I feel either of the first two options are fine for this project, but Paul is thorough and extends the FormatStyle protocol, only for currency, to have a new computed property .localcurrency - which is a great solution.&lt;/p&gt;</description></item><item><title>CodeTrimmer - First MacOS App</title><link>https://devendevour.iankulin.com/codetrimmer-first-macos-app/</link><pubDate>Thu, 06 Oct 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/codetrimmer-first-macos-app/</guid><description>&lt;p&gt;I was listening to the StackTrace app this morning (&lt;a href="https://stacktracepodcast.fm/episodes/169/" target="_blank" rel="noopener"&gt;episode 169 - &amp;ldquo;Choosing What Bugs to Ship&amp;rdquo;&lt;/a&gt; ) and one of the ideas discussed was taking the time to automate some of your development processes, partially to save time, but also because if you make a process simple and quick, you&amp;rsquo;ll be more likely to do it multiple times to improve quality.&lt;/p&gt;
&lt;p&gt;Coincidentally, I&amp;rsquo;d been thinking about how often I paste some code from Xcode in order to display it in one of these blog posts. If it&amp;rsquo;s from the middle of a method, it will generally be indented a long way in, and there&amp;rsquo;s no point in displaying it like that (especially for a mobile reader) so I usually manually delete a heap of spaces from each line to left align it whilst keeping the needed indentation.&lt;/p&gt;</description></item><item><title>Design Challenge</title><link>https://devendevour.iankulin.com/design-challenge/</link><pubDate>Wed, 05 Oct 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/design-challenge/</guid><description>&lt;p&gt;So, I&amp;rsquo;ve been working on translating the &lt;a href="https://devendevour.iankulin.com/design-help/"&gt;UI design&lt;/a&gt; created by the external designer into SwiftUI, and have done all of the easy bits:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/screen-shot-2022-10-03-at-8.19.43-am.jpg" alt="" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;The rounded rectangles for things like the question display/number input are just ZStacks of roundedrects filled, then stroked:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-swift" data-lang="swift"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ZStack {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; RoundedRectangle(cornerRadius: &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .fill(.white)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .padding(.horizontal)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; RoundedRectangle(cornerRadius: &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .stroke(.black, lineWidth: &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .padding(.horizontal)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; HStack {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Text(questionText)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .font(.title)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .fontWeight(.heavy)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Text(calculatorDisplay)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .font(.title)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .fontWeight(.heavy)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .foregroundColor(.blue)
&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;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.frame(maxWidth: &lt;span style="color:#ae81ff"&gt;350&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.offset(y: &lt;span style="color:#ae81ff"&gt;15&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Something I have learned in the process is the .offset modifer. This is what&amp;rsquo;s used to move a view from where SwiftUI would have placed it, and is what I&amp;rsquo;ve done to create that overlapped style where the question display/number input is sitting halfway over the bottom of the blue rounded rectangle. This is in the last line of the code above: &lt;code&gt;.offset(y: 15)&lt;/code&gt; This is moving the whole ZStack down by 15. A trick to watch with this is that since you&amp;rsquo;ve messed with SwiftUI&amp;rsquo;s arrangement, it doesn&amp;rsquo;t then shuffle everything else around this - you need to manually deal with making some space below it.&lt;/p&gt;</description></item><item><title>iExpense Challenges</title><link>https://devendevour.iankulin.com/iexpense-challenges/</link><pubDate>Sun, 02 Oct 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/iexpense-challenges/</guid><description>&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/screen-shot-2022-09-29-at-6.41.29-am.png" alt="" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.hackingwithswift.com/100/swiftui/38" target="_blank" rel="noopener"&gt;Day 38&lt;/a&gt; is three challenges on the iExpense app - a simple expense tracking app that uses UseDefaults for storing it&amp;rsquo;s data.&lt;/p&gt;
&lt;h3 id="locale"&gt;Locale&lt;/h3&gt; &lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Use the user’s preferred currency, rather than always using US dollars.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;One of the joys of modern programming (as opposed to mid-1990&amp;rsquo;s programming) is the ability of the internet to give you answers. I knew the answer to this would be lurking in the locale environment variable, but instead of &lt;a href="https://developer.apple.com/documentation/swiftui/environmentvalues/locale" target="_blank" rel="noopener"&gt;looking it up&lt;/a&gt; , just googled, and found a viable looking solution on &lt;a href="https://www.reddit.com/r/SwiftUI/comments/t7g7ds/localising_currency/" target="_blank" rel="noopener"&gt;Reddit&lt;/a&gt; .&lt;/p&gt;</description></item><item><title>Animating Guess The Flag</title><link>https://devendevour.iankulin.com/animating-guess-the-flag/</link><pubDate>Sat, 24 Sep 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/animating-guess-the-flag/</guid><description>&lt;p&gt;The challenges for &lt;a href="https://www.hackingwithswift.com/100/swiftui/34" target="_blank" rel="noopener"&gt;Project 6&lt;/a&gt; of 100 Days of SwiftUI was to add some animations to the &lt;a href="https://devendevour.iankulin.com/project-2-guess-the-flag/"&gt;Guess the Flag&lt;/a&gt; app from a little while ago. The animations themselves were not particularly tricky, my main issue was that I was creating the views for the three flags in a ForEach, so the animations were applied to all three flags, but we wanted different animations for the flag the user had clicked versus those they had not.&lt;/p&gt;</description></item><item><title>Animations in Views</title><link>https://devendevour.iankulin.com/animations-in-views/</link><pubDate>Fri, 23 Sep 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/animations-in-views/</guid><description>&lt;p&gt;It&amp;rsquo;s a very Apple-thinking thing to be learning about making beautiful and intuitive user experiences this early in a programing tutorial as I am with the &lt;a href="https://www.hackingwithswift.com/100/swiftui/32" target="_blank" rel="noopener"&gt;100 Days of Swift UI&lt;/a&gt; series. Here&amp;rsquo;s a quick look at three different ways of doing animation in SwiftUI Views.&lt;/p&gt;
&lt;h4 id="implicit-animation"&gt;Implicit animation&lt;/h4&gt; &lt;p&gt;An &lt;em&gt;implicit&lt;/em&gt; animation in SwiftUI is when you add a .&lt;em&gt;animation&lt;/em&gt;() modifier to a view. It needs to be bound to the value that&amp;rsquo;s changing so the framework knows to animate when that value changes, and the nature of the change.&lt;/p&gt;</description></item><item><title>Project 5 - Word Scramble</title><link>https://devendevour.iankulin.com/project-5-word-scramble/</link><pubDate>Mon, 19 Sep 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/project-5-word-scramble/</guid><description>&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/screen-shot-2022-09-17-at-4.30.14-pm.jpg" alt="" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;Another &lt;a href="https://www.hackingwithswift.com/100/swiftui" target="_blank" rel="noopener"&gt;100 Days of Swift UI&lt;/a&gt; project wrapped up - this time a scrabble like word game. New techniques included saving a large text file in the app bundle and loading it (via a string) into an array on launch of the view. Also a short adventure into UIKit to use a UITextChecker.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/IanKulin/WordScramble/compare/c64c21d..ada15e2" target="_blank" rel="noopener"&gt;Source&lt;/a&gt; .&lt;/p&gt;</description></item><item><title>Word Scramble Feedback</title><link>https://devendevour.iankulin.com/word-scramble-feedback/</link><pubDate>Mon, 19 Sep 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/word-scramble-feedback/</guid><description>&lt;p&gt;As is my practice now, after completing the &lt;a href="https://www.hackingwithswift.com/books/ios-swiftui/word-scramble-wrap-up" target="_blank" rel="noopener"&gt;challenges for Project 5&lt;/a&gt; , I reviewed Paul&amp;rsquo;s solution (which is only available to subscribers) to see what he&amp;rsquo;d done better so I could learn from it.&lt;/p&gt;
&lt;p&gt;Most of the differences where not of much significance, but there was a couple of things I picked up:&lt;/p&gt;
&lt;p&gt;When the user had pressed the reset button, to empty the array of word guesses from the previous turn, I had&lt;/p&gt;</description></item><item><title>Project 4 Challenges</title><link>https://devendevour.iankulin.com/project-4-challenges/</link><pubDate>Fri, 16 Sep 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/project-4-challenges/</guid><description>&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/screen-shot-2022-09-13-at-7.22.43-pm.png" alt="" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve completed the Project 4 challenges (source) of the 100 Days of SwiftUI, no biggie - the increase in difficulty between each step of Paul&amp;rsquo;s bootcamp is small enough that it&amp;rsquo;s never too stressful, but large enough you feel like you&amp;rsquo;re progressing all the time.&lt;/p&gt;
&lt;p&gt;Since I&amp;rsquo;ve paid to be a member of Hacking with Swift, one of the perks is to see Paul&amp;rsquo;s video solutions. I&amp;rsquo;ve not worries about it before, but I should - looking at them and comparing to my efforts is probably good feedback. So here&amp;rsquo;s the differences in our answers to the challenges.&lt;/p&gt;</description></item><item><title>Rock, Paper, Scissors (1)</title><link>https://devendevour.iankulin.com/rock-paper-scissors-1/</link><pubDate>Sat, 10 Sep 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/rock-paper-scissors-1/</guid><description>&lt;p&gt;As I mentioned yesterday, I needed to make some progress to blog about, and I had a half working version of a Rock, Paper, Scissors for &lt;a href="https://www.hackingwithswift.com/100/swiftui/25" target="_blank" rel="noopener"&gt;Day 25&lt;/a&gt; so I pushed myself to get that working.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s lots in the code below I don&amp;rsquo;t love.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The rock paper scissors could be some better data structure than an array and some ints.&lt;/li&gt;
&lt;li&gt;I don&amp;rsquo;t love the try to win, try to lose aspect, but the client specified it&lt;/li&gt;
&lt;li&gt;Having the didUserWin and didComputerWin funcs is a cop out - that should probably be a single function returning a win/lose/draw type&lt;/li&gt;
&lt;li&gt;I also am unhappy with nesting them in the view namespace to use my #consts&lt;/li&gt;
&lt;li&gt;duplicating the last part of the view but making the elements .hidden() to keep the same spacing seems like a kludge&lt;/li&gt;
&lt;li&gt;when I added the link to the Hacking With SwiftUI page with the app brief just now, I noticed I haven&amp;rsquo;t done the scoring the way it was asked for&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="https://github.com/IanKulin/RockPaper/commit/b1497cccf2dc8af953b946458af797dc5ad12dc9?diff=unified#diff-223dd39ecc4f631b084c99b065a71ea40dc2deba8e36e7f5f939802e60c80186" target="_blank" rel="noopener"&gt;source on github&lt;/a&gt; &lt;/p&gt;</description></item><item><title>.self in ForEach</title><link>https://devendevour.iankulin.com/self-in-foreach/</link><pubDate>Wed, 07 Sep 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/self-in-foreach/</guid><description>&lt;p&gt;I&amp;rsquo;m on Day 25 of Hacking With SwiftUI, and &lt;a href="https://www.hackingwithswift.com/guide/ios-swiftui/2/2/key-points" target="_blank" rel="noopener"&gt;Paul is making a point&lt;/a&gt; about how SwiftUI can loop over an array to build a view. He starts with this:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;let agents = [&amp;#34;Cyril&amp;#34;, &amp;#34;Lana&amp;#34;, &amp;#34;Pam&amp;#34;, &amp;#34;Sterling&amp;#34;]
VStack {
 ForEach(0..&amp;lt;agents.count) {
 Text(agents[$0])
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But then proposes an alternative:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;let agents = [&amp;#34;Cyril&amp;#34;, &amp;#34;Lana&amp;#34;, &amp;#34;Pam&amp;#34;, &amp;#34;Sterling&amp;#34;]
VStack {
 ForEach(agents, id: \.self) {
 Text($0)
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;He explains the use of \.self here by saying&lt;/p&gt;</description></item><item><title>Project 3</title><link>https://devendevour.iankulin.com/project-3/</link><pubDate>Mon, 05 Sep 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/project-3/</guid><description>&lt;p&gt;This one&amp;rsquo;s not really a project, just a couple of little updates to earlier work, and a code snippet.&lt;/p&gt;
&lt;h4 id="challenge-1"&gt;Challenge 1&lt;/h4&gt; &lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Go back to project 1 and use a conditional modifier to change the total amount text view to red if the user selects a 0% tip.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The first one is pretty simple - a ternary condition to make the total red if the tip is set to zero.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/screen-shot-2022-09-02-at-5.10.56-pm.png" alt="" class="img-responsive"&gt; &lt;/p&gt;</description></item><item><title>Day 23 - Views and Modifiers - Part 4</title><link>https://devendevour.iankulin.com/day-23-views-and-modifiers-part-4/</link><pubDate>Sat, 03 Sep 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/day-23-views-and-modifiers-part-4/</guid><description>&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/psm_v10_d562_the_hindoo_earth-3.jpg" alt="This image has an empty alt attribute; its file name is psm_v10_d562_the_hindoo_earth-3.jpg" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;Then the last trick for for decomposing the views, is to remember we can pass values when we init a struct. So something like this:&lt;/p&gt;
&lt;p&gt;struct ContentView: View {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var body: some View {
 VStack{
 GreenPaddedText(text: &amp;quot;Hello&amp;quot;)
 GreenPaddedText(text: &amp;quot;world&amp;quot;)
 }
}


struct GreenPaddedText: View {
 var text: String

 var body: some View {
 Text(text)
 .foregroundColor(.green)
 .padding()
 }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;</description></item><item><title>Day 23 - Views and Modifiers - Part 3</title><link>https://devendevour.iankulin.com/day-23-views-and-modifiers-part-3/</link><pubDate>Fri, 02 Sep 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/day-23-views-and-modifiers-part-3/</guid><description>&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/psm_v10_d562_the_hindoo_earth-3.jpg" alt="" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;The next part of day 23 started to make my brain hurt a bit. It&amp;rsquo;s easy to imagine that when presenting a complex screen - perhaps some data from a source as a mixture of images and text loaded from a database into a scroll-able view, that the view may start to get complex. Then it becomes good practice to decompose the views to make the code clearer, less error prone, and to avoid any unnecessary repetition.&lt;/p&gt;</description></item><item><title>Day 23 - Views and Modifiers - Part 2</title><link>https://devendevour.iankulin.com/day-23-views-and-modifiers-part-2/</link><pubDate>Thu, 01 Sep 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/day-23-views-and-modifiers-part-2/</guid><description>&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/psm_v10_d562_the_hindoo_earth-2.jpg" alt="" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;Although &amp;ldquo;immutable&amp;rdquo; the view structs can contain some control statements such as if/then and for loops. So this is quite legal, and useful.&lt;/p&gt;
&lt;p&gt;struct ContentView: View {
@State private var likesGreen = true&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var body: some View {
 if likesGreen {
 Text(&amp;quot;Hello World&amp;quot;)
 .background(.green)
 }
 else
 {
 Text(&amp;quot;Hello World&amp;quot;)
 .background(.blue)
 }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;But Paul cautions against this, saying:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.hackingwithswift.com/books/ios-swiftui/conditional-modifiers" target="_blank" rel="noopener"&gt;You can often use regular if conditions to return different views based on some state, but this actually creates more work for SwiftUI – rather than seeing one Button being used with different colors, it now sees two different Button views, and when we flip the Boolean condition it will destroy one to create the other rather than just recolor what it has.&lt;/a&gt; &lt;/p&gt;</description></item><item><title>Day 23 - Views and Modifiers - Part 1</title><link>https://devendevour.iankulin.com/day-23-views-and-modifiers-part-1/</link><pubDate>Wed, 31 Aug 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/day-23-views-and-modifiers-part-1/</guid><description>&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/psm_v10_d562_the_hindoo_earth-1.jpg" alt="" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;I found this one of the trickier days, so I&amp;rsquo;ll write it out to clear up my thinking.&lt;/p&gt;
&lt;p&gt;To draw to to screen in SwiftUI, we don&amp;rsquo;t call a command to draw on a canvas or window. Rather, a &lt;em&gt;view&lt;/em&gt; is defined as an immutable struct of type some View. Here&amp;rsquo;s the simple one from the default Xcode project.&lt;/p&gt;
&lt;p&gt;struct ContentView: View {
var body: some View {
Text(&amp;ldquo;Hello, world!&amp;rdquo;)
.padding()
}
}&lt;/p&gt;</description></item><item><title>Challenge 1</title><link>https://devendevour.iankulin.com/challenge-1/</link><pubDate>Mon, 29 Aug 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/challenge-1/</guid><description>&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/screen-shot-2022-08-22-at-8.54.26-am.jpg" alt="" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m up to Challenge 1 of 100 Days of SwiftUI (&lt;a href="https://www.hackingwithswift.com/100/swiftui/19" target="_blank" rel="noopener"&gt;Day 19&lt;/a&gt; ) which is to make your own simple (no MVVM) version of the app built in the previous three days. It&amp;rsquo;s about as simple as can be whilst still feeling like a real app. Something I hadn&amp;rsquo;t done before was limiting the keyboard to numbers or adding a toolbar to close it, so that was nice.&lt;/p&gt;
&lt;p&gt;Something that&amp;rsquo;s not nice, is that when you touch into the text field to change the number, it&amp;rsquo;s not selected ready to type over (the way they always are in browser url fields) so you need to backspace over the previous entry. That&amp;rsquo;s the sort of anoying behaviour I don&amp;rsquo;t like. It seems (after some googling) there&amp;rsquo;s no straightforward way of addressing this in SwiftUI, with the best solution involving importing a package. I will come back to that because it is bugging me.&lt;/p&gt;</description></item><item><title>Codewars / reduce</title><link>https://devendevour.iankulin.com/codewars-reduce/</link><pubDate>Wed, 24 Aug 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/codewars-reduce/</guid><description>&lt;p&gt;&lt;a href="https://www.codewars.com/" target="_blank" rel="noopener"&gt;&lt;img src="https://devendevour.iankulin.com/images/1_0plbhkaulwnsx4u2mqyn2w.png" alt="" class="img-responsive"&gt; &lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.codewars.com/" target="_blank" rel="noopener"&gt;codewars.com&lt;/a&gt; is a &amp;ldquo;coding practice&amp;rdquo; website. You chose a language and a skill level, then it offers up a task (or &lt;em&gt;kata&lt;/em&gt;) for you to write a suitable function. The first one it gave me was seemed too hard, so I changed my level to beginner and skipped to the next one. This was my task:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; Given an array of integers, find the one that appears an odd number of times.
 
 There will always be only one integer that appears an odd number of times.
 
 Examples
 [7] should return 7, because it occurs 1 time (which is odd).
 [0] should return 0, because it occurs 1 time (which is odd).
 [1,1,2] should return 2, because it occurs 1 time (which is odd).
 [0,1,0,1,0] should return 0, because it occurs 3 times (which is odd).
 [1,2,2,3,3,3,4,3,3,3,2,2,1] should return 4, because it appears 1 time (which is odd).
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I know there&amp;rsquo;s a cool &amp;ldquo;Set&amp;rdquo; container type in Swift, so my plan was to iterate through the array, then for each number if there&amp;rsquo;s no entry in the set, then add one, but if there is, remove it. That way whatever is left in the set at the end must be in the original array an odd number of times. I was pretty pleased with myself. Here&amp;rsquo;s the code I Playground&amp;rsquo;d up:&lt;/p&gt;</description></item><item><title>Named Loops</title><link>https://devendevour.iankulin.com/named-loops/</link><pubDate>Sun, 21 Aug 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/named-loops/</guid><description>&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/img_2768.png" alt="" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;Here’s a neat thing I haven’t seen before. Other languages I’ve worked in haven’t had a neat way to break out of a set of nested loops to a particular loop. It’s not an issue that comes up a lot, but when it has I’ve solved it by creating a continue flag and having that as the first condition of each loop.&lt;/p&gt;
&lt;p&gt;To explain, say if we had these two loops (in C):&lt;/p&gt;</description></item><item><title>Checkpoint 9</title><link>https://devendevour.iankulin.com/checkpoint-9/</link><pubDate>Sat, 20 Aug 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/checkpoint-9/</guid><description>&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/-JmAbcISEmY?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;/*
Your challenge is this: write a function that accepts an
optional array of integers, and returns one randomly.
If the array is missing or empty, return a random number
in the range 1 through 100.&lt;/p&gt;
&lt;p&gt;If that sounds easy, it’s because I haven’t explained
the catch yet: I want you to write your function in a
single line of code. No, that doesn’t mean you should
just write lots of code then remove all the line breaks
– you should be able to write this whole thing in one
line of code.&lt;/p&gt;</description></item><item><title>Checkpoint 8</title><link>https://devendevour.iankulin.com/checkpoint-8/</link><pubDate>Wed, 17 Aug 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/checkpoint-8/</guid><description>&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/Ga800-Qgft4?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;/*
Your challenge is this: make a protocol that describes a
building, adding various properties and methods, then
create two structs, House and Office, that conform to it.&lt;/p&gt;
&lt;p&gt;Your protocol should require the following:
A property storing how many rooms it has.
A property storing the cost as an integer
(e.g. 500,000 for a building costing $500,000.)
A property storing the name of the estate agent
responsible for selling the building.
A method for printing the sales summary of the building,
describing what it is along with its other properties.&lt;/p&gt;</description></item><item><title>Protocols</title><link>https://devendevour.iankulin.com/protocols/</link><pubDate>Tue, 16 Aug 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/protocols/</guid><description>&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/protocoldroid-swe.jpg" alt="" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;The evolution of structs into class-like things that can hold properties &lt;em&gt;and&lt;/em&gt; methods in Swift raised in my mind &amp;ldquo;what about inheritance?&amp;rdquo; - but no: structs in Swift can not use inheritance.&lt;/p&gt;
&lt;p&gt;Swift classes implement inheritance, but only from one class; there&amp;rsquo;s no multiple inheritance. Protocols neatly address both these concerns to a large extent, but perhaps before we look at how they work, we should have a brief diversion into inheritance in C++.&lt;/p&gt;</description></item><item><title>Checkpoint 7</title><link>https://devendevour.iankulin.com/checkpoint-7/</link><pubDate>Mon, 15 Aug 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/checkpoint-7/</guid><description>&lt;p&gt;&lt;a href="https://www.hackingwithswift.com/quick-start/beginners/checkpoint-7" target="_blank" rel="noopener"&gt;&lt;img src="https://devendevour.iankulin.com/images/screen-shot-2022-08-08-at-8.43.44-pm.jpg" alt="" class="img-responsive"&gt; &lt;/a&gt; &lt;/p&gt;
&lt;p&gt;/*
Your challenge is this: make a class hierarchy
for animals, starting with Animal at the top,
then Dog and Cat as subclasses, then Corgi and
Poodle as subclasses of Dog, and Persian and Lion
as subclasses of Cat.&lt;/p&gt;
&lt;p&gt;But there’s more:
The Animal class should have a legs integer
property that tracks how many legs the animal has.
The Dog class should have a speak() method that
prints a generic dog barking string, but each of
the subclasses should print something slightly
different.
The Cat class should have a matching speak() method,
again with each subclass printing something
different.
The Cat class should have an isTame Boolean property,
provided using an initializer.&lt;/p&gt;</description></item><item><title>Simple MVVM</title><link>https://devendevour.iankulin.com/simple-mvvm/</link><pubDate>Thu, 11 Aug 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/simple-mvvm/</guid><description>&lt;p&gt;MVVM (Model-View-View Model) is an architectural pattern for apps that separates the data (Model) from the user interface (View). The communication between these two parts is facilitated by a View Model.&lt;/p&gt;
&lt;p&gt;Model &amp;lt;-&amp;gt; View Model &amp;lt;-&amp;gt; View&lt;/p&gt;
&lt;h3 id="model"&gt;Model&lt;/h3&gt; &lt;p&gt;The &lt;em&gt;Model&lt;/em&gt; is platform independent - we should be able to pluck it out and add it to a different application running on a different platform without any trouble. Any business rules will be part of the Model along with the data. For example, if it&amp;rsquo;s a rule that every customer has a sales contact, this can be enforced in the Model.&lt;/p&gt;</description></item><item><title>Memorise Assignment 1</title><link>https://devendevour.iankulin.com/memorise-assignment-1/</link><pubDate>Thu, 28 Jul 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/memorise-assignment-1/</guid><description>&lt;p&gt;&lt;img src="https://devendevour.iankulin.com/images/screen-shot-2022-07-23-at-7.33.03-pm.jpg" alt="" class="img-responsive"&gt; &lt;/p&gt;
&lt;p&gt;A small milestone achieved - I&amp;rsquo;ve completed the first assignment from the CS193p lecture series - some minor changes to the app being built in the lectures. There was a couple of things I was unhappy with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The text under the SF Symbols you can see in the preview above not being vertically aligned.&lt;/li&gt;
&lt;li&gt;Having duplicated code in my emoji arrays:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; let animalEmojis = [&amp;#34;🐠&amp;#34;, &amp;#34;🐢&amp;#34;, &amp;#34;🦋&amp;#34;, &amp;#34;🐥&amp;#34;, &amp;#34;🐣&amp;#34;, &amp;#34;🐰&amp;#34;, &amp;#34;🐝&amp;#34;, &amp;#34;🦄&amp;#34;, &amp;#34;🐵&amp;#34;, &amp;#34;🐛&amp;#34;]
 let weatherEmojis = [&amp;#34;🌪&amp;#34;, &amp;#34;🌝&amp;#34;, &amp;#34;🌈&amp;#34;, &amp;#34;🔥&amp;#34;, &amp;#34;🌧&amp;#34;, &amp;#34;🌙&amp;#34;, &amp;#34;🌬&amp;#34;, &amp;#34;☃️&amp;#34;, &amp;#34;☔️&amp;#34;, &amp;#34;🌫&amp;#34;]
 let transportEmojis = [&amp;#34;🚗&amp;#34;, &amp;#34;🚕&amp;#34;, &amp;#34;🚲&amp;#34;, &amp;#34;🚚&amp;#34;, &amp;#34;🛵&amp;#34;, &amp;#34;🚜&amp;#34;, &amp;#34;🛴&amp;#34;, &amp;#34;🛺&amp;#34;, &amp;#34;🚃&amp;#34;, &amp;#34;🚡&amp;#34;]

 // I&amp;#39;m not happy with this duplication //TODO
 @State var emojis = [&amp;#34;🐠&amp;#34;, &amp;#34;🐢&amp;#34;, &amp;#34;🦋&amp;#34;, &amp;#34;🐥&amp;#34;, &amp;#34;🐣&amp;#34;, &amp;#34;🐰&amp;#34;, &amp;#34;🐝&amp;#34;, &amp;#34;🦄&amp;#34;, &amp;#34;🐵&amp;#34;, &amp;#34;🐛&amp;#34;]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This second problem is because I couldn&amp;rsquo;t just&lt;/p&gt;</description></item><item><title>Checkpoint 6</title><link>https://devendevour.iankulin.com/checkpoint-6/</link><pubDate>Sat, 23 Jul 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/checkpoint-6/</guid><description>&lt;pre tabindex="0"&gt;&lt;code&gt;/*
create a struct to store information about a car, including its model, number of seats, and current gear, then add a method to change gears up or down. Have a think about variables and access control: what data should be a variable rather than a constant, and what data should be exposed publicly? Should the gear-changing method validate its input somehow?
*/

struct Car {
 static let maxGear = 10
 static let minGear = 1
 var model = &amp;#34;no model&amp;#34;
 var seats = 4
 private (set) var currentGear = Car.minGear
 
 init (model: String, seats: Int) {
 self.model = model
 self.seats = seats
 }
 
 mutating func gearUp() {
 if currentGear &amp;lt; Car.maxGear{
 currentGear += 1
 }
 }
 
 mutating func gearDown() {
 if currentGear &amp;gt; Car.minGear{
 currentGear -= 1
 }
 }
 
}

var myUte = Car(model: &amp;#34;Rodeo&amp;#34;, seats:2)
print(&amp;#34;My \(myUte.model) has \(myUte.seats) seats and is in gear: \(myUte.currentGear)&amp;#34;)
myUte.gearDown()
print(&amp;#34;My \(myUte.model) has \(myUte.seats) seats and is in gear: \(myUte.currentGear)&amp;#34;)
myUte.gearUp()
print(&amp;#34;My \(myUte.model) has \(myUte.seats) seats and is in gear: \(myUte.currentGear)&amp;#34;)
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Checkpoint 5</title><link>https://devendevour.iankulin.com/checkpoint-5/</link><pubDate>Sat, 16 Jul 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/checkpoint-5/</guid><description>&lt;pre tabindex="0"&gt;&lt;code&gt;/*
 Your input is this:
 
 let luckyNumbers = [7, 4, 38, 21, 16, 15, 12, 33, 31, 49]
 
 Your job is to:
 
 Filter out any numbers that are even
 Sort the array in ascending order
 Map them to strings in the format “7 is a lucky number”
 Print the resulting array, one item per line
 
 So, your output should be as follows:
 
 7 is a lucky number
 15 is a lucky number
 21 is a lucky number
 31 is a lucky number
 33 is a lucky number
 49 is a lucky number
 */

let luckyNumbers = [7, 4, 38, 21, 16, 15, 12, 33, 31, 49]

func isNumberOdd(number:Int) -&amp;gt; Bool {
 return number%2 == 1
}

let filteredNumbers = luckyNumbers.filter(isNumberOdd)

// this closure effectively does nothing
let sortedNumbers = filteredNumbers.sorted(by: {$0&amp;lt;$1}) 

let mappedNumbers = sortedNumbers.map({ String($0)+&amp;#34; is a lucky number&amp;#34; })

for i in 0..&amp;lt;mappedNumbers.count {
 print(mappedNumbers[i])
}
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Learning Retention</title><link>https://devendevour.iankulin.com/learning-retention/</link><pubDate>Thu, 14 Jul 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/learning-retention/</guid><description>&lt;p&gt;In order to have something to put up on GitHub (as part of working all that out) I went back to re-write the Checkpoint 2 code that I&amp;rsquo;d written, but not saved, three or four days ago.&lt;/p&gt;
&lt;p&gt;The task was to count the unique elements in an array. The teaching had been about the complex data types, so clearly the hint was to cast the array to a set. Although the idea of sets is new to me this year, I&amp;rsquo;ve come across them twice. Once in the 100 days course (the same day as having to write this code) and once from a few days earlier from a &lt;a href="https://firesideswift.fireside.fm/157" target="_blank" rel="noopener"&gt;podcast episode&lt;/a&gt; . This is high quality learning - getting the same topic a couple of different ways a few days apart, then having to use the information for real.&lt;/p&gt;</description></item><item><title>Checkpoint 4</title><link>https://devendevour.iankulin.com/checkpoint-4/</link><pubDate>Wed, 13 Jul 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/checkpoint-4/</guid><description>&lt;pre tabindex="0"&gt;&lt;code&gt;/*
 The challenge is this: write a function that accepts an integer from 1 through 10,000, and returns the integer square root of that number. That sounds easy, but there are some catches:
 
 You can’t use Swift’s built-in sqrt() function or similar – you need to find the square root yourself.
 If the number is less than 1 or greater than 10,000 you should throw an “out of bounds” error.
 You should only consider integer square roots – don’t worry about the square root of 3 being 1.732, for example.
 If you can’t find the square root, throw a “no root” error.
 */

enum IntSqrtError: Error {
 case low, high, noIntRoot
}

func calculateIntSqrt(_ number:Int) throws -&amp;gt; Int {
 let lowerBound = 1
 let upperBound = 10_000
 if number &amp;lt; lowerBound {throw IntSqrtError.low}
 if number &amp;gt; upperBound {throw IntSqrtError.high}
 // brute force sqrt finder
 for i in lowerBound...number {
 if i*i == number {
 return i
 }
 }
 // none found or we would have returned by now
 throw IntSqrtError.noIntRoot
}

do {
 try print(calculateIntSqrt(5929))
} catch IntSqrtError.low {
 print(&amp;#34;Lower bound error&amp;#34;)
} catch IntSqrtError.high {
 print(&amp;#34;Upper bound error&amp;#34;)
} catch IntSqrtError.noIntRoot {
 print(&amp;#34;No integer root&amp;#34;)
} catch {
 assert(false)
 print(&amp;#34;Unknown error&amp;#34;)
}
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Checkpoint 4 optimisation</title><link>https://devendevour.iankulin.com/checkpoint-4-optimisation/</link><pubDate>Wed, 13 Jul 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/checkpoint-4-optimisation/</guid><description>&lt;p&gt;The &lt;a href="https://www.hackingwithswift.com/quick-start/beginners/checkpoint-4" target="_blank" rel="noopener"&gt;Checkpoint 4&lt;/a&gt; task was to find an integer square root of numbers up to 10000. My &lt;a href="https://devendevour.iankulin.com/checkpoint-4/"&gt;first pass solution&lt;/a&gt; was:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;func calculateIntSqrt(_ number:Int) throws -&amp;gt; Int {
 let lowerBound = 1
 let upperBound = 10_000
 if number &amp;lt; lowerBound {throw IntSqrtError.low}
 if number &amp;gt; upperBound {throw IntSqrtError.high}
 // brute force sqrt finder
 for i in lowerBound...number {
 if i*i == number {
 return i
 }
 }
 // none found or we would have returned by now
 throw IntSqrtError.noIntRoot
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Although not coded for speed, there are a couple of subtle optimisations here; the first is that it gives up once it gets to the number instead of going up to the end (it assumes the square root of a number can&amp;rsquo;t be greater than the number), and the second is that it counts up from the bottom rather than down from the top - I&amp;rsquo;m assuming the bottom of the range is richer in square roots than the top.&lt;/p&gt;</description></item><item><title>Checkpoint 3</title><link>https://devendevour.iankulin.com/checkpoint-2/</link><pubDate>Fri, 08 Jul 2022 00:00:00 +0000</pubDate><guid>https://devendevour.iankulin.com/checkpoint-2/</guid><description>&lt;pre tabindex="0"&gt;&lt;code&gt; /*
 If it’s a multiple of 3, print “Fizz”
 If it’s a multiple of 5, print “Buzz”
 If it’s a multiple of 3 and 5, print “FizzBuzz”
 Otherwise, just print the number.
 */

for i in 1...100 {

 let isMultOfThree = (i % 3 == 0)
 let isMultOfFive = (i % 5 == 0)

 if (isMultOfFive &amp;amp;&amp;amp; isMultOfThree) {
 print(&amp;#34;FizzBuzz&amp;#34;)
 } else if isMultOfThree {
 print(&amp;#34;Fizz&amp;#34;)
 } else if isMultOfFive {
 print(&amp;#34;Buzz&amp;#34;)
 } else {
 print(i)
 }
}
&lt;/code&gt;&lt;/pre&gt;</description></item></channel></rss>