<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Cyndi Chin</title>
        <description>Personal Website</description>
        <link>cyndichin.github.io/</link>
        <atom:link href="cyndichin.github.io/feed.xml" rel="self" type="application/rss+xml"/>
        <pubDate>Tue, 09 Sep 2025 14:05:37 +0000</pubDate>
        <lastBuildDate>Tue, 09 Sep 2025 14:05:37 +0000</lastBuildDate>
        <generator>Jekyll v3.10.0</generator>
        
            <item>
                <title>Firefox iOS: Homepage Rebuild Project</title>
                <description>&lt;h1 id=&quot;overview&quot;&gt;Overview&lt;/h1&gt;
&lt;p&gt;This blog post goes over the homepage rebuild project for the Firefox iOS app, which I led and was dev complete by release version 138. This post is mainly a self reflection of the project and I hope to share my thoughts for those who are interested.&lt;/p&gt;

&lt;h2 id=&quot;homepage-feature&quot;&gt;Homepage Feature&lt;/h2&gt;
&lt;p&gt;Before I dive in, this post assumes some knowledge of how the Firefox homepage works from the user perspective. If you are unfamiliar with the homepage feature, there is a &lt;a href=&quot;https://github.com/mozilla-mobile/firefox-ios/wiki/Application-overview#firefox-homepage&quot;&gt;brief wiki&lt;/a&gt; that gives an overview of the homepage feature. You can read more details there and feel free to &lt;a href=&quot;https://cyndichin.github.io/contact/&quot;&gt;reach out&lt;/a&gt; to me if you have further questions!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/ios/homepageRebuildProject/04-feature.png&quot; alt=&quot;Homepage Feature&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;background-context&quot;&gt;Background Context&lt;/h2&gt;
&lt;h3 id=&quot;proposal&quot;&gt;Proposal&lt;/h3&gt;
&lt;p&gt;The homepage is one of the main features in the Firefox app and we want to contiously improve and enhance the experience for our users. There was a time when our homepage code caused app crashes every other week.&lt;/p&gt;

&lt;p&gt;One common crash that the homepage was facing was caused by the collection view layout becoming out of sync with the underlying data—often triggered by tab actions like closing tabs. This inconsistent state led to crashes when the layout expected more cells than the data could provide. There were also unsafe access patterns, like reading from arrays without bounds checks and thread-unsafe data updates in general.&lt;/p&gt;

&lt;p&gt;To put out the fires, the team implemented temporary patches and band-aid fixes to help stabilize the application. However, these fixes were never intended to be long term solutions, as they make the code brittle and difficult to update.&lt;/p&gt;

&lt;p&gt;Knowing that in the near future we want to experiment on the homepage, we took this opportunity to propose rebuilding the homepage instead of refactoring it. Therefore, a proposal was written to compare the two options with a recommendation to rebuild the homepage, which was eventually approved.&lt;/p&gt;

&lt;p&gt;In the long-term, rebuilding will achieve the following benefits compared to refactoring:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;less dev time in untangling code&lt;/li&gt;
  &lt;li&gt;less effort in pulling apart dependencies&lt;/li&gt;
  &lt;li&gt;avoid encountering unknowns that arise when refactoring&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By investing in a complete rebuild, we ensure the homepage will not only perform better, but also make it easier for future development and feature expansion.&lt;/p&gt;

&lt;p&gt;With the approval, we began the homepage rebuild project.&lt;/p&gt;

&lt;h3 id=&quot;goal&quot;&gt;Goal&lt;/h3&gt;
&lt;p&gt;The main goal of the project was to rebuild the homepage by integrating Redux for state management and using diffable data source to allow the UI to respond better to changes in the underlying data. Previously, the homepage was reloading an unnecessary large amount of times which also caused poor user experience such as flickering icons and diffable data source solves this by making updates on the differences.&lt;/p&gt;

&lt;p&gt;There were 3 main key objectives that were listed out for this project:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A. Centralized State Management with Redux&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Implement Redux architecture to centralize and standardize state management across the homepage. Each section in the homepage will have itself contained Redux components if needed. Redux will provide a single source of truth, making it easier to track, debug, and manage state transitions for each homepage section. This should significantly reduce the likelihood of state-related bugs, eliminate some usage of delegates and provide a single directional flow of information.&lt;/p&gt;

&lt;p&gt;An example of a section using Redux architecture:
The Top Sites section will have its own state &lt;a href=&quot;https://github.com/mozilla-mobile/firefox-ios/blob/main/firefox-ios/Client/Frontend/Home/Homepage%20Rebuild/TopSites/TopSitesSectionState.swift&quot;&gt;(TopSitesSectionState)&lt;/a&gt;, action &lt;a href=&quot;https://github.com/mozilla-mobile/firefox-ios/blob/main/firefox-ios/Client/Frontend/Home/Homepage%20Rebuild/TopSites/TopSitesAction.swift&quot;&gt;(TopSitesAction)&lt;/a&gt; and middleware &lt;a href=&quot;https://github.com/mozilla-mobile/firefox-ios/blob/main/firefox-ios/Client/Frontend/Home/Homepage%20Rebuild/TopSites/TopSitesMiddleware.swift&quot;&gt;(TopSitesMiddleware)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;B. Enhanced UI Updates with Diffable Data Source&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Integrate diffable data source to manage dynamic content updates in the UI. This will allow the system to efficiently handle changes to the data model, such as insertions, deletions, and reordering of elements, without requiring full updates in reloading the whole collection view, which we are doing currently. This will lead to smoother and more performant UI transitions and less crashes in terms of inconsistencies between data and UI.&lt;/p&gt;

&lt;p&gt;This implementation can be found in &lt;a href=&quot;https://github.com/mozilla-mobile/firefox-ios/blob/main/firefox-ios/Client/Frontend/Home/Homepage%20Rebuild/HomepageDiffableDataSource.swift&quot;&gt;HomepageDiffableDataSource&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C. Improved Stability, Reliability + Maintainability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The combination of Redux and diffable data source is expected to enhance the stability and reliability of the homepage. By reducing the complexity of state and UI management, we aim to eliminate crashes and other issues that have previously affected the user experience. The improved architecture will also make the codebase more robust and easier to extend in the future. The goal is to facilitate easier onboarding to our homepage code, faster development cycles, and more straightforward debugging and feature enhancements.&lt;/p&gt;

&lt;p&gt;From testing, there have been minimal bugs, but as of writing this blog, we are still running the experiment and confirming with metrics is still to be determined.&lt;/p&gt;

&lt;h3 id=&quot;expected-outcomes&quot;&gt;Expected Outcomes&lt;/h3&gt;
&lt;p&gt;More maintainable and scalable homepage architecture for future development&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Reduced instances of crashes&lt;/li&gt;
  &lt;li&gt;Improved application stability&lt;/li&gt;
  &lt;li&gt;Ease of development and iteration&lt;/li&gt;
  &lt;li&gt;Enhance user experience through smoother + more responsive UI updates&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;project-development&quot;&gt;Project Development&lt;/h1&gt;
&lt;p&gt;This project was in development from October 2024 until April 2024, but was not worked 100% capacity (i.e. vacation time and work weeks).&lt;/p&gt;

&lt;h2 id=&quot;set-up&quot;&gt;Set Up&lt;/h2&gt;
&lt;p&gt;During the initial stages of development, there were a couple of actions taken before pure code implementation.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Estimation&lt;/strong&gt;: To give better estimates on the project, I created a spreadsheet that outline the different tasks.  Originally, the estimation provided was with two full time engineers, but due to re-prioritization it became mainly one engineer at a time.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Epic&lt;/strong&gt;: Created separate tasks that needed to be complete for the project.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Public channel&lt;/strong&gt;: Created a public communication channel so that the team and stakeholders can view any questions or status updates.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Documentation&lt;/strong&gt;: Internal doc that was created (I reused some of that information here).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Architecture Diagram&lt;/strong&gt;: Created initial diagram to confirm with the team on the architecture before implementing. Updated and used this diagram to perform handoff to engineers that will be working on the new homepage features.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/images/ios/homepageRebuildProject/01-diagram.png&quot; alt=&quot;Architecture Diagram&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;implementing-new-homepage&quot;&gt;Implementing New Homepage&lt;/h2&gt;
&lt;p&gt;The homepage rebuild project has been implemented and dev complete (aside from some nice to haves). Most of the new code can be found in the &lt;a href=&quot;https://github.com/mozilla-mobile/firefox-ios/tree/main/firefox-ios/Client/Frontend/Home/Homepage%20Rebuild&quot;&gt;Homepage Rebuild folder&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/ios/homepageRebuildProject/02-directory.png&quot; alt=&quot;Homepage Rebuild Directory&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;phase-breakdown&quot;&gt;Phase Breakdown&lt;/h3&gt;
&lt;p&gt;Due to the large scope of the homepage, the rebuild project was broken up into two phases. The phases were also a way to help QA test and familiarize with the homepage rebuild project without waiting until full completion. This would help catch issues earlier if needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase I&lt;/strong&gt; - Create a foundation for the homepage using diffable data source and compositional layout and start the Redux foundation for the following subsections:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Header&lt;/li&gt;
  &lt;li&gt;Top Sites Section&lt;/li&gt;
  &lt;li&gt;Pocket Section&lt;/li&gt;
  &lt;li&gt;Customize Homepage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also, includes wallpaper, context menu, scrolling logic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase II&lt;/strong&gt; - Continue to rebuild the other homepage subsections:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Messaging&lt;/li&gt;
  &lt;li&gt;Bookmarks Section&lt;/li&gt;
  &lt;li&gt;Jump Back In&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also, includes adding telemetry + adhering to our new telemetry naming guidelines.&lt;/p&gt;

