Thursday, 30 October 2014

Microsoft Band (day 1)

I had no clue Microsoft was working on the Band until the reviews starting to leak out last night, but I was immediately keen to try one out. Today I dropped by the Microsoft Store at opening to pick one up, and I'm happy to report it's actually a pretty cool piece of tech.

Let me start by saying two things: (1) I really wanted to like the Band ~ smart watches don't really appeal to me but this feels smaller, less obvious and more focused that the Apple and Android devices (2) my primary use-case is running - with GPS and heart rate recording - so that is my measure of the device's success.

TL;DR I like the device a lot, my initial impression is that it does what I want while running and it pleasantly surprised me in a lot of other ways as well.


Features

The initial setup was painless: I downloaded the Microsoft Health app to my iPhone, paired the Band and was immediately able to receive alerts (texts, voicemail alerts, etc) on the Band. The app was easy enough to figure out: I changed the color scheme and turned on Facebook, Twitter, Notifications... and everything just worked.

Using the Band's menu on the phone screen is surprisingly smooth - although I'm not sure how people will bigger hands will find it. The device itself is less bulky than I expected (especially on my small wrist)... don't get me wrong it still feels "big" and looks a little "wide", but it's not heavy and after I'd worn it for a while I barely noticed it.

Playing around with heart-rate monitoring, calendar, notifications, alarms, the step counter, the UV detector and the workouts feature was a lot of fun; but as I said my primary concern was using it for run training...

Running

I was easily able to figure out how to get everything working, but here is the running "support page" for reference. To be clear - you do NOT need your phone with you while running! The GPS functionality is built-in to the Band, along with the step-counter and heart-rate monitor, so you get plenty of good data while exercising without dragging a phone around :)

To compare the accuracy and usability of the Band I wore my Garmin Forerunner 10 for comparison. They both took a while to 'find satellites' (and it always feels like forever when you want to start running), but the Band was actually ready slightly ahead of the Garmin.

During the run, they both kept in pretty close sync, beeping out kilometer markers at roughly the same time (and therefore showing similar splits). There was a bit of drift between them but nothing dramatic. The screen of the Band was constantly lit (which was great, as I was running at night), and the elapsed time is pretty easy to read. The heart-rate text is pretty small to read while you're moving unfortunately.

Your pace is available by 'swiping down' on the screen while you're running. It auto-hides after a while, returning the display to the elapsed time and heart-rate. I haven't got pictures of these screens and haven't found them on the support site yet. At each kilometer marker (or mile if you must) it beeps and shows your pace-per-kilometer/mile for a few seconds, before again reverting to the elapsed time display.

After the run was over, I uploaded my Garmin data to Strava (as I normally do) so I could compare the results. The Band seamlessly sync'd its data to my phone as soon as I opened the Microsoft Health app.

Summary Data

Here's the summary info from the Microsoft Health app versus Strava's view of my Garmin-collected data. Both compare pretty well - the Calories calculations are fairly different (something to investigate further) but the distance and pace are pretty close. The best thing about the Band is the inclusion of heart-rate info, without the hassle of a chest-strap or other additional device.



The Band also has an interesting 'Recovery' estimate (not shown) which I'm still to learn more about.

Map

Here's the two maps (Band/Health app vs Garmin/Strava). The Band does cute color-coding of pace, I'm not sure whether Strava can do that with more information (it does not have any heart rate data available as the Garmin Forerunner 10 does not support that). The Band track seems a little more accurate, but with a sample size of one it's a little early to draw conclusions about that.



I'm not sure what to make of the Band coloring a 4'20" kilometer as "snails pace" (jk :-)

Splits

Both provide similar splits data, although the data varies slightly (due to GPS variance).



Graphs

The Microsoft Health app shows pace, heart-rate and elevation. Strava doesn't get heart-rate data but graphs the other two (note the Garmin's GPS error causing a pace calculation error in the Strava graph around the 2km mark).



Navigating around the map, splits and graphs is fairly easy once you figure it out. Just tap and swipe around until you get the hang of it.

Conclusion

After less than a day it's probably a bit early to draw conclusions, but I overall I had a lot of fun playing with the Band today. Can't wait to race with it and check the data against the watch (and to see heart-rate info for the first time in ages). Here's hoping the number of app integrations increase and they eventually work out sync'ing with Strava!

Tuesday, 30 September 2014

iPhone 6 and 6 Plus LaunchScreen.storyboard for Xamarin

Following on from the previous post about adding launch images for iPhone 6 and 6 Plus, here are the instructions for adding a LaunchScreen.storyboard file instead of multiple fixed-size images. Apple's documentation recommends this method over using the static images. I used these instructions for replacing launch images with storyboards as a reference.

Configuring a LaunchScreen like this will automatically scale up your app for iPhone 6 and iPhone 6 Plus devices. You might also want to consider adding @3x retina images for iPhone 6 Plus support.

1. Add a new Storyboard to your project and call it LaunchScreen.storyboard.

