Sunday 29 December 2013

Rultech weekly

iOS News

Is your AppDelegate.m cluttered with a lot of initialization code? There is a better way to organize all that code with launchOptions parameter. Great article from Mattt on different launchOption keys and code snippets on how to use it.

We all have spent numerous hours going back and forth arranging pixels and waiting for the app to build and look for the output on simulator. Ole has worked out a way with the help of Classy, Masonry and ClassyLiveLayout to see live edits in the simulator.

Great overview of Core Bluetooth APIs and best practices. iOS 7 made some great additions to the Core Bluetooth API and with iBeacon using Bluetooth LE under the hood, Apple is surely going to make more additions to it in the future versions.

UI Dynamics is the newly added library to iOS 7 that allow you to add real-world inspired interactions to your UI. Mehfuz Hossein step-by-step shows how to create a simple slide-out menu with UI Dynamics. Definitely check it out if you havent yet used UI Dynamics in your app.

Goes without saying, debugging is the most time consuming thing we do as a programmer. XCPretty library helps you format Xcode build log so you can clearly look at the error messages rather than reading between the lines.

Design

Logo matters, it gives the first visual identity to your app. Its worth looking into logo creation from every perspective. Take a look at 11 of those perspectives in this great visual post.

Dragging things from one side of the screen to another is painful and even more so when its on a touch screen. Dave makes a good case for using touchable interface rather than drag & drop.

Business and Marketing

Software Developer Dennis Reimann lists his reasons for switching to a freemium model for your apps. Interesting read which discusses the growing Freemium model and the App stores tendency to leave "demo" version of apps behind in search rankings.

When words can only go so far, its up to you to screenshot the essence of your app for the respective store. Use this guide to make sure the pictures of your app are at their best.


Android News

Ever given thought to what the programming of tomorrow will look like? An Android developer walks us through a sample of what its like to develop for Google Glass.

Want to allow users to limit your app access to certain profiles? Gabriele has written a great post on how to accomplish it. Netflix just started doing it, you should too!

If you are like me you probably hate writing tests. But its good to know your options just in case. Wiebe walks through four different functional testing frameworks in this post.

Design

When words just wont do the trick you can use this collection of icons for relaying hand motions for user navigation. Fast, functional, and free.


Cross-Platform development is sometimes considered the way to go but developing the app and designing it can be worlds apart. This post aims to eek developers into consideration regarding the vastly different UIs of the standard iOS and Android App.

Tuesday 29 January 2013

Android: Fragments within Fragments


Fragments is something I largely ignored last time, as it was available for Honeycomb and I only had 2.x devices. Now I’ve got the phone and tablet running 4.1.1 I thought it was time to have a go. Additionally, the app I’m building has some quite complex UI so fragments was basically a requirement reading the docs.
I was building out the settings stuff first (the app needs credentials to work so I kinda had to start there), which was relatively easy. I wanted to create a setup flow, whereby when you start the app it checks if you have credentials that are valid and if not walks through the setup procedure. I was using fragments to do this, each setup page being a different fragment rendered within the whole window in the main activity.
Upon realising that I had already built a PreferenceFragment for the config settings a user had to setup at the beginning (they were easy to logically group this way) I thought I would just include that in one of the setup flow fragments and my config options would be all set up themselves. This worked rather nicely, until I got a rather nasty exception when I ran through the flow for a second time:

