Double Negative

Software, code and things.

Don't Repeat Yourself - iOS

Don't Repeat Yourself (DRY)

The Don't Repeat Yourself principle is one of the most important concepts that a software engineer has in his/her arsenal (in my opinion).

I previously worked on a legacy PHP project whereby a complete disregard for DRY has resulted in a completely unmaintainable codebase. If someone found a small, insignificant bug you would often find yourself fixing the same issue in multiple places.

On the most primitive of levels, if you isolate one piece of business logic and reuse it as appropriate, when there is an issue or you decide to change the business logic then you only need to update your code in one place.

When can you repeat yourself

There is a very interesting Stack Overflow post on this topic here: Is violation of DRY principle always bad?.

My personal view is that DRY is a great principle to be thinking about as you code. In some circumstances however you need to do a simple cost benefit analysis. For me readability is vitally important in my codebase.

A few cases spring to mind from my current iOS project where I have explicitly chosen not to follow the DRY principle. For example:

  • I have some custom UIView subclasses which implement an interface to display a loading screen. At the moment they all show the same loading screen using the same code. By duplicating the code it makes each individual class more readable. Furthermore I intend for these implementations to diverge in the future.

  • I use a custom dependency factory pattern to abstract the dependencies of various classes. This in itself makes my codebase so much more readable and as such the fact that two similar classes have dependency factories with similar implementations is a worthwhile trade off. Any further abstraction would lose me the benefits of clarity.

iOS and the delegate pattern

The delegate pattern plays a big role in iOS development. The out of the box classes provided by Apple which make up most user interfaces rely on them heavily. For example UITableView uses the delegate pattern to implement its datasource and its layout. As another example UITextView has a delegate for indicating when various things happen.. for example the textViewDidBeginEditing: delegate method.

Extending protocols

On the iOS platform (Objective-C, Swift.. both can) you can extend a protocol. In Swift the code is exactly the same as how you would write a subclass.

protocol SubProtocol: SuperProtocol {}  

What has this got to do with DRY?

Very good point.. :P

I recently built a pull to refresh/scroll to load more piece of functionality in Swift. My conceptual premise was that anything I want to refresh/load more of will be in (or can be put in) a subclass of UIScrollView - UITableView, UICollectionView etc.

I figured that I could write a custom implementation of the various scroll view delegate methods to track the users scrolling and show the respective pull to refresh header/load more footer when appropriate.

Unfortunately it was not as easy as I had hoped.. (That is not to say that it was difficult ;) )

Apple give us these various UIView subclasses out of the box, and they are extremely powerful. One can not really complain. That said I don't understand why Apple didnt seperate the table view delegate from the scroll view delegate in relation to table views and collection views.

UITableViewDelegate is a sub-protocol of UIScrollViewDelegate which means when you implement the former you have to implement the latter. UIScrollViewDelegate has no required methods but that is beside the point :)

The difficulty is that I want to implement some of the UIScrollViewDelegate delegate methods but I do not want to couple them with an implementation of any UITableViewDelegate methods because I want to use them elsewhere. I do not want to repeat myself !

Resolution

The way to resolve this is simple.

I wrote a class (PTRScrollDelegate) which implements the UIScrollViewDelegate protocol. It does various fancy things to make my pull to refresh functionality work.

I then have a custom class which extends this scroll view delegate AND implements UITableViewDelegate. Simple.

If I want to use the functionality with a UICollectionView I again create a custom delegate class, extend my scroll delegate and implement the UICollectionViewDelegate

You implement your scroll view delegate methods within your superclass whilst you implement your table view delegate methods in your subclass.

Problems

There is one patently apparent problem with this kind of setup (although it does not present itself in this specific case).

That is the fact that Swift does not support multiple inheritance whilst it does support the implementation of multiple protocols.

Consider the situation where you have a protocol which extends three additional protocols. You would not be able to keep the implementations of the various delegate methods in independent reusable classes in this case.

That said I can not think of (off the top of my head) a situation within the various provided iOS delegates where this would be a problem. Anyone know of any?

If you are in a situation where this is an issue for you there is more than likely or more appropriate way of structuring your design.

On that note..

Conclusion

The above is essentially a personal case study of my approach to avoiding code repetition on the iOS platform (in one particular situation). Hopefully this will be of use to somebody.

If you have any questions, comments, or suggestions for future posts then I would love to hear from you :)

Stateful enumeration in Android

Whilst clever solutions to complex problems are always interesting and insightful, sometimes the answer is a lot more simple.

When gearing up to release our first app to the Google Play store we engaged in some real world testing. The results were generally positive but it made apparent one large oversight in our development - the Android system destroying our application process in its entirity.

When a user presses the home button, or recieves a phone call whilst utilising an app, in certain circumstances your activity can be destroyed by the system. For example on older devices with smaller amounts of memory.

The application in question is heavily fragment based and utilizes setRetainInstance and a custom backstack implementation to retain fragment state for the most common 'recreation' situations (e.g orientation changes).

