Double Negative

Software, code and things.

DN.com Escrow services review

Recently I was approached by a buyer based in China interested in purchasing one of the domain names owned by Double Negative. After a prolonged back and forth we agreed on a sales price and agreed to complete the transaction through an Escrow service.

Why not Escrow.com?

The transaction was for a significant amount of money and as such safety and security for both parties was important.

Having previously worked for Uniregistry and their domain sales platform DomainNameSales.com I had previous experience with Escrow.com and knew them to be a safe bet when it comes to domain name Escrow.

Unfortunately however things did not go to plan in that the buyer could not actually pay Escrow.com due to various (bank related) problems. I enquired to the Escrow.com support team as to whether they had any Chinese speaking staff members who could aid in resolving the issue. Unfortunately they did not.

Whilst I am appreciative that in the grand scheme of things the fees being charged are not extremely high I felt that the team at Escrow.com came across as being particularly disinterested in helping at all..

Given this, when the buyer suggested using DN.com.. after a little initial reluctance I decided to give it a try.

Why DN.com?

The buyer in this transaction was Chinese and he verified to me that he had previously transacted on high value deals through DN.com. Furthermore, being local meant that sending a payment to DN.com was no issue for the buyer.

I was initially reluctant because DN.com is relatively new in the grand scheme of things. Given however that DN.com is associated with 4.cn I decided that things were probably by the book.

I have never personally transacted on 4.cn but I regularly hear about sales that occur through the platform and they generally seem to have a good reputation. Perhaps more importantly I have never heard about any negative experiences with them.

One thing that did concern me somewhat was their heavy marketing through Namepros.com - they offered various deals through the forum platform which seemed a little informal in their approach for a company dealing with potentially massive domain Escrow transactions.
That said, having conversed with Cynthia at DN.com (see below) apparently this marketting effort resulted in a significant number of new customers whereby neither the buyer or the seller was a Chinese national.

An overview

The process

The actual Escrow process was very standard.

  • Buyer submits payment
  • Seller transfers domain
  • DN.com release payment.

DN.com do offer a 'Premier service' whereby they act as a middleman and the domain is actually transferred to them.

Fees

The Escrow fees are extremely competitive - better than any other service out there (that I know of). For a transaction in excess of $25,000 the fee is 0.8%. For the 'Premier Service' you pay 1.6%

The website

The interface is clear and logical - it is patently apparent what you need to do, when you need to do it, and how you go about doing it. That said, it does lack a little polish. For example when you press an action button there is no indication that anything is going on until the action is complete. They use a lot of Javascript behind the scenes and I suspect that if anything failed on the backend you'd be left completely bemused unsure as to why absolutely nothing had happened :)

One thing that I found particularly worrying was that the support form doesn't/didn't work. I tried submitting various questions (prior to completing the transaction) to which I received no response. A direct email followup to service@dn.com did receive a reply (see below).

These issues are really quite significant in that if your website doesn't instill confidence you may push away customers. It is somewhat bemusing that you would develop a full Escrow platform and then not put a loading spinner on a form :P

The only other issue with the website was speed. On a number of occasions I found the website to be particularly slow which once again did not fill me with confidence.

Notifications At each step of the way you get an email so you do not need to keep logging in to see what is going on. In addition to that, Cynthia at DN.com emailed me directly to verify my payment details - I liked this touch. No-one wants their money going into someone elses account because of a typo :)

Payments DN.com has a fantastic payment management system. You can hold currency in your account in CNY, USD, or EUR and you can convert between the three using their simple (albeit powerful) interface. Withdrawing funds was simple and painless.

History and statistics

I emailed Cynthia at DN.com to find out some further information about why they built DN.com and how things have been going so far.

Cynthia made some incredibly interesting points.

DN.com was built to fill a hole in the market. They are working towards connecting the Chinese market (where there is a significant amount of capital and an ever growing interest in domain names) with the international markets where the best domain names are held (due to earlier Internet adoption).

"We want to make DN.com your first choice to make domain business with Chinese and we are going to stride further into the global market after that."

Cynthia mentioned that Escrow.com is the market leader and has resources and (unspecified) advantages that they cannot match at present. They are however targetting a niche market and hoping to serve that niche well.

Personally I think DN.com is right up there with Escrow.com (see below).

Some statistics

I was very kindly provided with some statistics. They certainly make for interesting reading.

  • Since launching (last September) they have completed over 300 transactions
  • 2/3 of transactions are in USD
  • Their transactions range in value from $150 to $400,000
  • Most of their transactions are in the $1,000 to $5,000 range
  • The largest transactions tend to be conducted in CNY by domestic users of 4.cn
  • They have a number of clients who are 'regular' users, completing in excess of 10 transactions monthly.

Conclusion

Overall my experience with DN.com was really good. The only problems that I had were with the visuals of the platform. The service was second to none. With a little bit of polish DN.com would be my go to choice of Escrow service.

For so long in the industry Escrow.com has been the 'go to' Escrow service. There is however certainly another big player in DN.com

There are other Escrow services such as SEDO.com and Afternic.com but my personal view is that both of those platforms are outdated and out of touch. Services such as eCop.com and EscrowHill.com would sadly never get my business because they are too small to instill confidence in the security of my money and domains.

When I was researching DN.com to decide as to whether I was prepared to use it I was unable to find much in the way of significant hands on experiences.

If you are considering utilizing DN.com and have stumbled upon this post.. I absolutely reccomend DN.com, and would be happy to answer any questions that you may have.

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.