2. Drag a UIViewController in and design your launch screen. I chose a black background with some white centered text - it looks like this (use the VIEW AS option to preview in different sizes):
3. Open the iPhone application Project Options and scroll down to the iPhone Launch Images section. There is a new Launch Screen dropdown (currently in Beta) that will automatically be populated with the available storyboards and xibs in your project. Choose the storyboard you just added.
3a. This creates the following key in your Info.plist (just FYI):
 <key>UILaunchStoryboardName</key>
 <string>LaunchScreen</string>

4. When you build the app, appropriate launch images will be generated for your app. Here's a shot of the emulator starting up showing the launch image for iPhone 6:

I've updated my Xamarin.Forms Todo sample, the code and storyboard are available on github.

UPDATE: Gerry reminded me about Marco's experience where adding a LaunchImage.storyboard file causes iOS to ignore the UIDeviceFamily setting in Info.plist (which specifies iPhone/iPod, iPad, or Universal app) and upscale iPhone-only apps to full iPad screen size (potentially making your app look really weird!). This behavior still appears to occur on the simulator, so test before you launch :)




Monday, 22 September 2014

iPhone 6 and 6 Plus Launch Images for Xamarin

I was initially stumped by how to get my Xamarin.iOS and Xamarin.Forms apps to size correctly on the iPhone 6 and iPhone 6 Plus. Thanks to this StackOverflow question & answer I have a solution - reposting here because the solution that works best for me right now is only the 3rd most popular answer there.

Simply create two new default images (this is for portrait only, but landscape will become obvious later):

Default-667h@2x.png for iPhone 6; dimensions 752x1334

Default-736h@3x.png for iPhone 6 Plus; dimensions 1242x2208

and place them in the application root or the Resources folder. Notice the filename format is similar to the Default-568h@2x.png image that Apple introduced for the iPhone 5 screen.

Now edit the source of your Info.plist file (open in a text editor so you can type XML directly) and add the following UILaunchImages key (the first two items are for iPhone 6, the others are for the older default image configuration):

<key>UILaunchImages</key>
<array>
<dict>
<key>UILaunchImageMinimumOSVersion</key>
<string>8.0</string>
<key>UILaunchImageName</key>
<string>Default-667h</string>
<key>UILaunchImageOrientation</key>
<string>Portrait</string>
<key>UILaunchImageSize</key>
<string>{375, 667}</string>
</dict>
<dict>
<key>UILaunchImageMinimumOSVersion</key>
<string>8.0</string>
<key>UILaunchImageName</key>
<string>Default-736h</string>
<key>UILaunchImageOrientation</key>
<string>Portrait</string>
<key>UILaunchImageSize</key>
<string>{414, 736}</string>
</dict>
<dict>
<key>UILaunchImageMinimumOSVersion</key>
<string>7.0</string>
<key>UILaunchImageName</key>
<string>Default-568h</string>
<key>UILaunchImageOrientation</key>
<string>Portrait</string>
<key>UILaunchImageSize</key>
<string>{320, 568}</string>
</dict>
 <dict>
  <key>UILaunchImageMinimumOSVersion</key>
  <string>6.0</string>
  <key>UILaunchImageName</key>
  <string>Default</string>
  <key>UILaunchImageOrientation</key>
  <string>Portrait</string>
  <key>UILaunchImageSize</key>
  <string>{320, 480}</string>

 </dict>
</array>
If you wish to support landscape images, add matching keys with Default-Landscape-???h filenames and specify the correct orientation and size.

Note that this is not Apple's preferred way of indicating support for the screen sizes. Their Launch Images doc says:

You use a launch XIB or storyboard file to indicate that your app runs on iPhone 6 Plus or iPhone 6.

which requires you to create a Storyboard or XIB using size classes. More on how to do that in this post, or head back to that StackOverflow post!

p.s. this iPhone 6 Screens Demystified post by PaintCode is awesome!

UPDATED: @jamesmontemagno informs me that you need to add the original 320x480 into the plist too, so I've added to the example above. 

Sunday, 29 September 2013

Android TextToSpeech API with Xamarin: it talks too!

A recent post covered Apple's new text-to-speech API in iOS 7, but forgot to mention that Android has actually had this capability for a while! It's really easy to add text-to-speech to a Xamarin.Android app: just implement TextToSpeech.IOnInitListener (which is a single method: OnInit) then create a new TextToSpeech instance:

speaker = new TextToSpeech (this, this);

and call Speak:

void Speak(string text) {
   var p = new Dictionary ();
   speaker.Speak (text, QueueMode.Flush, p);
}

The TaskyPro sample code has been updated so that both the iOS and Android apps have a Speak button. The Android app looks like this:

Check out this cool TtsSetup sample for Xamarin (via StackOverflow) for more details on how to customize the Android TextToSpeech API.

Friday, 27 September 2013

Built-in Barcode Scanning with iOS7 and Xamarin: MonkeyScan!