10-07 13:28:02.663: E/AndroidRuntime(1809): FATAL EXCEPTION: main
10-07 13:28:02.663: E/AndroidRuntime(1809): java.lang.RuntimeException: Unable to destroy activity {com.example.app/com.example.app.Base}: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
10-07 13:28:02.663: E/AndroidRuntime(1809): at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3273)
10-07 13:28:02.663: E/AndroidRuntime(1809): at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3291)
10-07 13:28:02.663: E/AndroidRuntime(1809): at android.app.ActivityThread.access$1200(ActivityThread.java:130)
10-07 13:28:02.663: E/AndroidRuntime(1809): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1248)
10-07 13:28:02.663: E/AndroidRuntime(1809): at android.os.Handler.dispatchMessage(Handler.java:99)
10-07 13:28:02.663: E/AndroidRuntime(1809): at android.os.Looper.loop(Looper.java:137)
10-07 13:28:02.663: E/AndroidRuntime(1809): at android.app.ActivityThread.main(ActivityThread.java:4745)
10-07 13:28:02.663: E/AndroidRuntime(1809): at java.lang.reflect.Method.invokeNative(Native Method)
10-07 13:28:02.663: E/AndroidRuntime(1809): at java.lang.reflect.Method.invoke(Method.java:511)
10-07 13:28:02.663: E/AndroidRuntime(1809): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
10-07 13:28:02.663: E/AndroidRuntime(1809): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
10-07 13:28:02.663: E/AndroidRuntime(1809): at dalvik.system.NativeStart.main(Native Method)
10-07 13:28:02.663: E/AndroidRuntime(1809): Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
10-07 13:28:02.663: E/AndroidRuntime(1809): at android.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1280)
10-07 13:28:02.663: E/AndroidRuntime(1809): at android.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1291)
10-07 13:28:02.663: E/AndroidRuntime(1809): at android.app.BackStackRecord.commitInternal(BackStackRecord.java:548)
10-07 13:28:02.663: E/AndroidRuntime(1809): at android.app.BackStackRecord.commit(BackStackRecord.java:532)
10-07 13:28:02.663: E/AndroidRuntime(1809): at com.kodhus.tropics.setup.SetupCredsFragment.onDestroy(SetupCredsFragment.java:24)
10-07 13:28:02.663: E/AndroidRuntime(1809): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:983)
10-07 13:28:02.663: E/AndroidRuntime(1809): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1035)
10-07 13:28:02.663: E/AndroidRuntime(1809): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1017)
10-07 13:28:02.663: E/AndroidRuntime(1809): at android.app.FragmentManagerImpl.dispatchDestroy(FragmentManager.java:1826)
10-07 13:28:02.663: E/AndroidRuntime(1809): at android.app.Activity.performDestroy(Activity.java:5171)
10-07 13:28:02.663: E/AndroidRuntime(1809): at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1109)
10-07 13:28:02.663: E/AndroidRuntime(1809): at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3260)
10-07 13:28:02.663: E/AndroidRuntime(1809): ... 11 more
I had a Google and was surprised to find endless Stack Overflow posts saying “Fragments in fragments can’t be done”. Well I may be new to this version of Android development but that seemed a little foolish and also acted like a red flag to a bull. So I had a hunt around and it turns out it is possible to do fragments within fragments, but you just have to clean up after yourself – activities only clean up the top level fragments in them when they are closed or transitioned etc.
Thus I had a half hour of playing around trying to find the right settings, and this is the code I came up with. It goes in the onDestroy method of the middle fragment, i.e. the one that is within the activity and has another fragment within it. Note that you need to know the ID of the inner fragment for this to work.

@Override
public void onDestroy() {
Fragment fragment = getFragmentManager().findFragmentById(R.id.innerfragment);
if (fragment.isResumed()) {
getFragmentManager().beginTransaction().remove(fragment).commit();
}
super.onDestroy();
}
Some explanation: first load up the inner fragment by its ID, in this case R.id.innerfragment. Make sure this is right or you will kill the wrong thing! Next, check if it is resumed. If you don’t do this check, you will try and kill a previously killed fragment, which will barf out even worse than the problem we’re trying to solve, and a little more unpredictably at that. Finally if you have a fragment that is not removed, use the fragment manager to construct a transaction to remove it. At the end you continue the stack’s destroy method call.
Turned out to be rather a few lines of code in the end to accomplish something pretty awesome, which should be possible anyway.