Category Archives: Programming

Love when things work as you expect

I always love it when you think something should work one way and that’s exactly the way it works.  Had that happen to me today with a Stack object.

I wanted to iterate over a List and remove any objects that are null. Now I know I can do a reverse iterate and remove any nulls as I come across them without breaking the List, but I wanted to try to do it differently, just because 😬.

As I iterated the List, I pushed the index of any entry that was null onto a Stack.  Then when I was done, I could use Foreach on the Stack to pull out each index and remove it from the list.  As I’d used a Stack, the entries are fetched in the order of last-in, first-out, even in a Foreach loop.  Thought that might be the case, and was happy to find out it was.

Thought I’d share.

Apple WatchKit 2.2 – NATIVE apps what are they good for?

We have a workout app that supports the Apple Watch, and it was something that I’d hacked into the original project when the watch first shipped.  It’s a Unity3D based project and back then, adding the Watch target was a real pain, but I managed to get it done and even got it working as best as I could.

One of the major complaints was that the watch didn’t always notify users when a workout ended and a new one would start.  With the original WatchKit there was no way to access the haptic feedback system or even make the watch go ‘bing’. I’d used local notifications to make this happen as best as possible, but iOS decides if it’s going to forward a notification to the watch or not, and there was no way to ensure such forwarding – very haphazard…

Enter WatchKit 2 and NATIVE watch apps.  I was quite excited about this, I’d be able to update the code and fix the biggest complaint the app received from our users.  I’d be able to make the watch buzz and bing on command!

I started this update a few weeks back, and migrated the code to the new WatchKit2 system and had the code run on the watch.  In the simulator, things were working really well, however I was having difficulties in getting the app to actually run on my watch.  Turns out all was not well with my XCode project and the watch wouldn’t validate the binary and run it.  Of course, there was no error popups or feedback to XCode, just silence.

After numerous reboots of everything involved, a pairing of the watch to another test phone, I decided to try a new XCode project just to see where the problem actually was.  That new project built & ran just fine, and when I copied my code & storyboards across from the old project (one file at a time) that also worked as expected.  Huzzah, I had my code running on my watch.  I retired the old XCode project and continued with the new one.

At this point, I was able to run my code on an actual watch.  This was after a frustrating few days of trying everything else to resolve the problems.  So my frustration level was then enhanced when I discovered that an App running on the actual watch is suspended when the watch sleeps, or the user taps the crown to return to the clock display.  This didn’t happen on the simulator!  Some simulation!

It turns out all my previous work was pretty useless.  The App I’d moved to run independently of the attached iPhone does not work as expected.  If I setup an NSTimer to alert the user when it’s time to switch an activity, unless the user keeps the watch alive by tapping the screen, that NSTimer is suspended when the watch sleeps.  The timer never expires, the user is never alerted, and the App fails.

Even if I put all the code back on the iPhone, I can’t even make the watch vibrate and bing when the NSTimer expires, unless the watch happens to be awake when that happens and the user happens to have my App in the foreground.  So I’m back to the unreliable notification system with all the same problems as before.  There really is no point in building an update at this point.

I was pretty excited by WatchKit2, I really thought it would solve the issues I had with the original WatchKit, but it seems that once again, Apple have dropped the ball and not provided a cure.  I know the battery drain is the biggest concern, but seriously, couldn’t you spare enough juice to run one special background timer and let us notify the user when it expires…

Grrrrr.

XCode and the App Store!

While getting ready to update an old App, I realized I needed to update XCode to build to the latest iOS release I’d installed on my phone…

After lots of waiting, watching, clicking and hair pulling, I’ve decided to never ever never update XCode via the App Store again…

Just go to https://developer.apple.com/downloads/ and download it from there – much better and pretty straight forward.  Trust me, you’ll be a lot happier for it.

Ok – FAIR WARNING – XCode 7.3 requires OSX 10.11 or higher (El Capitan), that’s a real bummer for me as I’d been holding off upgrading my Mac – guess I’ve no option now 😡😡😡.

JNI Type signatures

For my future reference, one of the things that will show up when you’re debugging your java stuff are functions with signatures.

The official documentation is here: http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/types.html#wp16432

But for quicker access, here’s what matters:

Type Signature

Java Type

Z

boolean

B

byte

C

char

S

short

I

int

J

long

F

float

D

double

L fully-qualified-class ;

fully-qualified-class

[ type

type[]

( arg-types ) ret-type

method type

For example, the Java method:

long f (int n, String s, int[] arr); 

has the following type signature:

(ILjava/lang/String;[I)J 

 

More Java issues

I’ve upgraded some of the projects I’ve been working on to Unity 5 and at the same time, I upgraded the Google Play Unity plugin to the latest version.

The GP plugin now uses AAR files (a android library file) instead of JARs (a standard java library file).  Unity 5 prefers AAR’s so that makes sense.  However, I ran into a headscratcher when my plugins (JAR files) started giving me the ‘java.lang.NoSuchMethodError’ errors again.

I verified I had all the libraries I needed in my Plugin folder so I couldn’t see what the problem was.  As I was messing with various debug additions I noticed the the standard GooglePlay folder was being deleted by something in Unity from my Plugin folder, and that this was the root of the problem.

A little more digging and I discovered that the new version of the GPlay plugin will remove that folder from Plugin/Android and then includes the ‘referenced’ parts of the library when you compile it for your android build.  As their plugin didn’t use the advertising or analytic’s part of the GPlay libraries, it was not including it in the final APK, and my plugins would then fail as I use both of those.

They have a mechanism to create a c# class that their code will pull in and let you add additional dependencies, which in turn enables those sections to be included in the APK.  I wasn’t able to figure that out, and in frustration (I’d already spent several hours tracking this down) I just modified a file in their plugin to include the dependencies I wanted.

I modified the static constructor by adding two lines to PlayServicesResolver.cs

        static PlayServicesResolver()
        {
            svcSupport = PlayServicesSupport.CreateInstance(
                PlayServicesResolver,
                EditorPrefs.GetString(AndroidSdkRoot),
                ProjectSettings);
            //CG  added the following two lines
            svcSupport.DependOn(com.google.android.gms, playservicesads, GooglePlayGames.PluginVersion.PlayServicesVersionConstraint);
            svcSupport.DependOn(com.google.android.gms, playservicesanalytics, GooglePlayGames.PluginVersion.PlayServicesVersionConstraint);

        }

These two lines keep the analytics and AdMob modules in the final APK and most importantly, let my plugins function as expected.  When I have time, I’ll figure out the correct way to do this.