Another new iOS 7 feature is built-in support for barcode-scanning via the AVFoundation AVCaptureDevice API. Back in 2012 I threw together MonkeyScan using Windows Azure Services and the ZXing barcode scanning library. For iOS 7 I've updated the code to use the Azure Mobile Services Component and the new iOS 7 barcode scanning API instead.

The app looks like this when scanning a PassKit pass:

The code that sets up an AVCaptureDevice for 'metadata capture' (as opposed to capturing an image or video, I guess :) is shown below:

bool SetupCaptureSession () {
   session = new AVCaptureSession();
   AVCaptureDevice device = 
      AVCaptureDevice.DefaultDeviceWithMediaType(AVMediaType.Video);
   NSError error = null;
   AVCaptureDeviceInput input = 
      AVCaptureDeviceInput.FromDevice(device, out error);

   if (input == null)
      Console.WriteLine("Error: " + error); 
   else
      session.AddInput(input);

   AVCaptureMetadataOutput output = new AVCaptureMetadataOutput();
   var dg = new CaptureDelegate(this);
   output.SetDelegate(dg, MonoTouch.CoreFoundation.DispatchQueue.MainQueue);
   session.AddOutput(output); // MUST add output before setting metadata types!

   output.MetadataObjectTypes = new NSString[] 
      {AVMetadataObject.TypeQRCode, AVMetadataObject.TypeAztecCode};

   AVCaptureVideoPreviewLayer previewLayer = new AVCaptureVideoPreviewLayer(session);
   previewLayer.Frame = new RectangleF(0, 0, 320, 290);
   previewLayer.VideoGravity = AVLayerVideoGravity.ResizeAspectFill.ToString();
   View.Layer.AddSublayer (previewLayer);

   session.StartRunning();
   return true;
}

You can specify specific barcodes to recognize or use output.AvailableMetadataObjectTypes to process all supported types.

...and it speaks!
Since the app now requires iOS 7, it can also use the new AVSpeechSynthesizer to speak the scan result as well (see previous post).

if (valid && !reentry) {
   View.BackgroundColor = UIColor.Green;
   Speak ("Please enter");
} else if (valid && reentry) {
   View.BackgroundColor = UIColor.Orange;
   Speak ("Welcome back");
} else {
   View.BackgroundColor = UIColor.Red;
   Speak ("Denied!");
}

The MonkeyScan github repo has been updated with this code.

Thursday, 26 September 2013

iOS SpeechSynthesizer API with Xamarin: it talks!

Mike posted a neat code example today on adding the new iOS 7 AVSpeechSynthensizer API to a Xamarin app.

It's so easy, I added speech synthesis to the this TaskBoard to-do list example in about 5 lines of code. Now the app can read the to-do item back to you :) just by adding this code:

if (UIDevice.CurrentDevice.CheckSystemVersion (7, 0)) {
   SpeakButton.TouchUpInside += (sender, e) => {    // requires iOS 7
      Speak (TitleText.Text + ". " + NotesText.Text);
   };
}

and

void Speak (string text) {
   var speechSynthesizer = new AVSpeechSynthesizer ();

   var speechUtterance = new AVSpeechUtterance (text) {
      Rate = AVSpeechUtterance.MaximumSpeechRate/4,
      Voice = AVSpeechSynthesisVoice.FromLanguage ("en-AU"),
      Volume = 0.5f,
      PitchMultiplier = 1.0f
   };

   speechSynthesizer.SpeakUtterance (speechUtterance);
}

The UI now looks like this: touch the Speak button to hear the text read back to you.

Wednesday, 10 July 2013

New Dropbox API one day, on Xamarin the next

Long-time Xamarin customers know that there is a history of delivering updates same day when the native platforms (iOS and Android, for example) are upgraded. Today there was another little surprise - the new Dropbox Datastore API that was announced at DBX yesterday was made available via a Xamarin Component today!

Think of it as a cross-platform iCloud-like key-value store ~ same kind of stuff you can do with Parse or even Azure Mobile Services.

Check out the Xamarin Blog for all the details and a cute sample app called MonkeyBox.

But wait, there's more!
In the past I've posted about porting a small "To Do List" application to various different platforms, including Azure (iOS, Android, Mac and more) twice as well as an iCloud version for iOS.

Here's the same basic code using the new Dropbox Datastore API (just iOS, for now...):

Here's a direct link to the code on github... to use just download the solution (which includes the Xamarin Dropbox Component) and:

  1. Visit the Dropbox App Console to get your access credentials set-up.
  2. Add the App key and App secret to the AppDelegate.cs in the project.
  3. Add a Custom URL Type to the advanced Info.plist settings (replacing the identifier and also YOUR_APP_KEY with the correct credential value) like this

When the app is up-and-running, you can 'browse datastores' from the Dropbox App Console and see the data update on the server in real-time!

In only a few lines of code you can use a cloud-based data store simply and easily, across multiple platforms and devices! Load up the app on a couple of iOS devices (and/or the iOS Simulator) and watch the magic in action :)