issues, tutorials, and curious app development stuff

Monthly Archives: August 2014

You may consider yourself an expert Android programmer, and you might even have successful apps published in Google Play Store, but sometimes, IDEs are so easy and helpful, that we forget to worry about what’s happening behind the scenes. This graph extracted from http://developer.android.com/tools/publishing/preparing.html and very well explained by the guys at http://www.bignerdranch.com/, explains every step that is happening when we click on the “Run” button. After understanding it, some technicisms that we often see in the log messages (aapt, zipalign, Dx, dex, dalvik) may sound more familiar for us.

3.- Open the PDF from Google Drive, click on the icon at the top-right corner, select “Open in…“. Select iBooks.

4.- Et voila, your PDF will be downloaded and included to your iBooks library.

I know there many more ways of doing that, but most of them are annoying:

– Dropbox is all the time coming with “buy more storage, invite people for more storage, do a handstand for more storage, buy buy BUY BUY” and it’s very annoying.

– iTunes politely invites you to “synchronise your iPhone/iPad”, deleting all the content that Apple might not like, to have their users under control (mmh nice try Apple).

So with that simple steps, you can have your PDF for reading without too many annoying obstacles. We are storing on Google Drive, so make sure your PDF does not contain the words “murder” or “president”, or else the FBI will be knocking your door in a couple of hours 😉

If you are using asynchronous requests (e.g. AsyncTasks, Services+BroadcastReceivers, android-volley, android-async-http or any other flavour), this scenario may sound familiar to you:

1.- in the Activity’s onCreate() or onResume() method, an asynchronous HTTP request is sent
2.- User quickly destroys the Activity (for example, rotating the phone)
3.- Response to the request made in step 1 arrives, the onResponse/onHandleIntent callback is fired, but the Activity/Fragment is no longer existing, because you have destroyed it in step 2. so BOOM!!! App crashes, giving your users this undesirable “Has stopped unexpectedly” message, and generating such a bad experience with your app.

If you are planning to implement a PreferenceActivity (preference screen) in your App, i highly recommend you to have a look at this example App made by CommonsWare. Have a look at the EditPreference class and how it handles headers, then the different kind of SharedPreferences (checkboxes, lists, inputs, etc), without needing to elevate complexity introducing additional Fragment classes (Fragments are private classes inside).

One difficult thing to implement in iOS SDK is an App offering In-App Purchases (from now on, IAPs). There are plenty of tasks to be done in iTunes Connect (Tax, Banking and Contracts, Manage Test Users, Manage Apps, Create App IDs, certificates, provisioning profiles, …), then tasks to be done in Xcode, and also a few more in the iOS device (look well, I said iOS device! and not SIMULATOR!).

The first thing you have to know is that In-App Purchases cannot be tested on the iOS Simulator. If you were trying to do that, or were planning to try, spend your time in something better.

But even in the iOS device, it is not trivial to find the way to test if our IAP implementation is working fine. Here are the steps for doing it. Following them carefully will for sure save you time and headaches 🙂

Prerequisites:

iOS App created in iTunes connect, all fields filled and screenshots uploaded. Must have “Ready to upload binary” status.

At least one in app purchase created for the iOS App, with its SKU and Bundle ID. I suggest you this tutorial for this point and the previous one.

An email account that has no AppleID associated. Immediate access to its inbox.

1.- In iTunes connect, go to Manage Users and create a Test User with the email account mentioned previously. Fill in the rest of the fields (name, secret questions, date of birth, …). Specify a password and take note of it, we’ll need it later.

2.- Get into the mentioned email’s inbox. There should be a mail from Apple with an activation link. Click it to activate the AppleID, note that the email from Apple could be on the Spam folder.

3.- Once the user is created, in your iPhone/iPad and go to Settings > iTunes Store and App Store > Apple ID (on top). Tap on it and select Disconnect in order to logout your AppleID from the iOS device.

4.- Run your iOS App, navigate to your purchase menu, and click on the “Buy” or “Purchase” button. It will ask you for your AppleID, select Use an existing Apple ID and fill in the email and password of the Test User activated in steps 1/2. A message asking you to purchase the item in [Environment: sandbox] will appear. You can buy the item or cancel the transaction and test what happens on each case. After the first purchase, you can try to uninstall the App, reinstall, and purchase the item again to see if your restoration works correctly. That’s all

Steps 3 and 4 are specially important because this is the only way to make the IAP test work. If you try, for instance, to log in the iPad with the AppleID and password of the Test User, it will come with “This AppleID is not activated in the App Store” and ask you for data / credit card. Also, if you try the step 4 with another Apple ID logged in (not the Test User), it will return a “Can’t connect to iTunes Store” message and IAP won’t work.

As an iOS dummy i was, i downloaded the mapbox basic tutorial, built & ran it, and it worked perfectly. Now i was wondering how to integrate this example in an Xcode project that i start from zero.

After some research i discovered the way of doing it, and i made myself this little guide:

1.- In your new Xcode project, click on the main target, scroll to the bottom and you’ll find “Linked frameworks and libraries”. Click on the [+] button

2.- Now click on Add other, and locate the “Mapbox.framework” file. A copy of it is located inside “mapbox-example-ios” folder.

3.- repeat steps 1 and 2 but now locating and including “libsqlite3.dylib”, “CoreLocation.framework“, and “QuartzCore.framework“. Click on the [+] button, and on the search box type each name, it will appear.

4.- Create a new objC class extending UIViewController. In its .h file, include the #import <Mapbox/Mapbox.h>, and implement the “RMMapViewDelegate” delegate.

5.- copy the .mbtiles map file by dragging and dropping it to the project folder in xcode. IMPORTANT: Do not forget to check “copy items into destination group’s folder”, and to mark all the targets before clicking finish!

*If you don’t do this, you will get this error: reason: ‘*** -[NSURL initFileURLWithPath:]: nil string parameter’ (luckily, Google searches arrive here and anyone finding this error can fix it)

6.- in the .m file, initialize the TilesSource and the MapView as its done in the Mapbox example