&lt;p&gt;I foresaw that top sites and jump back in section would take the most time so I made sure to split the two in different phases to balance out the timeline. To help in keeping tracking with my progress, I would create a simple spreadsheet shown below, which really helps me when working on a self-led project.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/ios/homepageRebuildProject/03-tracker.png&quot; alt=&quot;Progress Tracker&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;new-telemetry-guidelines&quot;&gt;New Telemetry Guidelines&lt;/h3&gt;
&lt;p&gt;The biggest blocker of this project was having undefined telemetry guidelines. When we received the guideline to keep the telemetry consistent with previous implementation, it was discovered that there some flaws in the existing implemention. After discussion and review, we decided to implement new telemetry that adheres to our new telemetry naming guidelines (another initiative on the team), while keeping a few the same. Going forward, having telemetry requirements upfront and defined earlier would’ve helped move the project more quickly.&lt;/p&gt;

&lt;h3 id=&quot;writing-unit-tests&quot;&gt;Writing Unit Tests&lt;/h3&gt;
&lt;p&gt;One of the issues that the old homepage faced was flaky unit tests. Since the project was an opportunity to rewrite the homepage from the ground up, I wanted to make sure that I was developing with a TDD mindset and created solid tests. This prompted the wiki documentation - &lt;a href=&quot;https://github.com/mozilla-mobile/firefox-ios/wiki/Unit-Tests-Guidelines&quot;&gt;Unit tests guidelines&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The homepage project also led to developing unit tests for middlewares. This prompted creating the &lt;a href=&quot;https://github.com/mozilla-mobile/firefox-ios/blob/main/firefox-ios/firefox-ios-tests/Tests/ClientTests/Utils/StoreTestUtility.swift&quot;&gt;StoreTestUtility&lt;/a&gt; class and thanks to the collaboration with my team members, we also developed a better mock for testing middlewares. Our guidelines in testing with store is documented in this &lt;a href=&quot;https://github.com/mozilla-mobile/firefox-ios/wiki/Unit-Tests-Guidelines#mocking-the-store&quot;&gt;wiki&lt;/a&gt;. The issues with testing our Redux architecture is that our store and its middlewares are global and cause tests to be less isolated or testable. As we are moving forward to using a Redux architecture through the app, we are still learning what works best for our project. With that, we are still refining unit tests, such as needing to modify having the global middlewares set for the store. See more details in this &lt;a href=&quot;https://github.com/mozilla-mobile/firefox-ios/pull/26926&quot;&gt;PR&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;decision-table&quot;&gt;Decision Table&lt;/h3&gt;
&lt;p&gt;Throughout the project, there were many decisions made and changes to the homepage as well as clarification as what we wanted. Later in the development, I decided to create a decision table in the ongoing project document, but it would have been helpful to make this table earlier. A decision table is a visual tool that allows us to systematically list decisions considered and the outcomes. It helps teams ensure consistency and communicate decisions clearly.&lt;/p&gt;

