Skip to content

vermont42/CatFancy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

32 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CatFancy

GitHub Stars GitHub closed issues Twitter cat


Introduction

CatFancy is an iOS app that demonstrates iOS-development techniques. Users can browse breeds of cats with images from various sources and breed info from Wikipedia. CatFancy accompanies a blog post about UIKit iOS-developer coding challenges.

Build Tools & Versions Used

I developed CatFancy using Xcode 14.1 Beta 3, iOS 16.1, SwiftLint 0.30.1, and this song.

Discussion

Aside from meeting requirements that are typical of this sort of coding challenge, my emphases in CatFancy are using a technique, dependency injection, and an architectural pattern, the coordinator, that facilitate unit testing. I have come to value unit testing because, as Jon Reid observed, a "robust suite of unit tests acts as a safety harness, giving you courage to make bold changes." In nuts-and-bolts terms, dependency injection makes objects testable by isolating dependencies and side effects. I have written elsewhere on dependency injection. The coordinator pattern makes UIViewControllers more testable by removing from them the work of navigating to other UIViewControllers, whether in the app itself or in external apps. CatFancy's unit-test coverage is 88.5%.

CatFancy demonstrates two new Swift features, if let shorthand and async/await concurrency.

Although the breed-list screen, implemented primarily in BrowseBreedsVC and BrowseBreedsView, is the only screen whose implementation a take-home programming assignment typically requires, I chose to implement two additional screens. I wanted to give the user, the reviewer, the ability to choose different JSON files for display and different sort orders for the breeds. The settings screen, implemented in SettingsVC and SettingView, resulted. I wanted to give the user the ability to see information that cannot be displayed in the breed list. The details screen, implemented in BreedDetailVC and BreedDetailView, resulted. This screen shows walls of text about breeds and allows the user to view the breeds' Wikipedia pages and photo licenses in Safari. The settings and details screens exercise the coordinator pattern to an extent that the browsing screen, acting alone, could not.

CatFancy supports iPhone, iPad, landscape orientation, portrait orientation, Light Mode, and Dark Mode. I developed CatFancy primarily for iPhone. iPad would benefit from, for example, higher information density in breed rows. Landscape orientation on iPhone would be more idiomatic if it used UISplitViewController like Mail does. Due to time constraints that are characteristic of coding challenges, CatFancy may imperfectly support VoiceOver, but accessibility is important to me.

In both professional and side-project apps, I use color palettes from designers or the website Coolors. In CatFancy, I relied on system-provided colors due to time constraints.

The breeds fit perfectly the dainty iPhone SE form factor. If some breed info ended up not fitting in a BreedCell, tweaks would be in order. MarqueeLabel, a UILabel replacement that has performed well in RaceRunner, would obviate the need for either String truncation or widespread UI changes. Dynamic Type, which I did not test due to time constraints, might also necessitate tweaks.

Coding challenges typically do not state a requirement for internationalization or localization so, in the interest of time, I did not wrap user-facing Strings in NSLocalizedString(). I am, however, comfortable with that API.

Warning

If you run CatFancy in the simulator, as I did during development, you may see the following warning:

[plugin] AddInstanceForFactory: No factory registered for id <CFUUID 0x6000001ad4a0> F8BB1C28-BAE8-11D6-9C31-00039315CD46

My research indicates that this warning is harmless. I expect Apple to fix it in a future version of Xcode and iOS.

Screenshots

Browsing Details
Settings Launch

Credits

Christy Presler created the app icon and released it under the CC BY-SA 3.0 license.

Sound Jay created the chime and sad-trombone sounds and "allow[s] ... incorporat[ion of these sounds] into ... projects, be it for commercial or non-commercial use." Sound Jay "and its licensors retain all ownership rights to the sound files".

The humorous badges at the top of this readme are from my curated list of iOS-development podcasts.

Settings.swift and the GetterSetter files reflect an approach to storing and retrieving settings that I developed for Immigration and also use in Racerunner (GitHub), Conjugar (GitHub), and Conjuguer (GitHub).

SoundPlayerReal.swift reflects an approach to playing sounds that I developed for Immigration and also use in RaceRunner, Conjugar, and Conjuguer, though I added dependency injection to CatFancy's implementation because playing a sound is a side effect, I realized, that is undesirable in unit tests.

UIViewControllerExtensionTests.swift contains code I developed for Conjugar.

Doug Suriano shared the boilerplate-reduction technique in NSLayoutConstraintExtension.swift.

Antoine van der Lee shared the boilerplate-reduction technique in UsesAutoLayout.swift.

Point-Free developed and evangelized CatFancy's approach to dependency injection, The World.

Paul Hudson shared the approach to dependency injection for URLSession used in URLProtocolStub.swift and URLSessionExtension.swift.

Soroush Khanlou developed the coordinator pattern that CatFancy uses for navigation. Two posts by Paul Hudson also informed CatFancy's implementation.

Geoff Hackworth shared the technique of bespoke app/scene delegates for unit tests exemplified by TestingRootViewController.swift, TestingAppDelegate.swift, TestingSceneDelegate.swift, and main.swift, building on a technique shared by Jon Reid.

About

This app demonstrates iOS-development techniques.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages