<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Lukas Smetana on Medium]]></title>
        <description><![CDATA[Stories by Lukas Smetana on Medium]]></description>
        <link>https://medium.com/@lukas-smetana-ls?source=rss-766974ace25------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*Y5b8Upi49LB_ietJ33pEsA.png</url>
            <title>Stories by Lukas Smetana on Medium</title>
            <link>https://medium.com/@lukas-smetana-ls?source=rss-766974ace25------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 28 May 2026 03:03:38 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@lukas-smetana-ls/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Why Use Native UI Test Automation for Mobile Apps?]]></title>
            <link>https://lukas-smetana-ls.medium.com/why-use-native-ui-test-automation-for-mobile-apps-df140b0f3117?source=rss-766974ace25------2</link>
            <guid isPermaLink="false">https://medium.com/p/df140b0f3117</guid>
            <dc:creator><![CDATA[Lukas Smetana]]></dc:creator>
            <pubDate>Thu, 09 Jun 2022 09:58:37 GMT</pubDate>
            <atom:updated>2022-06-09T10:01:18.246Z</atom:updated>
            <content:encoded><![CDATA[<p>For us at STRV, one of the great things about switching between projects and not inheriting a tech stack is that we have the chance to try new approaches quite often. Especially in the Quality Assurance (QA) team, we are rarely forced to use specific tools or tech stacks. So as a QA analyst, whenever I get an opportunity to experiment with alternative approaches in the field of mobile test automation, I never hesitate.</p><p>Which leads me to the topic at hand, one where I believe we can help. When it comes to mobile test automation, it all starts with one simple decision. Native framework or third-party tools?</p><p>What does that mean? As leading mobile platforms, iOS and Android — and their creators, Apple and Google — offer a tool for mobile UI test automation (as well as for unit tests). For Android, the tool is called Espresso; for iOS, it’s XCUITest. On the other hand, we have representatives of open source: third-party solutions like Appium or Calabash, both of which have become QA industry standards for many reasons.</p><p>Back to the decision of native vs. third-party. If you’re stuck in a position of uncertainty, the information and examples below should help.</p><h3>Why Third-Party (Appium)</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*W4SDtm15MfCgPVC1Gk6SDQ.png" /></figure><p><em>We’re using Appium as the third-party example because this solution has been most frequently used at STRV.</em></p><p>In short, the benefits are:</p><ul><li>It is the current QA industry standard.</li><li>Allows for cross-platform tests.</li><li>It comes with a big community and tons of learning materials.</li></ul><p>According to many resources, Appium is the QA community’s favorite tool when it comes to mobile test automation. To see for yourself, try searching for Appium and then for XCUITest on <a href="https://www.udemy.com/">Udemy</a>. There are a few reasons for this popularity.</p><p>Firstly, Appium is the indirect follower of Selenium — Appium’s older, more mature brother. Both of these tools rely on the WebDriver API. Today, Selenium is still the no.1 used tool for web test automation, so it’s no surprise that QA analysts who had been using this tool adopted Appium when the mobile test automation trend started.</p><p>The second reason is that Appium provides the ability to write one test scenario that is executable on both Android and iOS. This is supposed to save QA analysts time when writing test cases. But the reality is often not as sweet as it may look. Only a small percentage of apps are truly identical on iOS and Android. More often than not, QA analysts must write up a lot of exceptions for the tests in order to run on both platforms. So whether or not the time saving benefit actually applies is arguable.</p><p>What I personally see as a big advantage of Appium is its community and how many learning materials are out there on the Internet. This is obviously great for the teams in which QA is not closely integrated with the developers; the community support allows QA analysts to solve a lot of the struggles and issues they come across before and during test automation, in both the earlier and advanced phases.</p><h3>Why Native</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/250/1*qT3jJ9M-96QBseXLGOm0cw.png" /></figure><p>After reading the section above, you might be wondering why anyone would decide to take an approach other than Appium? After all, it’s been established as the industry standard, it has a solid QA fanbase and there is a solid chance that your new QA hire will know the basic principles because he/she already knows Selenium. These are my thoughts:</p><ul><li>Native is much faster and more reliable.</li><li>It allows QA analysts to use the same tech stack and language as developers.</li><li>It provides better overall collaboration with app developers.</li><li>The test code is a part of the source code (in the same repository).</li><li>It is easier to integrate with CI/CD.</li></ul><p>Running the test in native tools like XCUITest and Espresso is much faster than running them in Appium. On top of that, tests in native tools are much less flaky. The reason is that Appium is actually running on XCUITest and Espresso frameworks under the hood. And the extra layer of code — which is meant to allow you to run one test on both platforms — is actually slowing down the test execution and sometimes making tests fail for no obvious reason.</p><p>It is true that you can use many languages to work with Appium, such as Ruby, Python, JavaScript, PHP or C#. But is this what your team needs? Wouldn’t it be better if QA analysts used the same language as developers? Especially in agile teams, this is very important and crucial when it comes to the cooperation between QA and devs — which is why I see the fact that XCUITest only uses Swift, and that Espresso only uses Kotlin, as a big advantage. Can you imagine an iOS developer helping a QA analyst fix his tests written in Java or Python? A QA analyst having a different tech stack than developers is immediately anti-agile.</p><p>Because XCUITest can be run with command-line tools such as xcodebuild, you can easily plug these tests into your CI pipeline. There is no need to build a separate app or separate app structure for the UI tests, since they run with your existing app in the same way as unit tests.</p><h3>Example: XCUITest on a Real Project</h3><pre>class LoginUITest: UITestBase {<br>    func testLogIn () {<br>        givenAppIsLaunched()<br>        whenUserSignsIn()<br>        thenUserIsSignedInAndLogsOut()<br>    }<br>    func testLogInWithNonExistingAccount() {<br>        givenAppIsLaunched()<br>        whenUserSignsInWithNonExistingAccount()<br>        thenUserNavigatesToOnboarding()<br>    }<br>    func testRegister() {<br>        givenAppIsLaunched()<br>        whenUserCreatesNewAccount()<br>        whenNewUserIsCreated()<br>        thenUserLogsOut()<br>    }</pre><p>Tests consist of reusable steps. The main idea of that is to be able to reuse some parts of the test in a different test. All of the tests are isolated, meaning that they don’t depend on each other. Inside of the test, there are specific instructions which are executed.</p><pre>func whenUserSignsIn() {<br>        XCTContext.runActivity(named: &quot;When user signs in&quot;) { _ in<br>            Onboarding.getStarted.element.tap()<br>            Onboarding.loginButton.element.tap()<br>            Onboarding.topTextField.element.tap()<br>            Onboarding.topTextField.element.typeText(&quot;<a href="mailto:lukas.smetana@strv.com">lukas.smetana@strv.com</a>&quot;)<br>            Onboarding.bottomTextField.element.tap()<br>            Onboarding.bottomTextField.element.typeText(&quot;TestPW1&quot;)<br>            Onboarding.continueButton.element.tap()<br>            cancelNotificationScreen()<br>        }<br>    }</pre><p>XCUITest also allows using XCTContext, which improves reporting and allows anyone to see exactly where the test failed in the report.</p><h3>So, Should You Use Native Frameworks for Test Automation?</h3><p>Test automation is inevitable on large and long-term projects. Manual testing can be highly effective on smaller projects and at a smaller scale but, as the project grows, manual testing gets very time-consuming and therefore costly.</p><p>The best thing about automated tests in XCUITest is that everyone can run them — developer, product owner and anyone on the client-side. This allows every stakeholder to have a real-time idea of the current application state.</p><p>There is no right or wrong answer when it comes to which automation framework you should choose. These are just ideas and thoughts based on the QA experience we’ve had at STRV. While there are teams that choose to select one framework, there are many teams that will combine two. So, whether you should use Espresso, XCUITest and/or Appium depends on your needs. Make sure to really understand what your project requires, discuss with experts if needed and go from there.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=df140b0f3117" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to Become an iOS Engineer in 2023]]></title>
            <link>https://lukas-smetana-ls.medium.com/how-to-become-an-ios-engineer-in-2022-9d86df2189ac?source=rss-766974ace25------2</link>
            <guid isPermaLink="false">https://medium.com/p/9d86df2189ac</guid>
            <category><![CDATA[swiftui]]></category>
            <category><![CDATA[ios-app-development]]></category>
            <category><![CDATA[apple]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[ios]]></category>
            <dc:creator><![CDATA[Lukas Smetana]]></dc:creator>
            <pubDate>Wed, 08 Jun 2022 16:48:40 GMT</pubDate>
            <atom:updated>2022-12-12T08:38:22.610Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*c4La_Yq1KUtrNCoMLGS-og.png" /></figure><p>If you Google “How to become an iOS engineer,” you’ll find hundreds of resources of all kinds. Videos, articles, offline gatherings, boot camps. Some are very technical, some are more superficial but motivational, some are personal and others are just empty marketing phrases selling you some super expensive courses. So, why another article?</p><p>When I started my iOS journey, these resources helped and motivated me to read or watch stories of other human beings struggling with a similar set of obstacles and problems, and overcoming them. And that’s exactly why I decided to put this little article together.</p><h3>Disclaimer: Learning Resource Paralysis</h3><p>An important disclaimer that I want to emphasize at the very beginning is that as with every other “How to become” piece of content, this article is strongly subjective and might not apply to everyone. The fact that you may take a different approach to your learning doesn’t mean you are doing something wrong.</p><p>I have an urge to highlight this because, from my experience, beginner engineers often struggle with decision paralysis from all the learning materials and resources that are available, and that causes them to never start deep learning of a given subject. So, again: <strong>If you haven’t taken a single course or used a single resource I mention here, it’s okay. </strong>There are almost endless opportunities.</p><h3>Is It a Good Idea to Learn iOS Development in 2023?</h3><p>Let’s start from a different angle. <strong>Does it still make sense to start with iOS development in 2023?</strong> The same question occurred to me in 2019 when I was beginning my iOS journey. I came across a few videos and articles questioning whether it makes sense to learn native mobile development in the age of emerging cross-platform solutions like React Native or Flutter.</p><p>Nobody wants to spend months of hard work on studying and learning a platform that is in decline, right? Other thoughts might be whether you should choose to learn something completely different, cool and trendy, something like VR development, blockchain engineering, etc. <strong>Shouldn’t you be worried about a future in which mobile devices are replaced by augmented reality wearables?</strong></p><p>These are all good questions. The truth is that mobile development is really already a standard software development branch and was new (and trendy) 10 years ago. I also don’t know what the future holds and what big tech companies are working on in secret. But I do have some ideas and key points that might calm you down.</p><ol><li><strong>Cross-platform apps won’t replace native iOS apps.</strong> They have their place on the market. In some cases, it is the right decision to go with cross-platform apps. But that doesn’t mean that the majority of mobile apps won’t still be native. Dig deeper into cross-platform vs. native with this <a href="https://www.youtube.com/watch?v=UsUriZLCwws">video</a>.</li><li><strong>Humankind is not giving up on phones yet.</strong> Apps aren’t going anywhere anytime soon.</li><li><strong>Even if mobile usage/mobile apps start to decline, the good thing is that you’re already in the software development world</strong> and can transform to backend, web frontend or any of the currently trending branches easier than before. Has Apple finally released the long-awaited AR glasses? Great, you can immediately start with ARKit, and the transition will be easier because you already know Apple’s ecosystem. You can also develop for Apple Watch, CarPlay and, potentially, any other device produced by Apple. And we can be sure that Apple won’t let any (hype) train leave without being aboard.</li></ol><h3>Is a Computer Science Background Needed?</h3><p>Alright, let’s stop with the philosophical musings about the future of mobile and, instead, focus on the learning path itself. For me, in the beginning, another important question was whether I need to have a proper computer science background. The quick answer is: <strong>No, you don’t need a computer science degree to become an iOS engineer,</strong> <em>but</em> I strongly believe that at least some basic CS knowledge is very helpful. For that, I recommend an amazing course by Harvard CS50’s <a href="https://www.edx.org/course/introduction-computer-science-harvardx-cs50x">Introduction to Computer Science</a>.</p><p>CS50 is amazing for multiple reasons. The main one for me is Professor David J. Malan because he’s just a great teacher who can explain every topic interactively and excitingly. <strong>The course itself is about general CS concepts, algorithms and data structures.</strong> You will use the programming languages C and Python to solve various tasks, such as ordering an array of elements without out-of-the-box functions, updating the RGB schema of every single pixel in the photo to apply an Instagram-like filter and much more.</p><p>The syllabus is slightly changed/updated every year. When I was doing CS50 in 2019, the last week of the course was dedicated to iOS development. It seems that, for this year, there is no major part of the course focused on that — but I still highly recommend it.</p><h3>UIKit or SwiftUI</h3><p>Apple offers engineers multiple ways to build iOS apps. For the UI frameworks, engineers choose whether they build their app with older and more robust UIKit or newer, trendy but, in some cases, not finished SwiftUI. This article is not meant to describe their differences, pros and cons. <strong>I want to try to help with deciding on whether you should start learning the older UIKit or jump right into SwiftUI.</strong></p><p>Many students might think that newer is better. Isn’t the newer SwiftUI the future? I think it is. But is it a strong enough argument to skip learning UIKit? I don’t think so. Even though you can find iOS beginner courses and boot camps entirely taught in SwiftUI, I still think it’s better to start with the “old” way of developing an iOS app — and that’s UIKit. Why? Simply because the chance of working with UIKit code this year, and next year, and even the year after is still pretty high.</p><p>Maybe you will join a startup company that started developing their app entirely with SwiftUI but chances are that, <strong>as a junior iOS engineer, you will work on an already-marketed app that will very probably be written with UIKit. </strong>Companies usually don’t decide to rewrite their whole app just because a new technology was released to the market. From my personal experience with the project I am working on right now, SwiftUI is not yet fully ready to be the only UI framework for complex production apps. So we use both SwiftUI and UIKit within one project.</p><p>I took the approach of starting with UIKit and then moving to SwiftUI, and I don’t regret it. Even though I do work mainly with SwiftUI nowadays, <strong>the base knowledge of the UIKit framework is crucial for my work.</strong> And truth to be told, I think that once you’re familiar with UIKit, the learning time needed for SwiftUI will be much shorter. <strong>It’s not the fastest way of learning iOS development but, in my opinion, it’s the right one.</strong></p><h3>Getting Into the iOS World</h3><p>Okay, so you passed your CS intro class (or not) and are now ready to jump into the iOS world. <strong>There are two resources I would recommend for this phase.</strong></p><ul><li><a href="https://www.udemy.com/course/ios-13-app-development-bootcamp/">Complete iOS App Development Bootcamp</a>, by Dr. Angela Yu</li><li><a href="https://www.hackingwithswift.com/100">100 Days of Swift</a>, by Paul Hudson</li></ul><p>Let’s talk about them a bit more in detail. <strong>The Complete iOS App Development Bootcamp and its creator, Dr. Angela Yu, is probably the course and person that were mentioned every time</strong> I was talking to junior engineers or someone who was just learning iOS. With over 74k ratings and 4.8 stars on Udemy, it’s easily one of the most popular courses.</p><p>Dr. Angela does a very good job of introducing you to the world of iOS development from the very beginning. But her course is not just full of technical stuff; she also adds a lot of “soft” topics to keep you motivated to learn. During the course, you will build many different apps. Very soon, you’ll start integrating backend API requests, etc. Even though the apps you build are always just one use case app, <strong>you will quickly get into real-world use cases</strong> — like integrating Firebase into your app or saving data locally with the Core Data framework.</p><p>There are also topics that I think are not necessary for a beginner iOS engineer, such as ARKit or Apple’s machine learning framework. If you fancy, try these lessons as well; it’s a fun thing to have an app that can recognize what is in the picture, etc. But don’t feel like you have to complete 100% of the course.</p><p>After the course from Dr. Angela, you are on a really good track to becoming an iOS engineer. <strong>You might feel like it’s time to move to the next step, to more complex topics. However, I strongly recommend doing the 100 Days of Swift first.</strong> Even though the topics are very similar, Paul Hudson does a great job of looking at problem-solving from a different perspective. He has a slightly different teaching style, and that’s exactly what you need at the beginning to understand the basics of Swift and iOS development. Repetition is king here — and that perfectly matches how the course is structured. As Paul says:</p><p>“<em>If you want to make a success of this course, there are only two rules:</em></p><ul><li><em>Every day, you spend one hour reading or watching Swift tutorials, or writing Swift code.</em></li><li><em>Every day, you post about your progress to the social media site of your choosing. Tell people!”</em></li></ul><p><strong>The one-hour-a-day part is the important one here. </strong>The lectures are built this way. And having already gone through Angela’s course (presumably), you can do more lectures per day if you’re a fast learner. On the other hand, if you need more time to grasp every single topic, the course is great for that as well.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/980/0*JFQuPvzhHxKGOLqK" /></figure><p>Title: Example of an app built during 100 Days of Swift by hackingwithswift.com</p><h3>What’s Next? Build a Real-world App</h3><p>I believe this is the most crucial part of the learning journey. And even though I don’t have the proper statistics, <strong>I feel that this stage is where the majority of the students drop out.</strong> I am talking about the stage where you have some basic understanding and knowledge about iOS, you went through several courses and touched on multiple topics, you’re connecting puzzle pieces of knowledge and the final image starts to materialize. But you just don’t feel ready to take on a job interview yet, there are some topics that you don’t understand and you just can’t imagine yourself building a standalone real-world app by yourself. You don’t want to get back to the basics again, but the bridge from your situation to the next level seems too complex. This results in a lack of motivation and may eventually end in you giving up on iOS learning.</p><p><strong>If you are in this phase, don’t worry. </strong>I have experienced exactly these feelings and I have a great course for you.</p><p>The course is from Sean Allan, another very well-known figure in the iOS world. <strong>The course is called iOS Dev Job Interview Practice — Take Home Project.</strong> It’s the perfect course for helping you cross over from beginner to job-interview-ready.</p><p>In the course, you will be making the GitHub Followers app. The whole process of making the app is designed to feel very similar to a real-world app or, as the name suggests, a take-home test project from a job interview. You will make the UI fully programmatically — no storyboards. <strong>Sean focuses on all the details. </strong>Correct organization of the code, avoiding code duplicates, refactoring and, in general, building the project as if you need to pass a job interview. Sean himself has worked on multiple projects for companies or his own apps and knows all the necessary practical details.</p><p>This course helped me to feel comfortable enough to take a chance, apply for a job at STRV and prepare the test project.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/705/0*l85Zce56k4WdYyJn" /></figure><p>Title: Design for GitHub Followers app, Source: <a href="https://seanallen.co/">https://seanallen.co/</a></p><h3>Go Down the Rabbit Hole</h3><p>I believe that consistency in learning is a key to success. Rather than spending every other weekend, whole Saturdays staring at the screen trying to learn iOS, <strong>I recommend spending less time on studying but doing so more frequently.</strong> Are you a student or are working at a non-engineering job? Spend 1–2 hours every day studying. In the beginning, I often spent too many hours in one day, then didn’t open Xcode for a week, and I ended up not remembering anything and having to start the lesson over again.</p><p><strong>Try to utilize tunnel vision with your goal of becoming an iOS engineer. </strong>What worked for me was to surround myself with the most approachable topics from the entire software development and Apple world.</p><p>I have some tips on how you can jump down the rabbit hole and keep yourself in tunnel vision mode. <strong>These activities are less about actively learning time and more about passively feeding yourself via the environment. </strong>It’s like when you’re trying to lose weight: It’s great to go to the gym a couple of times a week, but what can make the difference is the “passive activities” that accumulate through your day — walking instead of driving a car, biking as your form of commuting, drinking water instead of soda, etc. You know what I mean.</p><p><strong>Here are my tips:</strong></p><ul><li>Listen to the <a href="https://www.swiftbysundell.com/podcast/">Swift by Sundell podcast</a>, even the old episodes</li><li>Watch Sean Allan’s <a href="https://youtube.com/playlist?list=PL8seg1JPkqgGgJq7BKslPBVmnKDISu4dW">Swift News</a></li><li>Subscribe to <a href="https://www.youtube.com/c/Fireship">Firsehip</a> for funny yet educational content from the whole software engineering field; for example, <a href="https://www.youtube.com/watch?v=Xg9ihH15Uto">How to Land a 100K/yr Tech Job — 10 Strategies</a> or <a href="https://www.youtube.com/watch?v=tv-_1er1mWI">10 Design Patterns Explained in 10 Minutes</a></li><li>Follow <a href="https://www.youtube.com/c/DorianDevelops">Dorian Develops</a> on his journey in software development, his ups and downs in his programming career and strategies and ideas to become a good software engineer</li><li>Join <a href="https://seanallen.co/">Sean Allan’s Slack</a> group and chat with other students or at least read their posts</li><li>Watch older WWDC presentations by Apple</li><li>Tweet or write a <a href="https://lukas-smetana-ls.medium.com/my-100-days-of-swift-b9ba58caf90d">blog</a> about your progress, even if only your partner will read it :)</li><li>Watch <a href="https://www.youtube.com/watch?v=5bdzffoilxU">SwiftUI Roadmap</a> by Karin Prater and subscribe to her amazing channel full of great educational content</li><li>Watch the detailed and technically-focused <a href="https://www.youtube.com/watch?v=HNXzcAwNqMc">How to Become an iOS Developer</a> by Paul Hudson</li><li>Join the iOS community on Twitter</li></ul><p><strong>In short, surround yourself with the iOS world.</strong> Live it. Think about it. Talk about it. This will help you on your journey.</p><h3>(Don’t) Get a Mentor!</h3><p>In most videos and articles about how to learn software development, you will be advised to get a mentor, a senior dev in the field to help you with the learning. I can only partially agree.</p><p>All branches of software development — backend, web and mobile — are in high demand. There are not enough people for the jobs. This has one side effect and that is that everyone can become senior quite quickly, compared to other fields. This may give the senior people the confidence to mentor others, but <strong>I think that only a small amount of senior devs are suitable for the mentor role.</strong></p><p>In fact, I think it’s so few of them that there is a high chance of being mentored by the wrong person. Is it a big deal, you ask? Might be. The wrong mentor can quickly demotivate you and can have a bad influence on you, even if the intentions are good!</p><p><strong>If the mentor can’t adapt to your skills and learning speed, it may quickly end up with you doubting your skills and yourself.</strong> Imagine you are with a senior dev who’s explaining some advanced concept, you don’t understand his way of explaining and don’t get the topic. The mentor starts losing patience and you might start doubting yourself when, in fact, maybe the mentor chose the wrong way of explaining the topic — or maybe you were not ready for this topic at all. From my experience, the more junior the student is, the harder it is to get the right mentor.</p><p>So, as an alternative, I recommend getting in touch with other people who are learning on the same level. Talk with them about the problems you’re facing. Don’t be shy to make mistakes and ask the wrong questions. Chances are that other students might have been making the same mistake just a month ago and will give you their beginners’ perspective.</p><p><strong>Personally, what helped me the most was talking about my journey with an iOS engineer who was also self-taught. </strong>His way of explaining stuff and presenting concepts was much more understandable for me, an equally self-taught engineer.</p><p>Don’t get me wrong, I am not saying that having a mentor is a bad thing. I think it’s an awesome thing — but to get a suitable mentor early on in your career is, from my perspective, a hard thing to accomplish. As you evolve as an engineer, it will be much easier for you, as well as for the senior-dev mentors, to talk about common topics.</p><h3>Becoming iOS Engineer via the STRV Academy</h3><p>I’ll sneak in a little STRV promo. Another option, yet limited by location and time and only for those who’ve passed basic iOS introduction courses, could be the <a href="https://www.strv.com/academy/becoming-an-ios-engineer">STRV Academy: Becoming an iOS Engineer</a>. After two years marked by Covid-19, STRV is back with its proven concept of an offline, hands-on academy open for applications now. And if you miss this year’s dates, stay on the lookout next year. It’s sure to be back.</p><h3>Bonus: Are You a QA Engineer?</h3><p>If you are working as a QA engineer, analyst or tester and you’d like to transition to iOS development, this part is for you. <strong>I can help here as well — because that’s exactly my story.</strong></p><p>A couple of years back, I was working as a QA Tester. There was a task that nobody on the project wanted to push forward: test automation on iOS and Android. I decided I will try to pursue this mission myself. I chose to start with iOS because my cooperation with the iOS engineers in the team was pleasant.</p><p>I didn’t know much about it because, in my previous job, I was writing automated tests in Java purely for API. <strong>Mobile test automation was very new to me.</strong> At first, I had to decide whether to use Appium, which could run tests for both iOS and Android, or to go the native route. Luckily, the resources I got into made me go the native way. If you’d like, read more about <a href="https://lukas-smetana-ls.medium.com/why-use-native-ui-test-automation-for-mobile-apps-df140b0f3117">Why Use Native UI Test Automation for Mobile Apps</a>.</p><p>This goal of mine, to create UI automated tests for our iOS app, brought me to this <a href="https://testautomationu.applitools.com/introduction-to-ios-test-automation-with-xcuitest/">course</a> — which is nothing in comparison to the other courses I’ve recommended, but it’s what I started with. And it sent me in a good direction. What followed was a lot of Googling, try-fail situations and, finally, writing some tests in Swift for XCUITest. In the end, none of them were used in the production CI. But it laid my Swift foundation and helped me to get on the track of iOS development.</p><h3>You Can Do It!</h3><p>Good luck on your iOS journey. Get in touch in case of any questions or concerns, I will be more than happy to discuss any topic.</p><p>And to end with, I’d like to thank Gleb, Honza, Filip, Ondra, Dan and everyone who has helped (and is still helping) me on my journey.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9d86df2189ac" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[My 100 Days of Swift]]></title>
            <link>https://lukas-smetana-ls.medium.com/my-100-days-of-swift-b9ba58caf90d?source=rss-766974ace25------2</link>
            <guid isPermaLink="false">https://medium.com/p/b9ba58caf90d</guid>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[100-days-of-swift]]></category>
            <category><![CDATA[100daysofcode]]></category>
            <dc:creator><![CDATA[Lukas Smetana]]></dc:creator>
            <pubDate>Sat, 10 Apr 2021 11:33:31 GMT</pubDate>
            <atom:updated>2022-06-09T10:04:19.521Z</atom:updated>
            <content:encoded><![CDATA[<p>Here is my brief summary of every little project included in <a href="https://www.hackingwithswift.com/100">100 Days of Swift</a> by Paul Hudson, mainly for my own future references.</p><h3>PROJECT 25 — Selfie Share</h3><h3>MILESTONE PROJECT 8 (projects 22–24)</h3><ul><li>Milestone project 8 was a bit different, the goal was not to create a new app from scratch but only to implement 3 swift extensions</li></ul><h4>Challenge:</h4><ol><li>Extend <strong>UIView</strong> so that it has a <strong>bounceOut(duration:)</strong> method that uses animation to scale its size down to 0.0001 over a specified number of seconds. ✅</li><li>Extend <strong>Int</strong> with a <strong>times()</strong> method that runs a closure as many times as the number is high. For example, <strong>5.times { print(&quot;Hello!&quot;) }</strong> will print “Hello” five times. ✅</li><li>Extend <strong>Array</strong> so that it has a mutating <strong>remove(item:)</strong> method. If the item exists more than once, it should remove only the first instance it finds. Tip: you will need to add the <strong>Comparable</strong> constraint to make this work! ✅</li></ol><h3>PROJECT 24 — Teqchnique project — Strings</h3><p>Day 81–81, 27th of May</p><h4>I learned about:</h4><ul><li>Create String Extension in order to create custom properties and methods of the String struct for example extension allowing to access i-th character in the string like you would with array : string[i]</li><li>more practice with String methods like: hasSuffix(), hasPrefix(), contains(where:), dropFirst(), uppercased(), capitalized(),etc</li><li>Formating strings with NSAttributedString, example:</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XUUPubxVLxQrubwcilhpvA.png" /></figure><ul><li>There is also a chance to format just specific parts of the string</li></ul><p>Challenge:</p><ol><li>Create a <strong>String</strong> extension that adds a <strong>withPrefix()</strong> method. If the string already contains the prefix it should return itself; if it doesn’t contain the prefix, it should return itself with the prefix added. For example: <strong>&quot;pet&quot;.withPrefix(&quot;car&quot;)</strong> should return “carpet”. ✅</li><li>Create a <strong>String</strong> extension that adds an <strong>isNumeric</strong> property that returns true if the string holds any sort of number. Tip: creating a <strong>Double</strong> from a <strong>String</strong> is a failable initializer. ✅</li><li>Create a <strong>String</strong> extension that adds a <strong>lines</strong> property that returns an array of all the lines in a string. So, “this\nis\na\ntest” should return an array with four elements.</li></ol><h3>PROJECT 23 — Swift Ninja</h3><p>Day 77–80, 26th of May</p><p>I decided to skip this SpriteKit project because I am not expecting to use SpriteKit in the future.</p><h3>PROJECT 22 — Detect-a-Beacon</h3><p>Day 74–76, 25th of May</p><h4>I learned about:</h4><ul><li>Requesting location</li><li>CoreLocation framework</li><li>CLLocationManager</li></ul><h4>Description:</h4><p>Simple app showing distance to random iBeacon which is measured by Apple beacon technology using Bluetooth.</p><h4>Today I learned about:</h4><ul><li><strong>Core Location</strong></li><li><strong>CLBeaconRegion</strong></li><li>What is <strong>iBeacon</strong></li><li>Asking the user for <strong>permission about location</strong> — All the time (even when the app is not running ) or when the app is active.</li><li>Using location when the app isn’t running is of course highly sensitive information, so Apple flags it up in four ways:</li></ul><ol><li>If you request Always access, users will still get the chance to choose When In Use.</li><li>If they choose Always, iOS will automatically ask them again after a few days to confirm they still want to grant Always access.</li><li>When your app is using location data in the background the iOS UI will update to reflect that — users will know it’s happening.</li><li>Users can, at any point, go into the settings app and change from Always down to When In Use.</li></ol><h3><strong>MILESTONE PROJECT 7 (projects 19–21)</strong></h3><p>Day 73, 23rd of May</p><h3>PROJECT 21 — technique project — local notifications</h3><h4>Description:</h4><p>Another technique project, this time focused on notifications. There are two types of notifications local and push. They are not the same. Local notification can be scheduled only in the app but the push notifications require a dedicated server (or service, if you outsource) to send from.</p><h4>I learned about:</h4><ul><li>You <strong>can’t post messages </strong>to the user’s lock screen <strong>unless you have their permission </strong>so in order to send local notifications in our app, we first need to request permission</li><li>How to <strong>register</strong> and <strong>schedule</strong> a local notification</li><li><strong>Request permission</strong>: In the <strong>requestPermision() </strong>of <strong>UNUserNotificationCenter </strong>we have to specify what kind of notification we want to request for, for example options: [.alert, .badge, .sound]</li><li><strong>Schedule Notification</strong>: in order to schedule local notification we need to configure 3 things: content (what to show), a trigger (when to show it), and a request (the combination of content and trigger.)</li><li><strong>Notification trigger</strong>, when to show the notification — can be a calendar trigger that shows the notification at an exact time, it can be an interval trigger that shows the notification after a certain time interval has lapsed, or it can be a geofence that shows the notification based on the user’s location.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/421/1*j0Z8KFnmushkXEtZweUf6w.png" /></figure><ul><li><strong>Content of the notification:</strong> UNMutableNotificationContent has lots of properties that customize the way the alert looks and works</li><li>To attach custom data to the notification, e.g. an internal ID, use the <strong>userInfo</strong> dictionary property (in the content)</li><li>You can also attach custom actions by specifying the <strong>categoryIdentifier</strong> property (also in the content of the notification)</li><li>new data type called <strong>DateComponents</strong></li></ul><h4>Challenge:</h4><ol><li>Update the code in <strong>didReceive</strong> so that it shows different instances of <strong>UIAlertController</strong> depending on which action identifier was passed in.</li><li>For a harder challenge, add a second <strong>UNNotificationAction</strong> to the <strong>alarm</strong> category of project 21. Give it the title “Remind me later”, and make it call <strong>scheduleLocal()</strong> so that the same alert is shown in 24 hours. (For the purpose of these challenges, a time interval notification with 86400 seconds is good enough – that’s roughly how many seconds there are in a day, excluding summer time changes and leap seconds.)</li><li>And for an even harder challenge, update project 2 so that it reminds players to come back and play every day. This means scheduling a week of notifications ahead of time, each of which launch the app. When the app is finally launched, make sure you call <strong>removeAllPendingNotificationRequests()</strong> to clear any un-shown alerts, then make new alerts for future days.</li></ol><h3>PROJECT 20 — Fireworks game</h3><p>Days 70–72, 18th of May</p><h4>Description:</h4><p>Another SpriteKit project. This time a little firework game where the goal is to tap rockets of the same colour and make them explode by shaking of the tablet.</p><h4>I learned about:</h4><ul><li><strong>UIBezierPath</strong></li><li>New SKAction <strong>follow()</strong>, which takes in CGPath as a parameter and makes the node move along that path.</li><li>new syntax <strong>for case let — </strong>in the case of this project it is used to loop over an array of SKNode but because we need to execute some code only when the node is SKSpriteNode. We create a new constant with let and typecast it to SKSpiriteNode</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/661/1*NI2pSroSdg1NdmNpNI_0kg.png" /></figure><h4>Challenge:</h4><ol><li>For an easy challenge try adding a score label that updates as the player’s score changes. ✅</li><li>Make the game end after a certain number of launches. You will need to use the <strong>invalidate()</strong> method of <strong>Timer</strong> to stop it from repeating. ✅</li><li>Use the <strong>waitForDuration</strong> and <strong>removeFromParent</strong> actions in a sequence to make sure explosion particle emitters are removed from the game scene when they are finished.</li></ol><h3>PROJECT 19 — Safari extension — JavaScript Injection</h3><p>Days 67–69, 17th of May</p><h4>Description:</h4><p>The goal of this project is not an application or game as before but rather a Safari extension. This extension allows running JavaScript code that we provide to the text TextView. So for example we can enter and display an alert with the title of the page that we previously fetched from the Safari itself. Also, we have fixed a keyboard issue, where text inputted into TextView was hiding under the keyboard if it was too long. It was fixed with Pauls own method — observing values from NotificationCenter. In the observer, we react to any change by adjusting the <strong>contentInset</strong> and <strong>scrollIndicatorInsets</strong> of our text view.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/446/1*skMIwKJZiCV3GFNeLyfrvA.gif" /></figure><h4>I learned about:</h4><ul><li>When our Swift extension finishes we can send values back to JavaScript. Anything we send back is then made available to our action file<strong>.</strong></li><li>The <strong>addObserver()</strong> method of <strong>NotificationCenter</strong> lets us watch for a particular notification. This lets us attach some code to run when a notification comes in.</li><li>Scroll indicator insets control how big the scroll bars are relative to their view.</li><li>You must ship an app if you want to ship an extension. Extensions are shipped inside the parent app.</li><li>The <strong>contentInset</strong> property of a <strong>UITextView</strong> determines how text is placed inside the view.</li><li>We usually rely on the capture list from the outer closure.</li></ul><h4>Challenge</h4><ol><li>Add a bar button item that lets users select from a handful of prewritten example scripts, shown using a <strong>UIAlertController</strong> – at the very least your list should include the example we used in this project. ✅</li><li>You’re already receiving the URL of the site the user is on, so use <strong>UserDefaults</strong> to save the user&#39;s JavaScript for each site. You should convert the URL to a <strong>URL</strong> object in order to use its <strong>host</strong> property.</li><li>For something bigger, let users name their scripts, then select one to load using a <strong>UITableView</strong>.</li></ol><h3>PROJECT 18 — technique project — debugging</h3><p>Days 65–67, 11th of May</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/422/1*g8z_eg91RIhAAND2yMuCZA.png" /></figure><h4>Description:</h4><ul><li>Another technique project. Project with no real app as an outcome Only allows to practices some technique in the playground.</li><li>This time — debugging</li></ul><h4>I learned about:</h4><ul><li>different approaches to debugging</li><li>print() — the lamest approach to debugging. Used with Swift’s string interpolation to see the contents of your variables when your app is running.</li><li>assert() — lets us ensure the app’s state is exactly what you thought it was, for example, assert(array.isEmpty)</li><li>breakpoints — allows us to stop the program on the line, where the breakpoint is placed when the program execution comes to that line. It then allows to see the current values of all variables.</li><li>conditional breakpoints — create a condition for when breakpoint should be applied, for example, every 10th iteration of the loop</li><li>exceptions breakpoints — can be automatically triggered when an exception is thrown</li><li>backtrace —way how to track functions and from where they were called. So if a bug is found somewhere in the method <strong>d()</strong>, this back trace will show you that <strong>d()</strong> was called by <strong>c()</strong>, which was called by <strong>b()</strong>, which in turn was called by <strong>a()</strong> – it effectively shows you the events leading up to the problem, which is invaluable when trying to spot bugs.</li><li>view debugging — Capture View Hierarchy, great function of xCode. This debug mode is perfect for times when you know you’ve placed your view but for some reason can’t see it.</li></ul><h4>Challenges:</h4><ol><li>Temporarily try adding an exception breakpoint to project 1, then changing the call to <strong>instantiateViewController()</strong> so that it uses the storyboard identifier “Bad” – this will fail, but your exception breakpoint should catch it. ✅</li><li>In project 1, add a call to <strong>assert()</strong> in the <strong>viewDidLoad()</strong> method of DetailViewController.swift, checking that <strong>selectedImage</strong> always has a value. ✅</li><li>Go back to project 5, and try adding a conditional breakpoint to the start of the <strong>submit()</strong> method that pauses only if the user submits a word with six or more letters. ✅</li></ol><h3>PROJECT 17 — Space Race</h3><p>Days 64–65, 10th of May</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/962/1*QP-IEMw_fodV408WfFJ74A.gif" /></figure><h4>Description:</h4><p>Another mini-game. This time small rocket flying thru space and trying to avoid collision with randomly generated objects.</p><h4>I learned about:</h4><ul><li>How to use <strong>Timer</strong> to trigger a repeating method every few seconds</li><li>Postpone the initial state of the particles animation so it looks good right from the start (used for moving stars) with <strong>advanceSimulationTime()</strong></li><li><strong>linearDamping</strong> and <strong>angularDamping</strong> properties of <strong>SKPhysicsBody</strong> to force sprites to retain their speed and spin, rather than slowing down over time (enemy objects)</li></ul><h4>Challenges:</h4><ol><li>Stop the player from cheating by lifting their finger and tapping elsewhere — try implementing <strong>touchesEnded()</strong> to make it work.</li><li>Make the timer start at one second, but then after 20 enemies have been made subtract 0.1 seconds from it so it’s triggered every 0.9 seconds. After making 20 more, subtract another 0.1, and so on. Note: you should call <strong>invalidate()</strong> on <strong>gameTimer</strong> before giving it a new value, otherwise you end up with multiple timers.</li><li>Stop creating space debris after the player has died.</li></ol><h3>PROJECT 16 — MapKit</h3><p>Days 60–63, 7th of May</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/364/1*xvizMw5XwwJY4yca1rTtVQ.gif" /></figure><h4>Description:</h4><p>Simple one screen app displaying a map with pins representing “interesting” places. Every pin has its name and link to Wikipedia which is displayed as webView inside of the app on the next screen.</p><h4>I learned about:</h4><ul><li><strong>MKMapView</strong></li><li><strong>MKAnnotation</strong></li><li><strong>MKPinAnnotationView</strong></li><li><strong>CLLocationCoordinate2D</strong></li><li>Different <strong>MapView.mapType , f</strong>or example, <strong>.satellite</strong></li></ul><h4>Challenges:</h4><ol><li>Try typecasting the return value from <strong>dequeueReusableAnnotationView()</strong> so that it&#39;s an <strong>MKPinAnnotationView</strong>. Once that’s done, change the <strong>pinTintColor</strong> property to your favourite <strong>UIColor</strong>. ✅</li><li>Add a <strong>UIAlertController</strong> that lets users specify how they want to view the map. There&#39;s a <strong>mapType</strong> property that draws the maps in different ways. For example, <strong>.satellite</strong> gives a satellite view of the terrain. ✅</li><li>Modify the callout button so that pressing it shows a new view controller with a web view, taking users to the Wikipedia entry for that city. ✅</li></ol><h3>MILESTONE PROJECT 6 (projects 13–15)</h3><p>Day 59, 6th of May</p><h4>Challenge:</h4><p>Your challenge is to make an app that contains facts about countries: show a list of country names in a table view, then when one is tapped bring in a new screen that contains its capital city, size, population, currency, and any other facts that interest you.</p><h4>My approach:</h4><ul><li>getting data from open API <a href="https://restcountries.eu/">https://restcountries.eu/</a></li><li>created one central class APIManager which is calling this API with customized calls</li><li>fetching all countries and displaying them in the initial tableView</li><li>then I fetch single country data based on what cell was tapped and display info on the new screen</li><li>so far not able to fetch flag picture</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/481/1*QxIazmenfpZS1lVoPxrlsg.gif" /></figure><h3>PROJECT 15 — technique project — Animations</h3><p>Days 57–58, 4nd of May</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PfR6jylVYRfDjWlndQyT8Q.gif" /></figure><h4>Description:</h4><ul><li>Another technique project.</li><li>Project with no real app as an outcome</li><li>Only allows to practices some technique in the playground.</li><li>This time — Animations.</li></ul><h4>I learned about:</h4><ul><li><strong>UIView.Animate()</strong></li><li>How to use Alpha to make object invisible</li><li>How to move, rotate, and scale views using <strong>CGAffineTransform</strong>.</li><li>Scale — CGAffineTransform(scaleX: 2, y: 2)</li><li>Move — CGAffineTransform(translationX: -256, y: -256)</li><li>Rotate — CGAffineTransform(rotationAngle: CGFloat.pi)</li><li>Make invisible — <strong>self</strong>.imageView.alpha = 0</li><li>Return to original appearence —<strong>self</strong>.imageView.transform = .identity</li></ul><h4>Challenges</h4><ol><li>Go back to project 8 and make the letter group buttons fade out when they are tapped. We were using the <strong>isHidden</strong> property, but you&#39;ll need to switch to <strong>alpha</strong> because <strong>isHidden</strong> is either true or false, it has no animatable values between. ✅</li><li>Go back to project 13 and make the image view fade in when a new picture is chosen. To make this work, set the <strong>alpha</strong> to 0 first. ✅</li><li>Go back to project 2 and make the flags scale down with a little bounce when pressed. ❌</li></ol><h3>PROJECT 14 — Whack-A-Pinguine</h3><p>Days 54–56, 2nd of May</p><p><a href="https://github.com/lukassmetana/project14">https://github.com/lukassmetana/project14</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/980/1*YLiYJNUFgsBYelVMeaUT8g.gif" /></figure><h4>Description:</h4><ul><li>Simple Whack-a-mole type game. Instead of moles, there are good and bad pinguins.</li></ul><h4>I learned about:</h4><ul><li>SKTexture — Changing sprite images without moving the sprite, using <strong>SKTexture</strong></li><li>SKCRopNode — Cropping a sprite so that only part of it is visible, using <strong>SKCropNode</strong></li><li>More <strong>SKActions</strong>, including <strong>moveBy(x:y:)</strong>, <strong>wait(forDuration:)</strong>, <strong>sequence()</strong>, and even how to run custom closures using <strong>run(block:)</strong></li><li>The <strong>asyncAfter()</strong> method of GCD, which causes code to be run after a delay — used for delaying start of the round</li></ul><h4>Challanges:</h4><ol><li>Record your own voice saying “Game over!” and have it play when the game ends. ✅</li><li>When showing “Game Over” add an <strong>SKLabelNode</strong> showing their final score. ✅</li><li>Use <strong>SKEmitterNode</strong> to create a smoke-like effect when penguins are hit, and a separate mud-like effect when they go into or come out of a hole. ✅ (only effect when they are hit)</li></ol><h3>PROJECT 13 — PhotoFilters</h3><p>Days 51–53, 29th of April</p><p><a href="https://github.com/lukassmetana/project13">https://github.com/lukassmetana/project13</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/384/1*Z7wupMKe8NQV6L8JWkedOQ.gif" /></figure><h4>Description:</h4><ul><li>App that allows you to apply a filter on pictures from your photo library and save them</li></ul><h4>I learned about:</h4><ul><li>UISlider — How to let the user select from a range of values using <strong>UISlider</strong></li><li>Using Core Image (CIContext and CIFilter) — Create Core Image contexts using <strong>CIContext</strong>, and creating then applying Core Image filters using <strong>CIFilter</strong>.</li><li><a href="https://developer.apple.com/documentation/uikit/1619125-uiimagewritetosavedphotosalbum">UIImageWriteToSavedPhotosAlbum()</a> — Saving images back to the user’s photo library by calling the <strong>UIImageWriteToSavedPhotosAlbum()</strong> function</li><li>More practice using <strong>UIImagePickerController</strong>, to select pictures from the user’s photo library.</li></ul><h4>Challenges:</h4><ol><li>Try making the Save button show an error if there was no image in the image view. ✅</li><li>Make the Change Filter button change its title to show the name of the currently selected filter. ✅</li><li>Experiment with having more than one slider, to control each of the input keys you care about. For example, you might have one for radius and one for intensity. ❌</li></ol><h3>MILESTONE PROJECT 5 (projects 10–12)</h3><p>Day 50</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/354/1*oEvn0zIBeEXRzmYS_aqScA.gif" /></figure><h4>Challenge:</h4><ul><li>Your challenge is to put two different projects into one: I’d like you to let users take photos of things that interest them, add captions to them, then show those photos in a table view. Tapping the caption should show the picture in a new view controller</li></ul><h3>PROJECT 12 — technique project — UserDefaults</h3><p>Days 48–49</p><h3>PROJECT 11 — Pachinko</h3><p>Days 45–47, 21st of April</p><p><a href="https://github.com/lukassmetana/project11">https://github.com/lukassmetana/project11</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xEONa1Fk2YgmOdBvuYnJ-Q.png" /></figure><h4>Description:</h4><ul><li>First game-project using SpriteKit — Apple’s high-performance 2D games framework.</li><li>I would not even call it a game because there is no clear goal. User can just drop balls and if they end up in the green slot score increases and if they end up in the red one, score decreases.</li><li>Also, it&#39;s possible to add obstacles. When the ball hits an obstacle they are both “destroyed” and disappear.</li></ul><h4>I learned about:</h4><ul><li>A lot of stuff from SpriteKite 😀.</li><li>The <strong>SKSpriteNode</strong> class is responsible for loading and drawing images on the screen.</li><li>Draw sprites using a selection of blend modes. We used <strong>.replace</strong> for drawing the background image, which causes SpriteKit to ignore transparency. This is faster, and perfect for our solid background image.</li><li>Add physics to sprite nodes using <strong>SKPhysicsBody</strong>, which has <strong>rectangleOf</strong> and <strong>circleWithRadius</strong> initializers that create different shapes of physics bodies.</li><li>Adding actions to things, such as spinning around or removing from the game, is done using <strong>SKAction</strong>.</li><li>Measure angles in radians using <strong>CGFloat.</strong></li><li>Detecting user interaction with the screen (game) with <strong>touchesBegan(_:with:)</strong></li></ul><h3>Project 10 — Names to Faces</h3><p>Days 42–44, 17th April</p><p><a href="https://github.com/lukassmetana/project10">https://github.com/lukassmetana/project10</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/509/1*VHqp234lrw3ugKWQGIhbog.gif" /></figure><h4>I learned about:</h4><ul><li>UICollectionView</li><li>Designed a custom <strong>UICollectionViewCell</strong>, first in the storyboard and then in code. No like with UITableViewCell, CollectionViewCell always must be customized.</li><li>UUID — easy way how to create unique identifiers, which is the easiest way to generate filenames that are guaranteed to be unique</li><li>Saving Data to disk — converting each <strong>UIImage</strong> to a <strong>Data</strong> that could be written to disk, using <strong>jpegData()</strong></li><li><strong>appendingPathComponent()</strong> method, as well as Paul Hudson&#39;s<strong>getDocumentsDirectory()</strong> helper method. Combined, these two let create filenames that are saved to the user’s documents directory.</li></ul><h4>The thing I should have probably already known but realized just now:</h4><ul><li>UiCollectionView</li></ul><h4>Review quiz score: 11/12</h4><h4>Challenges:</h4><ol><li>✅</li><li>✅</li></ol><h3>MILESTONE PROJECT 4 (projects 7–9)</h3><p>Day 41</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/361/1*ERwiqH3xLntXfWSGfWxFQg.gif" /></figure><h4>Challenge:</h4><ul><li>The challenge is this: make a hangman game using UIKit.</li></ul><h3>PROJECT 9 — technique project — Grand Centra Dispatch</h3><p>Days 39–40, 11th of April</p><p><a href="https://github.com/lukassmetana/project9">https://github.com/lukassmetana/project9</a></p><h4>Review quiz score: 11/12</h4><h4>Challenges:</h4><h3><strong>PROJECT 8 — Swifty Words</strong></h3><p>Days 36–38, 8th — 10th of April</p><p><a href="https://github.com/lukassmetana/project8">https://github.com/lukassmetana/project8</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/734/1*ceTfzMJ2cSUlDMRu9hDDcA.gif" /></figure><h4>I learned about:</h4><ul><li>Building UI programmatically</li><li>Content hugging and content compression resistance priority</li><li>Property observer: didSet</li><li>Working with strings: contentsOf, components(separatedBy: ), enumerated(), replacingOccurrences()</li><li>Add action to UIButton with addTarget()</li><li>Difference between shuffle() and shuffled() array</li></ul><h4>The thing I should have probably already known but realized just now:</h4><ul><li>UIView is a parent class of all UIKit’s types like UIButton, UILabel, etc.</li></ul><h4>The thing I should probably remember: nil</h4><h4>Review quiz score: 11/12</h4><h4>Challenges:</h4><ol><li>✅</li><li>✅</li><li>✅</li></ol><h3>PROJECT 7 — Petitions</h3><p>Days 33–35</p><p><a href="https://github.com/lukassmetana/project7">https://github.com/lukassmetana/project7</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/518/1*QfGkKvpUlg8mMnwpmv1ppg.gif" /></figure><h4>I learned about:</h4><ul><li>UITabBarController</li><li>Getting data from the internet with Codable protocol</li><li>Data data type</li><li>Create custom HTML inside of WebView</li></ul><h4>The thing I should have probably already known but realized just now: nil</h4><h4>The thing I should probably remember: nil</h4><h4>Review quiz score: 11/12</h4><h4>Challenges:</h4><ol><li>✅</li><li>✅</li><li>✅</li></ol><h3>MILESTONE PROJECT 3 (projects 4–6)</h3><p>Day 32</p><h4>Challenge:</h4><ul><li>This time your job is to create an app that lets people create a shopping list by adding items to a table view.</li></ul><h3>PROJECT 6 — technique project — Auto Layout</h3><p>Days 30–31</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/345/1*_m-XbWMSrDQO-D082NZXEg.png" /></figure><h3>PROJECT 5 — World Scramble</h3><p>Days 27 — 29</p><h4>I learned about:</h4><ul><li>weak, strong, unowned references</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/356/1*ufuondGx-oTUDQvY4STsjw.gif" /></figure><h3>PROJECT 4 — Easy browser</h3><p>Days 24–26</p><p>I learned about:</p><ul><li><strong>WKWebView</strong></li><li>UIAlertController action sheets</li><li>UIToolbar, toolBarItems, rightBarButtonItem</li><li>UIProgressView</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/354/1*JIk7EMjfK5uOnUyKUCd2cA.gif" /></figure><h3>MILESTONE PROJECT 2 (projects 1–3)</h3><p>Day 23</p><h4>Challenge:</h4><p>Your challenge is to create an app that lists various world flags in a table view. When one of them is tapped, slide in a detail view controller that contains an image view, showing the same flag full size. On the detail view controller, add an action button that lets the user share the flag picture and country name using <strong>UIActivityViewController</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/478/1*WQrqtAi2RdMpucrDfmJOSg.gif" /></figure><h3>PROJECT 3 — technique project — UIActivityViewController</h3><p>Day 22</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/358/1*ncrmoF6SUhP1gyEpP0EmOQ.png" /></figure><h4>I learned about:</h4><ul><li><strong>UIBarButtonItem</strong></li><li><strong>UIActivityViewController</strong></li></ul><h3>PROJECT 2 — Guess the flag</h3><p>Days 19–21</p><h4>I learned about:</h4><ul><li><strong>UIButton</strong></li><li><strong>Assets </strong>— iOS assets come in three sizes — 1x , 2x , 3x, if you’re supporting only iOS 10 or later devices you only need to include the @2x and @3x images</li><li><strong>CALayer</strong> (CA = Core Animation)— every iOS view is backed by CALayer, which is a Core Animation data type responsible for managing the way views looks. Conceptually, <strong>CALayer</strong> sits beneath all <strong>UIView</strong>s (that&#39;s the parent of <strong>UIButton</strong>, <strong>UITableView</strong>, and so on), so it&#39;s like an exposed underbelly giving lots of options for modifying the appearance of views, as long as you don&#39;t mind dealing with a little more complexity. Example of CALayer property for UIButton is<strong>borderWidth</strong>.</li><li><strong>CGColor</strong> is is type by which we can set colour to borderColor of our layer. (CG = CoreGraphics)</li><li><strong>UIAlertController</strong></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/381/1*qkAPC3gl4gTo3s0LyCOXRg.gif" /></figure><h4>Challenges:</h4><ol><li>Try showing the player’s score in the navigation bar, alongside the flag to guess.</li><li>Keep track of how many questions have been asked, and show one final alert controller after they have answered 10. This should show their final score.</li><li>When someone chooses the wrong flag, tell them their mistake in your alert message — something like “Wrong! That’s the flag of France,” for example.</li></ol><h3>PROJECT 1 — Storm Viewer</h3><p>Days 15–18</p><p><a href="https://github.com/lukassmetana/project1">https://github.com/lukassmetana/project1</a></p><h4>Description:</h4><ul><li>Very simple TableView app displaying pre-loaded pictures (part of the repository), counting the number of views of every picture.</li><li>Added as part of a challenge from different weak: the number of views is saved in UserDefaults.</li></ul><h4>I learned about:</h4><ul><li>UITableView</li><li>UIImageView</li><li>FileManager</li><li>Outlets</li><li>StoryBoard</li><li>AutoLayout</li><li>UIImage</li><li>instantiateViewController from Storyboard</li><li>pushViewController with navigationController</li></ul><p>—</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/494/1*GS_mpHvQGFOHdvLxhobZdQ.gif" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b9ba58caf90d" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>