The problem is that when an activity is destroyed by the system, its fragment instances are also destroyed. On the other hand, during a normal orientation change, the instances (and as such the properties) are retained. When everything is destroyed we need to restore our data and state appropriately.

Like their activity counterparts, the onCreate, onCreateView, and onActivityCreated lifecycle methods of a fragment take a bundle of saved instance state as one of their parameters. This bundle contains any data that you set in onSaveInstanceState - a method the system calls prior to destroying the relevant instance.

When I go back to my application the Android system will try and restore its state. How Android does this exactly is not completely transparent but one can guess that the system stores data about your application state in an efficient low overhead format somewhere secure on the system. It then uses this data to recreate your application. It seems reasonable to also assume that the bundle of data you save in onSaveInstanceState is similarly stored.

Stateful enumeration

Android essentially trys to restore what was on screen. That is to say it recreates the activities and the contained fragments and puts them in the correct places. When recreating fragments the system calls the no argument constructor. The problem with this is that it does not store/restore:

  • any data you passed into the instance using a factory
  • the data you downloaded from the server
  • the fact that a network service was still ongoing
  • the fact that a network issues screen was displayed

To resolve these issues in a way which works universally for all destruction/recreation situations I utilized the simplicity of enums !

All you need is something as simple as the below:

enum PAGE_STATE { INITIALIZING, LOADING, LOADED, NETWORK_ISSUES }

PAGE_STATE currentState = PAGE_STATE.INITIALIZING;  

When your service is loading data you set the state to LOADING. If there are NETWORK_ISSUES.. ;)

This setup works for restoring the two situations that could occur. These are outlined below.

Detach and Attach

When you detach a fragment its onSaveInstanceState method is not called. This method is only called when the activity needs to save state (see documentation) i.e when it is destroyed.
If we then reattach the fragment its view will be recreated and our properties will be available and in tact - it is the same instance after all.

The problem however is that the state of our fragment means that we do not want the view displayed in its default state. For example, if the state is NETWORK_ISSUES we want to reshow the network issues screen when the view is recreated. We can simply utilize a switch statement based on the value of our currentState property and redisplay the appropriate views.

Likewise if the view was LOADED we can recreate our adapter and set it on our list.

Destroy and recreate

When our activity is destroyed onSaveInstanceState is called on our fragment. In this situation the fragment may well be completely destroyed and as such we may not retain our instance and its set properties. As such we need to save everything that we need to keep our state.

In the example above we may not mind reinitializing everything in which case we do not need to save any state. If however you have used the factory pattern to create the fragment in question and have passed in an identifier to send with your server request you will encounter issues. Specifically, you will encounter a NullPointerException as this property will not exist. To resolve this you need to save the server ID, and restore it when appropriate.

You could avoid requerying the server by saving the data that you have downloaded. In my use case after a server request returns a response, we utilize gson to convert our response JSON into POJOs. These objects implement the Parcelable interface, and as such I can save them in my state bundle and the system will store/restore them.

In my onActivityCreated method I check if I have a bundle of saved state. If I do, I restore the currentState property and execute the appropriate code to restore everything. This restoration involves restoring a list of data.. data which is also saved in the bundle.

There are more complex possibilities for example if the application is destroyed whilst the data is being downloaded.. In this situation the state would be LOADING and based on this you can restart your service appropriately. You could even add an additional state such as DESTROYED_DURING_LOAD and use this state to display a button such that a user must explicitly restart the service when the app is recreated.

Conclusion

Proper state restoration is imperative for a good user experience and is all the more relevant on Android where the range of devices mean consideration really must be given to the possibility of low memory.

Once you have got to grips with the concepts there really is no reason not to implement proper state management because:

  • As outlined.. it is really easy
  • Considering low memory application destruction is similar to the consideration associated with allowing orientation changes.. and surely you've considered that? ;)

If you have any questions, or anything needs clarifying feel free to ask away :)

Nested fragments not retained in latest support library releases

Since version 17 of the Android API it has been possible to nest fragments within your applications. Using the support library that the Android team provide, you can utilize this functionality from version 11 onwards.

There is however a bemusing issue in the latest versions of the support library which mean that nested fragments dont function as one would expect.

