Talk:Wikimedia Apps/Team/iOS/BestPractices

I hope to add a section here on how to improve testability w/ DI and class extensions. BGerstle (WMF) (talk)

Expected behaviors/contracts
Views (and related types, like layout implementations) have a few implicit—but expected—behaviors that are usually derived from conventions set by Apple in UIKit or other widely-used open source libraries. The more important and commonly-encountered ones are listed below to help engineers make design decisions about the views they create or modify:

Keep APIs DRY
When at all possible, leverage existing APIs to implement the desired effect, such as,   properties, etc. The purpose of this is twofold. First is to avoid needing to manually maintain consistent state between redundant properties and their "native" counterparts. Second, using existing APIs makes code easier to compose and reuse while also keeping the codebase more consistent as a whole. For example: a custom view that provides methods to hide and show itself in a certain way should return expected values for its  property. If it doesn't, we'll have a proliferation of N ways to check "Is this view hidden?" depending on the type of the view in question.

Separate concerns
Changes to properties in one domain should not affect another. For example, changing a view's appearance should not affect its visibility. One common point where the rubber meets the road on this is  versus. is meant to change a view's appearance (via transparency) while  effects whether or not it is visible. Put another way, if I hide a view, then show it again, it should have the same appearance (read: alpha) when redisplayed. The simplest means to honor this contract will be the most preferred.

There might be cases where concerns aren't entirely orthogonal. Using the above example, the responder chain will actually check multiple properties (alpha, hidden, frame—via ) to determine if a view should respond to an event.

Writable properties
Writable properties on a UI type should be idempotent, lazy, and reactive. Typically this is done by overriding the setter of your new property, checking for a change, and flagging it for later update:

Animatable properties
As mentioned above, this can sometimes be functionality your view gets "for free" by using APIs that are themselves animatable using the  API. In this case, there's no need to provide anything other than a settable property that can be used within an animation block. However, in cases where you have custom drawing code related to certain properties, you'll often need to use lower-level APIs to make them animatable and provide a suitable high-level abstraction in order to explicitly animate them. objc.io has a great article covering how to implement animations for custom properties using CoreAnimation.