&lt;h2 id=&quot;testing-the-new-homepage&quot;&gt;Testing the New Homepage&lt;/h2&gt;
&lt;p&gt;As of May 30, the new homepage is still under experimentation and hidden behind a feature flag. It can be tested in our nightly builds, or you if you pull down the Firefox iOS repo  (https://github.com/mozilla-mobile/firefox-ios), the feature flag has been enabled in dev mode by default. See details on configuration in &lt;a href=&quot;https://github.com/mozilla-mobile/firefox-ios/blob/8523c4d4697662405dd6e1eba2a05dab0bca89fa/firefox-ios/nimbus-features/homepageRebuildFeature.yaml#L3&quot;&gt;homepageRebuildFeature.yaml&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;checklist&quot;&gt;Checklist&lt;/h3&gt;
&lt;p&gt;While working on this project from end to end, I developed a checklist for myself that I hope to expand + continue for the future. Happy to hear any feedback on this list.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Initial Project Assignment&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Confirm design is finalized (+ went through design system review)&lt;/li&gt;
  &lt;li&gt;Confirm telemetry requirements defined&lt;/li&gt;
  &lt;li&gt;Create project documentation (notes / feature overview)&lt;/li&gt;
  &lt;li&gt;Create public communication channel&lt;/li&gt;
  &lt;li&gt;Create spike + develop initial architecture diagram&lt;/li&gt;
  &lt;li&gt;Create tickets in epic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Project Implementation&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Create spreadsheet with timeline + delegate tasks&lt;/li&gt;
  &lt;li&gt;Add unit tests / UI tests&lt;/li&gt;
  &lt;li&gt;Accessibility review&lt;/li&gt;
  &lt;li&gt;Post weekly status on Epic ticket or public channel&lt;/li&gt;
  &lt;li&gt;Confirm feature works in all themes / devices (iPad, iPhone, split view, multitasking)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Project Completion&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Finalize all documentation&lt;/li&gt;
  &lt;li&gt;Create QA Request&lt;/li&gt;
  &lt;li&gt;Experiment created (if needed)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;final-thoughts--wrap-up&quot;&gt;Final Thoughts + Wrap Up&lt;/h2&gt;
&lt;p&gt;Overall, I feel very fortunate to be able to work on this rewrite on a large feature using modern APIs and gained more confidence in working with our Redux architecture. Previously, I haven’t really worked with the homepage. With the homepage rebuild, I avoided going too much out of scope, so some areas are not adopting Redux fully and still follow MVVM (wallpapers) and the cell UI + data layer was reused. Having this experience, I was able to solidify my knowledge in diffable data source, compositional layout and improving our guidelines in Redux.&lt;/p&gt;

&lt;p&gt;Leading this project gives me more confidence to take on bigger projects. While I was able to break a complex project into separate tasks, I would like to have worked more closely with other engineers throughout the project. I was grateful that my teammate has also helped me with wallpapers and scrolling logic when I was out of office. During the time where we were both discussing the project, I really enjoyed to conversations and pairing we had.&lt;/p&gt;
</description>
                <pubDate>Thu, 29 May 2025 07:08:25 +0000</pubDate>
                <link>cyndichin.github.io/blog/homepagerebuildproject</link>
                <guid isPermaLink="true">cyndichin.github.io/blog/homepagerebuildproject</guid>
                
                <category>ios</category>
                
                <category>swift</category>
                
                <category>mobile</category>
                
                <category>firefox</category>
                
                <category>homepage</category>
                
                
            </item>
        
            <item>
                <title>Xcode Testing Tools</title>
                <description>&lt;blockquote&gt;
  &lt;p&gt;Part of the Mobile Development series&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;overview&quot;&gt;Overview&lt;/h1&gt;
&lt;p&gt;This blog post assumes you have some familiarity with Xcode and tests.&lt;/p&gt;

&lt;p&gt;Here are some Xcode tools that I use when writing tests to make sure that my tests are valuable.&lt;/p&gt;

&lt;h2 id=&quot;run-tests-repeatedly&quot;&gt;Run tests repeatedly&lt;/h2&gt;
&lt;p&gt;Running tests repeatedly helps catch issues early and provide a level of confidence that the tests are not flaky. In order to run tests repeatedly, this can be accomplished by going to the test navigator in Xcode and right clicking on the test that you would like to run repeatedly.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/ios/xcodeTestingTools/01-testNavigator.png&quot; alt=&quot;Test Navigator&quot; /&gt;&lt;/p&gt;

&lt;p&gt;After you select an option to run the tests repeatedly, then you should see a prompt pop up to specify some parameters. I usually keep the default settings and change the maximum repetitions to use 1000 times for individual test classes and 10 times for when I run the whole test suite.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/ios/xcodeTestingTools/02-testRepeatedlyPrompt.png&quot; alt=&quot;Test Repeatedly Prompt&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Select “Run” and can verify if your newly created tests have succeeded for all runs.&lt;/p&gt;

&lt;h2 id=&quot;check-code-coverage&quot;&gt;Check code coverage&lt;/h2&gt;
&lt;p&gt;Code coverage is a good way to indicate whether your tests are hitting certain code paths. It is a way of measuring how much production code the test code covers. This helps us discover whether we tested different paths of control flow.&lt;/p&gt;

&lt;p&gt;First, we need to make sure that code coverage is enabled in our Test Plan configurations. After selecting the test plan in the Project navigator, you should see a similar configuration as below. Ensure that the Code Coverage setting is On.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/ios/xcodeTestingTools/07-codeCoverageSetting.png&quot; alt=&quot;Code Coverage&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Next, I turn on the code coverage bar by navigating to the setting shown in the screenshot below. Then, I run the tests to see how much of the file is covered.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/ios/xcodeTestingTools/04-codecoverage.png&quot; alt=&quot;Code Coverage&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The coverage bar will show you the number of times a test has executed a part of the code. Green indicators show if the portion of a code has been reached, and red will be shown if no tests covers that specific part of the code. By using these indicators, this can help us confirm if we test multiple paths. Usually, the happy paths are covered, but its also important to cover other cases as well such as what happens when we return early.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/ios/xcodeTestingTools/09-codeCoverageBar.png&quot; alt=&quot;Code Coverage bar&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;view-the-reports&quot;&gt;View the reports&lt;/h2&gt;
&lt;p&gt;After running tests, I also look at the Tests and Coverage sections in the Report Navigator. The reports provides a high level overview on tests and the metrics related to the code coverage. By heading over to the report navigator, I can view the test results and view if there are any issues.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/ios/xcodeTestingTools/05-reportNavigator.png&quot; alt=&quot;Report Navigator&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Here is an example of what a Test report may look like. This may be useful to understand patterns, trends and issues that occurred when running tests.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/ios/xcodeTestingTools/06-testReport.png&quot; alt=&quot;Test Report&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Additionally, you can also view code coverage results from the Coverage report in the Report Navigator. This may be useful to understand gaps in coverage and areas that may need more testing.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/ios/xcodeTestingTools/08-codeCoverageReport.png&quot; alt=&quot;Coverage Report&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;wrap-up&quot;&gt;Wrap up&lt;/h2&gt;
&lt;p&gt;Overall, these are some handy tools that I use in Xcode while I am writing, viewing or troubleshooting tests. Hope sharing this will also help others who aren’t aware of these tools. 
In general, I enjoy writing tests because it gives me a sense of confidence in the code that I am writing and ensures that my production code is testable and decoupled. Additionally, it reaffirms that I understand
the code and provides me feedback when I am implementing requirements. The bonus for me that it can also catch bugs early on.&lt;/p&gt;

&lt;h2 id=&quot;more-resources&quot;&gt;More resources&lt;/h2&gt;
&lt;p&gt;To learn more about other Xcode tools, check out my other blog on debugging tools:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/Quick/Quick/blob/main/Documentation/en-us/README.md#documentation&quot;&gt;Xcode Debugging Tools&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Useful Apple Docs on testing tools:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.apple.com/documentation/xcode/determining-how-much-code-your-tests-cover#Enable-code-coverage-in-your-test-plan&quot;&gt;Apple Docs - Code Coverage&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.apple.com/documentation/xcode/updating-your-existing-codebase-to-accommodate-unit-tests&quot;&gt;Apple Docs - Updating tests&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
                <pubDate>Wed, 25 Sep 2024 05:16:33 +0000</pubDate>
                <link>cyndichin.github.io/blog/xcodetestingtools</link>
                <guid isPermaLink="true">cyndichin.github.io/blog/xcodetestingtools</guid>
                
                <category>ios</category>
                
                <category>swift</category>
                
                <category>mobile</category>
                
                <category>testing</category>
                
                
            </item>
        
            <item>
                <title>First Look into Quick + Nimble</title>
                <description>&lt;blockquote&gt;
  &lt;p&gt;Part of the Mobile Development series&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;quick--nimble-overview&quot;&gt;Quick + Nimble Overview&lt;/h1&gt;
&lt;p&gt;This blog post will document my initial investigation in using Quick + Nimble.&lt;/p&gt;

&lt;h2 id=&quot;what-is-quick--nimble&quot;&gt;What is Quick + Nimble?&lt;/h2&gt;
&lt;p&gt;Quick is a behavior driven development (BDD) testing framework and Nimble is a matching framework that helps make tests easier to read. Coupled together, they provide the advantage of being able to be very descriptive when writing unit tests in comparison to using XCTests.&lt;/p&gt;

&lt;h3 id=&quot;quick--nimble-vs-xctests&quot;&gt;Quick + Nimble vs. XCTests&lt;/h3&gt;
&lt;p&gt;Both frameworks have their advantages and disadvantages, so I created a chart to list down the positive and negatives from my experimentation, discussing with coworkers and surfing the interwebs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick + Nimble&lt;/strong&gt;&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Pros&lt;/th&gt;
      &lt;th&gt;Cons&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Supports BBD and acceptance testing better since tests are descriptive&lt;/td&gt;
      &lt;td&gt;Third Party Dependency&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Can easily read what is being tested&lt;/td&gt;
      &lt;td&gt;Does not have performance testing&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Structure is consistent with testing done across other languages and platforms&lt;/td&gt;
      &lt;td&gt;Learning curve for developers used to XCTests&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Easier to create subsets of tests in a suite&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Active community and open source project&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;strong&gt;XCTests&lt;/strong&gt;&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Pros&lt;/th&gt;
      &lt;th&gt;Cons&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Default native testing framework that is well integrated with Xcode&lt;/td&gt;
      &lt;td&gt;Hard to read and understand what is being tested&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Less of a learning curve&lt;/td&gt;
      &lt;td&gt;Assertion methods are not as thorough as the Nimble matching framework&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Can test performance&lt;/td&gt;
      &lt;td&gt;Less flexible in comparison&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Support for UI testing&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;When it comes to making a decision between the two, I lean towards using XCTests as the default testing framework for my personal project. However as the project gets bigger, then I will look into using a combination of both Quick + Nimble + XCTests. 
For a project in which there are more contributors and stakeholders, I can see the benefits of using Quick + Nimble as its easier to perform acceptance testing, understand the value of a tests and modularize the code.&lt;/p&gt;

&lt;h2 id=&quot;setting-up-quick--nimble-via-spm&quot;&gt;Setting Up Quick + Nimble via SPM&lt;/h2&gt;
&lt;p&gt;It was fairly easy to add the dependencies if your project is using the Swift Package Manager. Here is a snippet of what it looks like to add the frameworks in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Package.swift&lt;/code&gt; file.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;dependencies: [
    .package(url: &quot;https://github.com/Quick/Quick.git&quot;, from: &quot;7.3.0&quot;),
    .package(url: &quot;https://github.com/Quick/Nimble.git&quot;, from: 13.0.0&quot;),
]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;After adding the dependencies to the package, we can use them in a test target by adding them as products to the dependency section for the test target.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;.testTarget(
    name: &quot;DiscoverKitTests&quot;,
    dependencies: [
        &quot;DiscoverKit&quot;,
        .product(name: &quot;Quick&quot;, package: &quot;Quick&quot;), 
        .product(name: &quot;Nimble&quot;, package: &quot;Nimble&quot;)
    ]
)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can test if we incorporated the dependencies properly by importing the frameworks and creating a simple test file. For example, the following file that exists in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DiscoverKitTests&lt;/code&gt; target should not receive any compile errors after building. This is the start of writing a unit test.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;import Quick
import Nimble

@testable import DiscoverKit

final class DiscoverKistTests: AsyncSpec {
    override class func spec() {
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;quick-glance-at-writing-unit-tests-with-quick--nimble&quot;&gt;Quick Glance at Writing Unit Tests with Quick + Nimble&lt;/h2&gt;
&lt;p&gt;Quick provides uses a single function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;spec()&lt;/code&gt; to define a suite of test cases. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;spec()&lt;/code&gt; is can be composed of multiple sections which are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;describe()&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;context()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;it()&lt;/code&gt;.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;describe()&lt;/code&gt; - acts as a container and defines the behavior or action you want to test at a high level&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;context()&lt;/code&gt; - can be used if more details are needed to clarify a certain scenario that is being tested (optional)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;it()&lt;/code&gt; - used to define individual test cases as we would with a function in XCTests; expectation checks belong here.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;import Quick
import Nimble

@testable import DiscoverKit

final class DiscoverKistTests: AsyncSpec {
    override class func spec() {
        describe(&quot;the Discover tab&quot;) {
            it(&quot;shows loading state at initial load&quot;) {
                ...
            }
            it(&quot;shows recommendation list after fetch&quot;) {
                ...
            }
            it(&quot;shows error state after fetching error&quot;) {
                ...
            }
        }
    }
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When writing a test, the above constructs are used to organize the test cases within the suite. There are also other constructs to know such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;beforeEach&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;afterEach&lt;/code&gt; that acts similar to setting up and tear down of a tests. Although it looks like one giant test case if you are used to creating a function per test case with XCTests, you can still run the individual &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;it&lt;/code&gt; test cases by going to the test navigator and selecting on the test you want.&lt;/p&gt;

&lt;p&gt;Within each test case, we want to validate and fulfill test expectations. Nimble provides that power through using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;expect()&lt;/code&gt;, which replaces assertions from XCTests. There are a wide range of different matchers that can be used, some examples are:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# Checking if two values are equal
expect(value).to(equal(expectedValue))

# Checking if boolean is true
expect(isHappy).to(beTrue())

# Checking if result is nil
expect(result).to(beNil())

# Checking if collection contains a string
expect(books).to(contain(&quot;Harry Potter&quot;))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;p&gt;To learn more about Quick + Nimble, here are some useful resources that dives deeper into the framework:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://swiftpackageindex.com/Quick/Quick&quot;&gt;Swift Package Index - Quick&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://swiftpackageindex.com/Quick/Nimble&quot;&gt;Swift Package Index - Nimble&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/Quick/Quick&quot;&gt;Official Repository - Quick&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/Quick/Nimble&quot;&gt;Official Repository - Nimble&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/Quick/Quick/blob/main/Documentation/en-us/README.md#documentation&quot;&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
                <pubDate>Wed, 18 Oct 2023 09:16:33 +0000</pubDate>
                <link>cyndichin.github.io/blog/quickandnimble</link>
                <guid isPermaLink="true">cyndichin.github.io/blog/quickandnimble</guid>
                
                <category>ios</category>
                
                <category>swift</category>
                
                <category>mobile</category>
                
                <category>testing</category>
                
                
            </item>
        
            <item>
                <title>SwiftUI and Architecture Considerations</title>
                <description>&lt;blockquote&gt;
  &lt;p&gt;Part of the Mobile Development series&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;swiftui-overview&quot;&gt;SwiftUI Overview&lt;/h1&gt;
&lt;p&gt;This blog post will go over my current understanding of SwiftUI and existing architectures that can be used to apply.&lt;/p&gt;

&lt;h2 id=&quot;what-is-swiftui&quot;&gt;What is SwiftUI?&lt;/h2&gt;
&lt;p&gt;In iOS development, there are two popular frameworks used to build user interfaces for apps in the Apple ecosystem, which are SwiftUI and UIKit. SwiftUI is a UI framework that takes a more declarative approach in developing apps for Apple’s ecosystem. While there have been many discussions surrounding architectures around UIKit, I’m curious to understanding and see what discussions there have been regarding SwiftUI architecture and whether we can apply the same solutions.&lt;/p&gt;

&lt;p&gt;SwiftUI is becoming more popular in the iOS development community and was introduced in iOS 13 as a way to simplify the development process in creating UI for apps. The decision to choose between SwiftUI and UIKit is largely depending on the development goals for the app and complexity. For the purpose of this post, we will focus on SwiftUI and consider various architectures that can be applied.&lt;/p&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;p&gt;To learn more about SwiftUI, here are some useful resources that dives deeper into the framework:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.apple.com/documentation/swiftui&quot;&gt;Apple Documentation on SwiftUI&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.google.com/search?client=safari&amp;amp;rls=en&amp;amp;q=hacking+with+swift&amp;amp;ie=UTF-8&amp;amp;oe=UTF-8&quot;&gt;100 Days of SwiftUI&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://cs193p.sites.stanford.edu&quot;&gt;Stanford’s Course on Developing Apps for iOS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;common-architecture-patterns&quot;&gt;Common Architecture Patterns&lt;/h1&gt;
&lt;p&gt;There are several architecture patterns that are floating around when it comes to iOS development. Reading &lt;a href=&quot;https://www.objc.io/books/app-architecture/&quot;&gt;objc’s app architecture book&lt;/a&gt;, I have learned some sample iOS application design patterns in Swift. Although the examples in the book were using UIKit as the framework for building user interfaces, this has led me to ponder about the different architectures that can be developed with the SwiftUI framework.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;MVC - Model-View-Controller&lt;/li&gt;
  &lt;li&gt;MVVM-C - Model-View-ViewModel + Coordinator&lt;/li&gt;
  &lt;li&gt;MVC-VS - Model-View-Controller+ViewState&lt;/li&gt;
  &lt;li&gt;MAVB - ModelAdapter-ViewBinder&lt;/li&gt;
  &lt;li&gt;ELM - The Elm Architecture&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There isn’t one solution or one way to architect an application and the decision is mainly a group discussion with the developers that are working on the application. This is the beauty of programming where we get to use our creative mindset to determine how to program so that we maintain a solid foundation for an application that is constantly iterating and changing.&lt;/p&gt;

&lt;h2 id=&quot;swiftui-architecture-in-pockets-ios-app&quot;&gt;SwiftUI Architecture in Pocket’s iOS App&lt;/h2&gt;
&lt;p&gt;My main experience with building an application in SwiftUI is through Pocket’s iOS app. Therefore, I will briefly outline what the current architecture that the Pocket currently uses for their iOS app. Although there still needs to be discussion, let’s analyze the current architecture as it is in this open source repository: https://github.com/Pocket/pocket-ios&lt;/p&gt;

&lt;p&gt;Currently, the project has a mix of UIKit and SwiftUI, but we’re moving towards replacing as many of our UIKit views with SwiftUI views. When creating these SwiftUI views, we are following the MVVM architecture approach.&lt;/p&gt;

&lt;p&gt;MVVM (Model-View-ViewModel) allows us to separate the state and logic handling from our views into classes called view models. Our view models typically conform to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ObservableObject&lt;/code&gt; protocol so that changes can be reported back to the view. The view that wants to make UI updates based on the viewmodel will create a property variable with the view model as its type. By making this separation, we can write tests for our code more easily. We create &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@Published&lt;/code&gt; properties in the view model class to announce when changes occur and SwiftUI will monitor those changes.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;class ViewModel: ObservableObject {
  @Published private(set) var model: Model
}

struct ContentView: View {
  @ObservedObject var viewModel: ViewModel
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;architectures-aside-mvvm&quot;&gt;Architectures aside MVVM&lt;/h1&gt;
&lt;p&gt;There are resources out there that argue the use of MVVM for SwiftUI. Some argue that MVVM is over engineering the code as mentioned in this &lt;a href=&quot;https://developer.apple.com/forums/thread/699003&quot;&gt;thread&lt;/a&gt;. 
One popular architecture that I noticed was the The Composable Architecture (TCA) developerd by &lt;a href=&quot;https://github.com/pointfreeco/swift-composable-architecture&quot;&gt;pointfree&lt;/a&gt;. I hope to investigate this architecture future and will expand upon this blog post with my learnings from there.&lt;/p&gt;

&lt;h2 id=&quot;considerations&quot;&gt;Considerations&lt;/h2&gt;
&lt;p&gt;As we move forward to adopting a mindset of using SwiftUI as our main framework for building our user interface elements, there are some considerations that we want to keep in mind.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Dependency Injection: improve our existing DI patterns; consider using SwiftUI’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Environment&lt;/code&gt; class to handle this&lt;/li&gt;
  &lt;li&gt;Architecture: while we are using the MVVM approach, we may not need a view model in cases where it may see overkill&lt;/li&gt;
  &lt;li&gt;Navigation: Previously, we utilized MVVM-C with our UIKit framework and our coordinators handled the presentation layer. However, we decided to remove this, but we may consider using NavigationPath as a way to organization our complex presentation&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;summary&quot;&gt;Summary&lt;/h1&gt;
&lt;p&gt;Overall, this is my initial research and consideration of using SwiftUI in applications. I will continue to iterate and expand this post as I learn about various architectures that can be considered. Any feedback is appreciated!&lt;/p&gt;
</description>
                <pubDate>Thu, 29 Jun 2023 04:43:03 +0000</pubDate>
                <link>cyndichin.github.io/blog/swiftuiarchitecture</link>
                <guid isPermaLink="true">cyndichin.github.io/blog/swiftuiarchitecture</guid>
                
                <category>ios</category>
                
                <category>swift</category>
                
                <category>mobile</category>
                
                <category>architecture</category>
                
                
            </item>
        
            <item>
                <title>Xcode Debugging Tools</title>
                <description>&lt;blockquote&gt;
  &lt;p&gt;Part of the Mobile Development series&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;xcode-debugging-tools&quot;&gt;Xcode Debugging Tools&lt;/h1&gt;
&lt;p&gt;As I started my official iOS career in 2020, there were some tips and tricks in using Xcode to debug issues that I picked up along the way. This is an ongoing post in which I’ll continue to add my lesson learns as I become exposed to them and find it useful to share with others.&lt;/p&gt;

&lt;p&gt;Most of the tools that we will be going over are listed in the debug menu shown below:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/ios/xcodeDebugging/01-debugMenu.png&quot; alt=&quot;Debug Menu&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;ui-test-recorder&quot;&gt;UI Test Recorder&lt;/h1&gt;
&lt;p&gt;Going from left to right, you’ll see a red record button. If you are planning on implementing UI tests, this is helpful in generating automatic code for you. First, create a UI test case and then press the record button which will run the simulator. Now, the recorder will attempt to write code that matches the actions you take in the Simulator. Although I tend to write the code myself, this is useful in understanding how Xcode will interpret your actions and can provide insight on some names and what type of element you are interacting with.&lt;/p&gt;

&lt;h1 id=&quot;view-hierarchy&quot;&gt;View Hierarchy&lt;/h1&gt;
&lt;p&gt;As someone who is passionate about the UI, I really like this view hierarchy because you can see the layers of different UI elements that are appearing. It is useful if you have some weird UI bug to address as and want to see what the hierarchy looks like and there are attributes for each element. 
&lt;img src=&quot;/images/ios/xcodeDebugging/02-viewhierarchy.png&quot; alt=&quot;View Hierarchy&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;memory-debugger&quot;&gt;Memory Debugger&lt;/h1&gt;
&lt;p&gt;Although I rarely use the memory debugger, it helps to know that this tool is available and provides more insight when there is a memory leak and you can see if an instance is created multiple times. This will give is a clue is something should be deallocated.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/ios/xcodeDebugging/03-memorydebugger.png&quot; alt=&quot;Memory Debugger&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;environment-overrides&quot;&gt;Environment Overrides&lt;/h1&gt;
&lt;p&gt;Accessibility is usually seen as the last thing and sometimes isn’t emphasized when it comes to building features. However, I definitely think it should be a consideration throughout if not at the beginning. The environmental overrides is useful for making sure that the app works in different environments. The environments could be based of dark mode, text sizes or other accessibility details.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/ios/xcodeDebugging/04-environmentoverrides.png&quot; alt=&quot;Environment Overrides&quot; /&gt;&lt;/p&gt;
</description>
                <pubDate>Wed, 07 Dec 2022 08:30:03 +0000</pubDate>
                <link>cyndichin.github.io/blog/xcodedebugtools</link>
                <guid isPermaLink="true">cyndichin.github.io/blog/xcodedebugtools</guid>
                
                <category>ios</category>
                
                <category>swift</category>
                
                <category>mobile</category>
                
                
            </item>
        
            <item>
                <title>SwiftLint Overview</title>
                <description>&lt;blockquote&gt;
  &lt;p&gt;Part of the Mobile Development series&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;swiftlint-overview&quot;&gt;SwiftLint Overview&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;What is SwiftLint?&lt;/strong&gt; A tool that allows us to enforce certain Swift style guide and conventions. It is an open source library and more details can be found here: &lt;a href=&quot;https://github.com/realm/SwiftLint&quot;&gt;https://github.com/realm/SwiftLint&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What are the benefits?&lt;/strong&gt; Having a consistent style guide across a codebase helps the repository become more readable and maintainable. Also, incorporating SwiftLint will prevent engineers from having to manually comment style nitpicks in open Pull Requests (PR) since SwiftLint will catch it.&lt;/p&gt;

&lt;p&gt;There are thorough details in how to install and use SwiftLint in the GitHub repository, but this post will walk through how SwiftLint was incorporated in the &lt;a href=&quot;https://github.com/realm/SwiftLint&quot;&gt;Pocket&lt;/a&gt; project using Swift Package Manager (SPM) specifically. We will also go into seeing how warnings and errors are generated for violating the SwiftLint rules and how we can create custom rules that are specific to our projects.&lt;/p&gt;

&lt;p&gt;This post will go over the following:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Installation&lt;/li&gt;
  &lt;li&gt;SwiftLint in Action&lt;/li&gt;
  &lt;li&gt;Custom Rules&lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;installation&quot;&gt;Installation&lt;/h1&gt;
&lt;h2 id=&quot;add-swiftlint-to-build-phase-in-pocket-ios&quot;&gt;Add SwiftLint to Build Phase in Pocket (iOS)&lt;/h2&gt;
&lt;p&gt;First, we want to add a Build Phase so that we run the swiftlint checks after each build.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/ios/swiftlint/01-buildphase.jpg&quot; alt=&quot;SwiftLint Build Phase&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Below is an example in the Pocket project, but feel free to configure the shell script differently.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;export PATH=&quot;$PATH:/opt/homebrew/bin&quot;

if which swiftlint &amp;gt; /dev/null; then
  if [ &quot;$CONFIGURATION&quot; = &apos;Debug&apos; ]; then
    swiftlint
  else 
    echo &quot;Skipping swift lint because it is not a local developer build.&quot;
  fi  
else
  echo &quot;warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint&quot;
fi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Next, we want to add the configuration file.&lt;/p&gt;

&lt;h2 id=&quot;create-the-swiftlint-configuration-file&quot;&gt;Create the SwiftLint Configuration File&lt;/h2&gt;

&lt;p&gt;Add a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.swiftlint.yml&lt;/code&gt; file in the directory you want to run the SwiftLint command from. This is what the file looks like in the Pocket repository: 
&lt;a href=&quot;https://github.com/Pocket/pocket-ios/blob/develop/.swiftlint.yml&quot;&gt;https://github.com/Pocket/pocket-ios/blob/develop/.swiftlint.yml&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are a set of rules that the SwiftLint can check for. There are two main groups:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;disabled_rules&lt;/code&gt;: Disable rules from the default enabled set.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;opt_in_rules&lt;/code&gt;: Enable rules that are not part of the default set.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Include and remove any rules that you want to apply the codebase. The rule directory is located here: https://realm.github.io/SwiftLint/rule-directory.html&lt;/p&gt;

&lt;p&gt;For more details on configuration: &lt;a href=&quot;https://github.com/realm/SwiftLint#configuration&quot;&gt;https://github.com/realm/SwiftLint#configuration&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;swiftlint-in-action&quot;&gt;SwiftLint in Action&lt;/h1&gt;
&lt;p&gt;Once you add the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.swiftlint.yml&lt;/code&gt; file, we can verify that swiftLint is checking that the codebase is adhering to the Swift Style rules. If you don’t see any warnings, we can see it in action with a simple test using the vertical whitespace rule (&lt;a href=&quot;https://realm.github.io/SwiftLint/vertical_whitespace.html&quot;&gt;https://realm.github.io/SwiftLint/vertical_whitespace.html&lt;/a&gt;). Make sure that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;disabled_rules&lt;/code&gt; does not include the identifier &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vertical_whitespace&lt;/code&gt;. Then go to any of your files and add a bunch of vertical line spaces. The following warning should appear:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/ios/swiftlint/02-warning.jpg&quot; alt=&quot;SwiftLint Warning&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now you have SwiftLint integrated and working in your project! If you don’t want to address the issues manually, there is a neat command to auto fix the issues: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;swiftlint --fix&lt;/code&gt;. Sometimes it can’t auto fix the issues, but it does a pretty great job from what I seen.&lt;/p&gt;

&lt;p&gt;If you are seeing the following issue &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-bash: swiftlint: command not found&lt;/code&gt;, you can run the following command &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;brew install swiftlint&lt;/code&gt; to make sure it is installed properly.&lt;/p&gt;

&lt;h1 id=&quot;custom-rules&quot;&gt;Custom Rules&lt;/h1&gt;
&lt;p&gt;As mentioned above, SwiftLint has a rule directory of all the different rules that you can disable or enabled depending on which set the rule belongs to. However, these set of rules are limited in numbers and at times we may want to add custom rules that are not included in the set from the directory. The custom rules uses regular expressions to capture any violations. For example, the rule below will warn if there is any string with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;internal func&lt;/code&gt; in the codebase. This custom rule is for demo purposes as it does not check whether it is redundant or not.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/ios/swiftlint/03-customrule.png&quot; alt=&quot;SwiftLint Custom Rule&quot; /&gt;&lt;/p&gt;

&lt;p&gt;There are many regex tools out there that we can use such as &lt;a href=&quot;https://regex101.com/&quot;&gt;https://regex101.com&lt;/a&gt; to help us test out these rules.&lt;/p&gt;

&lt;p&gt;You can also do a rule request by opening an issue on the open source repository as well: &lt;a href=&quot;https://github.com/realm/SwiftLint/issues&quot;&gt;https://github.com/realm/SwiftLint/issues&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;summary&quot;&gt;Summary&lt;/h1&gt;

&lt;p&gt;Overall, SwiftLint is amazing tool that I recommend integrating into your iOS projects at setup. It keeps you in check to make sure that a certain Swift Style is consistent across the codebase and becomes really helpful as a project has multiple engineers working on it. As always, feel free to reach out to me and provide any feedback or questions.&lt;/p&gt;
</description>
                <pubDate>Tue, 06 Dec 2022 08:03:03 +0000</pubDate>
                <link>cyndichin.github.io/blog/swiftlintoverview</link>
                <guid isPermaLink="true">cyndichin.github.io/blog/swiftlintoverview</guid>
                
                <category>ios</category>
                
                <category>swift</category>
                
                <category>mobile</category>
                
                
            </item>
        
            <item>
                <title>[OMSCS]  INTA 6450: Data Analytics + Security</title>
                <description>&lt;blockquote&gt;
  &lt;p&gt;Part of my OMSCS Review series&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;inta-6450-data-analytics--security&quot;&gt;INTA 6450: Data Analytics + Security&lt;/h1&gt;

&lt;p&gt;In Summer 2022, I completed my sixth course in the OMSCS Program at Georgia Tech, &lt;a href=&quot;https://omscs.gatech.edu/inta-6450-data-analytics-and-security&quot;&gt;Data Analytics and Security (INTA6450)&lt;/a&gt;. I was interested in this course because of the course project, which students can hone their data analytics skills on real world cybersecurity data. The data comes from NowSecure, a mobile app security company that the course has a partnership with. NowSecure scans all Android and iOS apps available on public app stores.&lt;/p&gt;

&lt;p&gt;With my background in security incident response and mobile development, I was interested to see how I can utilize my data analytic skills to find patterns and security vulnerabilities that are existing on mobile applications, which are installed on millions of devices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Topics Covered&lt;/strong&gt;: big data, linear regression, decision trees, clustering, probability, bayesian reasoning, neural nets, R, Python&lt;/p&gt;

&lt;h2 id=&quot;do-you-recommend-this-course&quot;&gt;Do you recommend this course?&lt;/h2&gt;
&lt;p&gt;I recommend taking this course for someone who wants an easy A course with a light workload. However, I wouldn’t take this course again because I didn’t learn too much and didn’t think I gain or improved my skillset. I did get a high level overview of big data and techniques used to perform data analytics, but it was at a superficial level and I doubt I will retain the information. The highlight for me was being able to gain access to a dataset that contained detailed analyses and reports of various mobile applications in the app store.&lt;/p&gt;

&lt;p&gt;This course may be more well suited for someone passionate about data analytics as Professor Borowitz was very friendly and passionate about the topic. Therefore, going to office hours may have provided someone who was interested in the topic with more value.&lt;/p&gt;

&lt;p&gt;Overall, I wouldn’t recommend this course unless you want to take an easy class or enjoy data analytics.&lt;/p&gt;

&lt;h2 id=&quot;course-overview&quot;&gt;Course Overview&lt;/h2&gt;
&lt;p&gt;The workload for this course was pretty light and I didn’t spend more than 5 hours a week on the course. I followed the syllabus, so I watched the lectures and completed the quizzes / discussions as they came out. The coding assignments were also easy because it was altering the code and then writing about those changes. Towards the end of the semester, it was a bit more time consuming as we had to complete the final project as a group.&lt;/p&gt;

&lt;h3 id=&quot;assignments&quot;&gt;Assignments&lt;/h3&gt;
&lt;p&gt;The assignments consisted of lecture activities (i.e. quiz, discussion posts), computing activities (i.e. R and Python tasks) and the final project. There were two options to pick from the project: Enron or NowSecure. I decided to choose NowSecure due to my interest in the mobile space. There were no exams.&lt;/p&gt;

&lt;p&gt;Here is the breakdown of the Assignments:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lecture Activities&lt;/strong&gt; (30%)&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Quizzes (9 total) - 50 points each&lt;/li&gt;
  &lt;li&gt;Discussions (11 total) - 4 points each&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The quizzes were open book and you can find the answers exactly on the slides or videos from the lectures, so it is easy to do well on them. For the discussions, the grading was also easy as long as you answer all the questions. Discussions would consist of reading an article or getting your opinion on a topic relating to the the lectures of that week.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Computing Activities&lt;/strong&gt; (20%)&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;R Exercises (4 total) - 10 points each&lt;/li&gt;
  &lt;li&gt;Crime and Punishment Python Exercise (1 total) - 10 points each&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The programming exercises were essentially to just make changes or add extensions to the code that was already provided. It was a way to give exposure to different languages and some libraries that might be helpful for our project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project Activities&lt;/strong&gt; (50%)&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Course Project, Part 1 Proposal – 20 points&lt;/li&gt;
  &lt;li&gt;Course Project, Part 1 Peer Review – 10 points&lt;/li&gt;
  &lt;li&gt;Course Project, Part 2 Paper – 30 points&lt;/li&gt;
  &lt;li&gt;Course Project, Part 2 Presentation – 30 points&lt;/li&gt;
  &lt;li&gt;Course Project, Part 2 Presentation Peer Review – 5&lt;br /&gt;
points&lt;/li&gt;
  &lt;li&gt;Peer Review of Teammates – 5 points&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The project was very open ended and creativity was given to use in terms of how we wanted to analyze a dataset. Since I choose to do the NowSecure project, our project was to find security vulnerabilities and patterns that surrounding insecure applications.&lt;/p&gt;

&lt;p&gt;For Part 1, the proposal was an individual assignment where you create a proposal for the project. The project was very vague and the professor provided some templates in what direction you can take the project. My initial proposal was to focus on applications that have misconfigured APIs and using this finding to predict that the application is also prone to contain other features such as data leakage, exposure of excessive information, and lack of proper cryptographic methods.&lt;/p&gt;

&lt;p&gt;For Part 2, the paper and presentation were group assignments. We could utilize any of our proposals in Part 1, but our group decided to go with a different route. In general, the paper consist of our analytical goal for the project, the methodologies we used, results we found, whether those results were good and if we could fix or not fix any problems with the approach we used. Our project goal, specifically, was to implement a ML model that predicts whether an application is secure enough to be available in the Android marketplace and we did this using key attributes related to the &lt;a href=&quot;https://owasp.org/www-project-mobile-top-10/&quot;&gt;OWASP Top 10 Mobile Risks&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The presentation (~20 min) was to cover the information in our paper and project. We discussed the pattern of security risk we focused on and our results of these findings. Also, we described what our limitations were and future enhancements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Make sure to get a good group for the course project.&lt;/p&gt;

&lt;h2 id=&quot;how-do-i-prepare-for-this-course&quot;&gt;How do I prepare for this course?&lt;/h2&gt;
&lt;p&gt;It is helpful if you have prior knowledge of Python for the final project, but not necessary. It’s important to find great group members early on. I got lucky that I had a great group and everyone contributed / participated in the meetings. We also had a data scientist which helped as he had more expertise in creating machine learning models using python libraries.&lt;/p&gt;

&lt;h2 id=&quot;lessons-learned&quot;&gt;Lessons Learned&lt;/h2&gt;
&lt;p&gt;From this class, I got to exercise my muscles in using Python to parse JSON data. Also, I got exposure to analyzing a dataset that contain information about mobile applications. Aside from that, I honestly don’t have much main takeaways from this course and learned very little, which is why I wouldn’t take it the course again.&lt;/p&gt;
</description>
                <pubDate>Tue, 16 Aug 2022 09:48:00 +0000</pubDate>
                <link>cyndichin.github.io/blog/inta6450</link>
                <guid isPermaLink="true">cyndichin.github.io/blog/inta6450</guid>
                
                <category>omscs</category>
                
                <category>gatech</category>
                
                <category>education</category>
                
                
            </item>
        
            <item>
                <title>[Book Review] Essentialism by Greg Mckeown</title>
                <description>&lt;blockquote&gt;
  &lt;p&gt;Part of the Book Review series&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;book-review-essentialism-by-greg-mckeown&quot;&gt;Book Review: Essentialism by Greg Mckeown&lt;/h1&gt;

&lt;p&gt;Essentialism walks you through the mindset of an Essentialist and discusses how we can develop a systematic approach for determining what are the important things in our lives and how we can focus our energy in contributing to those essentials when making a decision. It is not about getting more things done, it is about getting the right things done.&lt;/p&gt;

&lt;p&gt;An essentialist is one who knows how to live a life true to oneself and how to discern what is important and eliminate what is not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rating:&lt;/strong&gt; 5/5&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/bookreview/essentialism/cover.jpg&quot; alt=&quot;Essentialism Cover&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;recommended-if&quot;&gt;Recommended If:&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;you constantly feel busy, but also feel like you aren’t being productive or getting things done&lt;/li&gt;
  &lt;li&gt;you want to make the best investment of your time and energy in contributing to only what is essential to you&lt;/li&gt;
  &lt;li&gt;feel obligated to live the life others have set for you&lt;/li&gt;
  &lt;li&gt;you are looking for an interesting read to expand your horizons&lt;/li&gt;
  &lt;li&gt;you reflect on your life and regret on the decision you made in the past as it wasn’t contributing to what you value&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;highlights&quot;&gt;Highlights&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;“Essentialism is a disciplined, systematic approach for determining where our highest point of contribution lies, then making execution of those things almost effortless”&lt;/li&gt;
  &lt;li&gt;“Living by design, not by default”&lt;/li&gt;
  &lt;li&gt;“If you don’t prioritize your life, someone else will”&lt;/li&gt;
  &lt;li&gt;“If the answer isn’t a definite yes, then is should be no”&lt;/li&gt;
  &lt;li&gt;“Essential Intent - makes one decision that eliminates 1,000 later decisions”&lt;/li&gt;
  &lt;li&gt;“Remember, forcing these people to solve their own problems is equally beneficial for you and for them”&lt;/li&gt;
  &lt;li&gt;“Every day do something that will inch you closer to a better tomorrow”&lt;/li&gt;
  &lt;li&gt;“Done is better than perfect”&lt;/li&gt;
  &lt;li&gt;“Learning essential new skills is never easy. But once we master them and make them automatic … the skill remains with us for the rest of our lives”&lt;/li&gt;
  &lt;li&gt;“Life is available only in the present moment, if you abandon the present moment you cannot live the moments of your daily life deeply”&lt;/li&gt;
  &lt;li&gt;“In work, do what you enjoy. In family life, be completely present.”&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;going-forward&quot;&gt;Going Forward&lt;/h1&gt;
&lt;p&gt;This book help me realize that we should enjoy the journey and not just focus on the destination. We are also in control of our own choices, so we should spend time on the few essentials as opposed to spreading yourself thin. After reading the different steps, I aim to incorporate the following into my life:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Schedule one hour of blank space every day to think and escape from the busy life&lt;/li&gt;
  &lt;li&gt;Keep a journal to identify patterns or trends as small, incremental changes are hard to see in the moment, but can have a huge cumulative effect&lt;/li&gt;
  &lt;li&gt;Have consistent sleep&lt;/li&gt;
  &lt;li&gt;Apply selective criteria to opportunities before I make a decision&lt;/li&gt;
  &lt;li&gt;Create my essential intent&lt;/li&gt;
  &lt;li&gt;Learn the slow “yes”, and quick “no”&lt;/li&gt;
  &lt;li&gt;Build in buffers to reduce the friction cause by the unexpected&lt;/li&gt;
  &lt;li&gt;Focus on small wins vs setting big goals&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is my second time reading the book and I enjoyed it as much as the first as I am someone who feels constantly busy and always says “yes” to all opportunities that comes to me. After the first read, I realize that I am better now in saying “no” and not taking on opportunities that are not essential. However, I am  constantly applying this systematic approach and still working on focusing on living in the present and appreciating the journey.&lt;/p&gt;

&lt;h1 id=&quot;summary&quot;&gt;Summary&lt;/h1&gt;
&lt;p&gt;The book was broken into four sections: essence, explore, eliminate, and execute.&lt;/p&gt;

&lt;h2 id=&quot;part-i-essence&quot;&gt;Part I: Essence&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What is the core mind-set of an Essentialist?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This section discusses what an Essentialist is and how they choose, discern and view trade-offs. The way of the Essentialist is to practice the idea of &lt;strong&gt;less but better&lt;/strong&gt;. This is achieved in a disciplined way by saying “no” more and to pause to think if you are investing in the right activities. As there are many more opportunities now, especially with technology around, an Essentialist learns to filter through all the different options to select what is truly essential to them. This way we make significant progress in the things that matter.&lt;/p&gt;

&lt;p&gt;Nonessentialism is everywhere as we have too many choices, too much social pressure, and the constant idea of ‘you can have it all’. The core mind-set of an essentialist contains the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;We can choose how to spend our energy and time vs. I have to do it&lt;/li&gt;
  &lt;li&gt;Only a few thing really matter vs. It’s all important&lt;/li&gt;
  &lt;li&gt;The reality of trade-offs (we can’t have it all or do it all) vs. I can do both&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The next parts of the book describe the system that we can go through to obtain the mindset of an essentialist, which can be broken up to three components: explore, eliminate and execute. This process can be applied when making a decision.&lt;/p&gt;

&lt;h2 id=&quot;part-ii-explore&quot;&gt;Part II: Explore&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;How can we discern the trivial many from the vital few?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To explore is the beginning stage where we want to evaluate our professional and personal lives and understand what activities or efforts we want to focus on. In this stage, ask yourself three questions:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;What do you feel inspired by?&lt;/li&gt;
  &lt;li&gt;What are you particularly talened at?&lt;/li&gt;
  &lt;li&gt;What meets a significant need in the world?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The book breaks this section into escape, look, play, sleep and select.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Escape:&lt;/strong&gt; it is critical to set time to think, breadth and observe; this allows us to have clarity and space to explore different possibilities and options&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Look:&lt;/strong&gt; be a journalist of your own life to avoid focusing on the details and see the bigger picture; hear what is not being said and find the essential information&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Play:&lt;/strong&gt; do simply for joy rather than a means to an end; play sparks exploration and expand our minds&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Sleep:&lt;/strong&gt; sleep enables the highest level of contribution and is a priority&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Select:&lt;/strong&gt; be selective, explicit and right by saying yes only to top 10% of the opportunities&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;part-iii-eliminate&quot;&gt;Part III: Eliminate&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;How can we cut out the trivial many?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To eliminate is to actively get rid of those that do not make the highest possible contribution. By eliminating, we earn the time necessary to achieve what is essential. In this stage, ask yourself these questions:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;What out of my priorities, will I say no to?&lt;/li&gt;
  &lt;li&gt;If I didn’t already own this, how much will I spend to buy it?&lt;/li&gt;
  &lt;li&gt;If we could be truly excellent at one thing, what would it be?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The book breaks this section into clarify, dare, uncommit, edit and limit.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Clarify:&lt;/strong&gt; be clear about your purpose as motivation and cooperation can deteriorate when there is none&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Dare:&lt;/strong&gt; a clear “no” can be more graceful than a vague or noncommital “yes”&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Uncommit:&lt;/strong&gt; sunk-cost bias to continue to invest time and energy into something because we already incurred a cost that cannot be recouped; tendency is to undervalue things that aren’t ours and overvalue things because we already own them&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Edit:&lt;/strong&gt; cutting, condensing and correcting enable us to check ourselves&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Limit:&lt;/strong&gt; know your boundaries and set rules for a direct “no”&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;part-iv-execute&quot;&gt;Part IV: Execute&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;How can we make doing the vital few things almost effortless?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To execute is to create a process that makes getting the essential things done as effortless as possible. After understanding what efforts to keep in our life, we want a system that is routine to execute the essential things as easy as possible.&lt;/p&gt;

&lt;p&gt;The book breaks this section into buffer, subtract, progress, flow, focus, and be.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Buffer:&lt;/strong&gt; be prepared and build a buffer for unexpected events, planning fallacy is a phenonmenon that people tend to underestimate how long a task will take (even when they done it before)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Subtract:&lt;/strong&gt; understand what obstacle is keeping you back from achieving what really matters and how to remove them&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Progress:&lt;/strong&gt; start small and get big results, don’t go for the flashiest wins as small and concrete wins create momentum and affirms further success; there is power in steadiness and repetition&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Flow:&lt;/strong&gt; expend a small amount of initial energy to reate the routine and then executing the essentials will be autopilot&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Focus:&lt;/strong&gt; every second spent worrying about a past or future moment distracts us from what is important in the here and now, so focus on the now and be present&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Be:&lt;/strong&gt; the life of an Essentialist is a life of meaning and a life that really matters; live a life without regret&lt;/li&gt;
&lt;/ul&gt;

</description>
                <pubDate>Wed, 29 Dec 2021 06:11:03 +0000</pubDate>
                <link>cyndichin.github.io/blog/bookreviewessentialism</link>
                <guid isPermaLink="true">cyndichin.github.io/blog/bookreviewessentialism</guid>
                
                <category>book review</category>
                
                <category>essentialism</category>
                
                
            </item>
        
            <item>
                <title>[OMSCS] CS7632: Game AI</title>
                <description>&lt;blockquote&gt;
  &lt;p&gt;Part of my OMSCS Review series&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;cs7632-game-ai&quot;&gt;CS7632: Game AI&lt;/h1&gt;

&lt;p&gt;In Fall 2021, I completed my fourth course in the OMSCS Program at Georgia Tech, &lt;a href=&quot;https://omscs.gatech.edu/cs-7632-game-ai&quot;&gt;Game AI (CS7632)&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;I love playing video games and I was curious to see how AI agents are working behind the scenes, especially in games like Chess. Last semester, I took Artificial Intelligence and this class gave me a better insight on how it can be applicable to games. Overall, we learned about the role of AI in games and our assignments were based on implementing algorithms for different aspects of a game.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Topics Covered&lt;/strong&gt;: agent movement, path planning, decision making, goal-oriented behavior, learning, and procedural content generation&lt;/p&gt;

&lt;h2 id=&quot;do-you-recommend-this-course&quot;&gt;Do you recommend this course?&lt;/h2&gt;

&lt;p&gt;I highly recommend taking this course for someone who has taken AI and enjoy learning about how games work.&lt;/p&gt;

&lt;p&gt;The workload was a lot easier than CS6600: Artificial Intelligence, but a bit more time consuming than &lt;a href=&quot;https://cyndichin.github.io/blog/omscs6300&quot;&gt;CS6300: Software Development Process&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Professor Wilson was really responsive in Piazza and he was very nice in answering our questions about the assignments. The Slack channel was active, but I didn’t feel that I needed it as much as the assignments weren’t too difficult. Overall, I enjoy learning about AI being used in games, but not sure how practical this knowledge will be during my day to day.&lt;/p&gt;

&lt;h2 id=&quot;course-overview&quot;&gt;Course Overview&lt;/h2&gt;

&lt;p&gt;This course opens you up to consider how AI in academia differs from AI in games. For example, in games, we may want to dumb down the AI to make the gameplay more fun for the user. There is a sweet line when it comes to user experience as we want to avoid anxiety from a difficult game, but also avoid boredom.&lt;/p&gt;

&lt;p&gt;I found myself putting in 8 - 10 hours a week for this course and would say that most people get 100s on the assignments, so an A is doable. I wouldn’t say it was an easy A. The lectures were a bit slow, so I had to increase them to 2x speed. They also had transcripts for the lectures which was helpful during the exam.&lt;/p&gt;

&lt;p&gt;Since the assignments are in Unity, you will be using C#. I didn’t have much experience in C#, but knowing other languages help me ramp on it. The class was very organized and the professor was super responsive.&lt;/p&gt;

&lt;h3 id=&quot;assignments&quot;&gt;Assignments&lt;/h3&gt;

&lt;p&gt;Here is the breakdown of the Assignments:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Assignment 0 - &lt;a href=&quot;https://learn.unity.com/project/roll-a-ball&quot;&gt;“Roll-A-Ball” Unity Tutorial&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Assignment 1 - Grid Lattice&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/images/omscs/7632/assignment1.png&quot; alt=&quot;Assignment1&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Assignment 2 - Path Network&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/images/omscs/7632/assignment2.png&quot; alt=&quot;Assignment2&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Assignment 3 - AStar Pathfinding&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/images/omscs/7632/assignment3.png&quot; alt=&quot;Assignment3&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Assignment 4 - Navigation Mesh Generation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/images/omscs/7632/assignment4.png&quot; alt=&quot;Assignment4&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Assignment 5 - Decision Making with Finite State Machines (Prison Dodgeball)
    &lt;ul&gt;
      &lt;li&gt;There was a tournament that you could have participated to get extra points, but I didn’t not go through it as I didn’t think my implementation was that great.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;figure class=&quot;video_container&quot;&gt;
  &lt;video controls=&quot;true&quot; allowfullscreen=&quot;true&quot;&gt;
    &lt;source src=&quot;/videos/omscs7632/prison_dodgeball.mov&quot; type=&quot;video/mp4&quot; /&gt;
  &lt;/video&gt;
&lt;/figure&gt;

&lt;ul&gt;
  &lt;li&gt;Assignment 6 - Race Track
    &lt;ul&gt;
      &lt;li&gt;This was my favorite assignment because it was fun to see how I can create rules that trigger the vehicle to move right or left on its own depending on its position.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;figure class=&quot;video_container&quot;&gt;
  &lt;video controls=&quot;true&quot; allowfullscreen=&quot;true&quot;&gt;
    &lt;source src=&quot;/videos/omscs7632/race_track.mov&quot; type=&quot;video/mp4&quot; /&gt;
  &lt;/video&gt;
&lt;/figure&gt;

&lt;ul&gt;
  &lt;li&gt;Assignment 7 - Procedural Content Generation
    &lt;ul&gt;
      &lt;li&gt;This was the easiest assignment as there was no coding involved and was more about tweaking parameters in Unity. However, some students got creative with applying textures.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/images/omscs/7632/assignment7.png&quot; alt=&quot;Assignment7&quot; /&gt;&lt;/p&gt;

&lt;p&gt;With each assignment (except the last one), there were regrade opportunities. You are allowed two weeks for assignments, so I never felt pressured to stay up late to finish an assignment. The hardest assignment for me was the Finite State Machine (Prison Dodgeball) assignment.&lt;/p&gt;

&lt;h3 id=&quot;exams&quot;&gt;Exams&lt;/h3&gt;

&lt;p&gt;There was a midterm and a final (non cumulative). Both exams were open book and allowed 4 hours, which was more than enough. My score for the final was around the same as the midterm so the difficulty was fairly the same. The professor did curve the midterm which helped me retain an A.&lt;/p&gt;

&lt;h2 id=&quot;how-do-i-prepare-for-this-course&quot;&gt;How do I prepare for this course?&lt;/h2&gt;

&lt;p&gt;To prepare for this course, you can start with the Unity Tutorial (mentioned as Assignment 0 above). All of the assignments are done in Unity so a familiarity with that helps. Additionally, I recommend taking AI as some of the concepts in that course was reiterated in this class.&lt;/p&gt;

&lt;h2 id=&quot;lessons-learned&quot;&gt;Lessons Learned&lt;/h2&gt;

&lt;p&gt;From this course, I was able to understand how AI is applied to games. I was able to learn how to use Unity and C# to complete some projects. This class inspired me to learn how to create games in Swift so I purchased this book: &lt;a href=&quot;https://www.amazon.com/Apple-Game-Frameworks-Technologies-SpriteKit/dp/1680507842/ref=asc_df_1680507842/?tag=hyprod-20&amp;amp;linkCode=df0&amp;amp;hvadid=475772560923&amp;amp;hvpos=&amp;amp;hvnetw=g&amp;amp;hvrand=15972973116241648922&amp;amp;hvpone=&amp;amp;hvptwo=&amp;amp;hvqmt=&amp;amp;hvdev=c&amp;amp;hvdvcmdl=&amp;amp;hvlocint=&amp;amp;hvlocphy=9004148&amp;amp;hvtargid=pla-1186423385486&amp;amp;psc=1&quot;&gt;Apple Game Frameworks and Technologies: Build 2D Games with SpriteKit &amp;amp; Swift by Tammy Coron&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Topics Covered:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;How to create discretized spaces so that agents can move throughout the game world&lt;/li&gt;
  &lt;li&gt;How agents plan their paths whether using a grid lattice or navmesh to generate areas where they can move to&lt;/li&gt;
  &lt;li&gt;Understanding how agents make a decision depending on the circumstances that are occuring in the game state&lt;/li&gt;
  &lt;li&gt;In learning, we have exploitation and exploration where there is a balance between whether we want to explore or go down the path we believe has the highest reward&lt;/li&gt;
  &lt;li&gt;Games like minecraft uses procedural content generation to generate their terrain&lt;/li&gt;
  &lt;li&gt;Other topics: camera control, minimax, Monte Carlo Tree Search&lt;/li&gt;
&lt;/ul&gt;
</description>
                <pubDate>Mon, 13 Dec 2021 12:07:55 +0000</pubDate>
                <link>cyndichin.github.io/blog/omscs7632</link>
                <guid isPermaLink="true">cyndichin.github.io/blog/omscs7632</guid>
                
                <category>omscs</category>
                
                <category>gatech</category>
                
                <category>education</category>
                
                
            </item>
        
            <item>
                <title>[OMSCS] CS6300: Software Development Process</title>
                <description>&lt;blockquote&gt;
  &lt;p&gt;Part of my OMSCS Review series&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;cs6300-software-development-process&quot;&gt;CS6300: Software Development Process&lt;/h1&gt;

&lt;p&gt;In Spring 2021, I completed my second course in the OMSCS Program at Georgia Tech, &lt;a href=&quot;http://omscs.gatech.edu/cs-6300-software-development-process&quot;&gt;Software Development Process (CS6300)&lt;/a&gt;. I wanted to take this course because I am at the entry point of my career and wanted to get better insight on improving my software engineering skills.&lt;/p&gt;

&lt;p&gt;As someone who didn’t graduate from a CS degree, I thought this was a good foundational course to improve my software engineering fundamentals and become a better developer. Overall, we learned about various software engineering practices and methodologies as well as implementing them through projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Topics Covered&lt;/strong&gt;: git commands, basic android development, object oriented design, design documentation (i.e. requirements, test cases, use cases), white-box and black-box testing, agile methodologies, test-driven development (TDD), refactoring&lt;/p&gt;

&lt;h2 id=&quot;do-you-recommend-this-course&quot;&gt;Do you recommend this course?&lt;/h2&gt;

&lt;p&gt;I highly recommend taking this course for someone who doesn’t have much experience in software development or software engineering. It provides a pretty good foundation and highlights many topics that I see from my day job as an engineer.&lt;/p&gt;

&lt;p&gt;This course definitely opens you up to consider what is good architecture design, what software development cycles are, agile methodology and keeping in mind testing / refactoring. The downside is that the individual project seemed a bit tedious as it was a bit difficult trying to figure out all the test cases that we needed to cover. However, I felt that this class was pretty fair and on the easy side of things. In my class, many of the students struggled with A6, but I felt that keeping it simple with this assignment and revisiting the lectures helped for doing well on this. Personally, the group project was the most time consuming as we had to schedule meetings with our team members and delegate tasks.&lt;/p&gt;

&lt;p&gt;Professor Orso and the TA’s were pretty responsive in Piazza and they held Office Hours every week (though I didn’t attend all of them). Additionally the Slack channel for this course was also very helpful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Pay close attention to Piazza and read each detail of the assignments.&lt;/p&gt;

&lt;p&gt;Overall, I enjoyed being able to build an Android App that has a persistent database and multiple UI screens.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/omscs/6300/androidapp.png&quot; alt=&quot;Job Compare App&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;course-overview&quot;&gt;Course Overview&lt;/h2&gt;

&lt;p&gt;The workload for this course was pretty light and the lectures I was able to finish within two days after work. Each week there was an assignment and I typically finished them before the weekend. It was nice that as the assignment went on, the difficulty increased so there wasn’t a high learning curve for me. I did do a lot of googling when it came to building the Android App and developing in Java. Because I became used to implementing in Java, I started adding semi-colons at work haha.&lt;/p&gt;

&lt;h3 id=&quot;assignments&quot;&gt;Assignments&lt;/h3&gt;

&lt;p&gt;Here is the breakdown of the Assignments:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Assignment 0 - Participation / Syllabus Quiz&lt;/li&gt;
  &lt;li&gt;Assignment 1 - Team Matching Survey&lt;/li&gt;
  &lt;li&gt;Assignment 2 - Git Usage&lt;/li&gt;
  &lt;li&gt;Assignment 3 - Basic Java Coding and JUnit Testing&lt;/li&gt;
  &lt;li&gt;Assignment 4 - Simple Android App&lt;/li&gt;
  &lt;li&gt;Assignment 5 - Software Design
    &lt;ul&gt;
      &lt;li&gt;Developing a UML diagram for the upcoming group project which will be used to compare with your team members&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Group Project - Building an Android App to keep track of user’s current job, job offers and compare them&lt;/li&gt;
  &lt;li&gt;Assignment 6 - White-Box Testing&lt;/li&gt;
  &lt;li&gt;Individual Project - building a command line called cleave via Java that is used on a file and outputs a specific pattern. This command line had various options and for each option there is a different output. The goal of this project was to use test-driven development (TDD) by writing test cases before building the command line.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;exams&quot;&gt;Exams&lt;/h3&gt;

&lt;p&gt;There were no exams so that was nice too! I really like project based courses.&lt;/p&gt;

&lt;h2 id=&quot;how-do-i-prepare-for-this-course&quot;&gt;How do I prepare for this course?&lt;/h2&gt;

&lt;p&gt;Personally, I didn’t prepare because I read on OMSCentral that the course had a light workload and was an easy A. Additionally, I have experience in coding in an OOP language (Swift), so it was easy to pick up Java. The main issue was understanding the IDE and the syntax of using Java as well as how to build an Android App.&lt;/p&gt;

&lt;h2 id=&quot;lessons-learned&quot;&gt;Lessons Learned&lt;/h2&gt;

&lt;p&gt;From this class, I got to exercise my muscles in Java and developing Android Apps. We also utilized Android Studio and IntelliJ so got to have a bit of experience with those. This class inspired me to consider creating a simple Android app in the future. It was fun to be able to create and build an app, but also got to exercise my muscles in testing and addressing bugs.&lt;/p&gt;

&lt;p&gt;From this class, these are my main take aways that I will keep in mind as I continue to progress my career and hobby in software development:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Create designs and diagrams to before building projects&lt;/li&gt;
  &lt;li&gt;Develop code that is maintainable and scalable&lt;/li&gt;
  &lt;li&gt;Consider testing when building new features and keep in mind TDD&lt;/li&gt;
&lt;/ul&gt;
</description>
                <pubDate>Wed, 12 May 2021 08:20:55 +0000</pubDate>
                <link>cyndichin.github.io/blog/omscs6300</link>
                <guid isPermaLink="true">cyndichin.github.io/blog/omscs6300</guid>
                
                <category>omscs</category>
                
                <category>gatech</category>
                
                <category>education</category>
                
                
            </item>
        
    </channel>
</rss>