As outlined in this issue, versions 20 and 21 of the support library do not retain nested fragments correctly on configuration changes. This can be quite a difficult issue to diagnose if you are not expecting it (which you shouldn't be). I stumbled upon it because a nested map was disappearing on orientation change.

A duplicate issue more explicitly states the cause: "The issue is that Fragments now always null out their mChildFragmentManager property, so when they are re-attached to an Activity, a new child FragmentManager is always created, thus losing the old nested Fragments."

I wanted to see for myself so had a look at the source where you can see that the mChildFragmentManager is set to null.

Within the comments on the issue there is a link which proposes a solution.

The proposed solution is not however particularly clean or clear. As such I have created a gist with the solution I am using.

It works as follows:

  • The first time we load a fragment that extends from this base class, we save a reference to the child fragment manager.

  • On orientation change the saved instance variable is retained.

  • When the fragment is reattached post orientation change, if the variable is non null we use reflection to assign its value to the property which the support library uses.

I find it really quite bemusing that the Android team have not commented on this.. an issue that has been present for 8 months. I am also suprised that so few people have had anything to say on the matter.

Considerations

It should be noted that this fix isn't guaranteed to continue to work. Hopefully Google will fix this in the next support library release but if they don't it is theoretically possible that they could change the variable name used for the child fragment manager (although extremely unlikely).

Reflection is less than ideal but the methods we would need to override/the variables we need to access to fix this any other way are package private so this is the best we will get for now.

Thanks

Thanks of course to all who have commented on/investigated the issue. Hopefully this post provides a little more exposure for anyone else experiencing it and looking for a solution.

Simple Android Dependency Injection

Whilst I am aware of, and appreciative of the merits of both Roboguice and Dagger, I felt that they were not suitable for what I had initially intended to be a simple application.

That is not to say that they are complex or difficult to use but rather I didn't want my application to require another 3rd party library to function correctly. Especially given that my investigation into dependency injection (in Android) had only come about as a result of wanting to unit test a complete and working app.

The answer that I ended up with came about based on my own knowledge and research as well as general trial and error. Hopefully the information below will help someone else.

Constructor injection

My first thought was constructor injection. It seemed logical that injecting the service(s) on which my activity depended would be the easiest way to allow for mocking.

Unfortunately the Android frameworks do not allow for direct instantiation of activities, and as such injecting a dependency in the constructor is not easy enough to be worth doing.

You can however instantiate fragments directly, and as such constructor injection does have a part to play in my overall solution.

Fragments must have a constructor without parameters. That said, a common pattern for constructing fragments with parameters is to use a static factory method which creates the fragment instance. An example of this pattern can be seen here.

I decided that for the purposes of testing my fragments I would inject a dependency factory (a class which lazily creates instances of my fragments dependencies) into my static factory methods.

The benefits of this are twofold:

  • Lazy loading. We do not waste memory instantiating dependencies up front. We create them as/when we need them.

  • Dynamic instantiation parameters. Whilst you might know what dependencies a fragment relies upon, at the point of injection you may well not know the parameters than your dependency requires to instantiate itself correctly. By using a dependency factory we can build our dependency with the correct parameters when we known what they are.

One small problem

There is one small 'problem' with this method (unfortunately).

The example linked above demonstrates passing in simple values and setting them in a bundle - the fragments arguments bundle. What I want to do is pass in an instance of a (potentially very complex) dependency factory. Are there any extra considerations?

The example above sets this data in the arguments bundle because it is this bundle that the Android framework saves/restores when the fragment is recreated. The Android framework recreates fragments by calling their no parameter constructor. As such if you do not save parameters in the arguments bundle they will not be present when the fragment is recreated (for example on screen rotation).

The resolution for this is to either implement the Parcellable interface in your dependency factory and save your instance in the bundle (this is pretty advanced stuff) OR to retain your fragments state on recreation.

When I instantiate my fragment, I set the dependency factory as a property of said fragment. I can then access it to request a dependency anywhere within.

By using setRetainInstance(true) within my fragments 'onCreate' method, my fragments state (including its instance properties) are maintained by the Android framework. Likewise, if you replace a fragment (adding the transaction to the backstack) and then pop the backstack the instance variables are also retained.

For more information on retained state or for general clarification, I suggest you have a play with my fragment demo from a previous post. You can set your dependency factory as an instance variable, rotate your screen and still have access to that same instance - the arguments bundle is not required.

What about the activities?

As mentioned above, constructor injection does not work with activities.

The only simple way to inject a dependency into an activity is with setter injection. The problem with this however is that (as mentioned above) the instantiation of, and lifecycle of an activity is pretty well defined by the Android framework. There is no opportunity to set your dependency before it is needed.

Even if it were possible one would certainly want to avoid "two-step construction" (an antipattern) - there is a certain irony to making your code patently worse whilst trying to make it testable :)

With no obvious or apparent resolution to my issue it got me thinking about the environment in which I want to test. I have no interest in using Robolectric for the same reasons that I am avoiding Dagger. All I want is a nice simple ActivityUnitTestCase. Eureka !

A call to startActivity within an ActivityUnitTestCase creates an isolated test environment whereby only the onCreate method of the activity under test is executed. As such I can inject my dependency factory before it is needed.

What about two step construction you say? Well.. whilst my activities do require a dependency factory to function, the default factory is not injected but rather hard coded. The setter is only used for cases where we want to override the default.. for example testing.

Whilst this does mean modifying your code to facilitate testing (which is admittedly less than ideal), I am happy (personally) with the tradeoff to make my activities testable.

If you really want to, you could subclass your activities within your test package for the purposes of testing.

So where are we?

At this point I have outlined how you can make dependencies available to both activities and fragments in a way which allows for them to be swapped out (mocked) for testing.

It is not a perfect solution but it is simple, and it is easy to implement.

If you have any questions, I would be happy to answer them.