Xamarin Code for iBeacons

Did I mention how easy it is to track an iBeacon using Xamarin?

locationManager = new CLLocationManager();
var beaconId = new NSUuid("E437C1AF-36CE-4BBC-BBE2-6CE802977C46");
var beaconRegion = new CLBeaconRegion(beaconId, "My Beacon");
locationManager.RegionEntered += (s, e) => {
    if(e.Region.Identifier == "My Beacon")
    {
        Console.WriteLine("Found My Beacon");
        //Fire up ranging
        locationManager.StartRangingBeacons(beaconRegion);
        locationManager.DidRangeBeacons += (lm, rangeEvents) => {
            switch(rangeEvents.Beacons[0].Proximity)
            {
            case CLProximity.Far: 
                Console.WriteLine("You're getting colder!");
                break;
            case CLProximity.Near:
                Console.WriteLine("You're getting warmer!");
                break;
            case CLProximity.Immediate:
                Console.WriteLine("You're red hot!");
                break;
            case CLProximity.Unknown: 
                Console.WriteLine("I can't tell");
                break;
            default:
                throw new ArgumentOutOfRangeException();
            }
        };
    }
};
locationManager.StartMonitoring(beaconRegion);
//Create a beacon
var peripheralManager = new CBPeripheralManager(new MyPeripheralDelegate(), DispatchQueue.DefaultGlobalQueue, new NSDictionary());
var beaconOptions = beaconRegion.GetPeripheralData(null);
peripheralManager.StartAdvertising(beaconOptions);

My Favorite iOS 7 APIs Part 1: iBeacons and Multipeer Connectivity

Since Xamarin provides full native capabilities, developers don’t need to wait for us to exploit iOS 7′s awesome new APIs, such as:

  • iBeacon: This, to my mind, is the stealth API of the release. An iBeacon is a Bluetooth device (just iOS devices for now, but Apple says they’ll release a Bluetooth profile for h/w manufacturers) that broadcasts a UUID (the UUID is intended to be shared between many devices, e.g., a store-chain will have a UUID and all their stores will broadcast it: new store’s geofence works instantly). The UUID travels up to Apple and apps that monitor for that UUID get alerted when they enter a geofence around the beacon. Within the beacon’s region, BT, not GPS, is used to indicate proximity. Pair that with…

  • Multipeer Connectivity: Ad Hoc messaging and data with none of the hassle. Broadcast a protocol string (“com.MyCompany.MyApp”) and everyone in BT range or on the same WiFi network advertising their interest in that protocol string gets an alert and, boom!, you’ve got Birds of a Feather. (Whoever writes the “Fetish Friend Finder” app using iBeacon and MPC is going to retire early. Of course, there are only 2^122 GUIDs, so you couldn’t track every kink.) (UPDATE: A sample chat app I wrote )

iBeacons can be combined to create many actionable zones within a physical location:

Here’s some Xamarin code

3D Maps in iOS 7 with Xamarin

It’s trivially simple to show 3D maps in iOS 7:

    var target = new CLLocationCoordinate2D(37.7952, -122.4028);
    var viewPoint = new CLLocationCoordinate2D(37.8009, -122.4100);
    //Enable 3D buildings
    mapView.ShowsBuildings = true;
    mapView.PitchEnabled = true;

    var camera = MKMapCamera.CameraLookingAtCenterCoordinate(target, viewPoint, 500);
    mapView.Camera = camera;

MKMapCamera

Full Screen Content and EdgesForExtendedLayout in iOS 7

One of the difference that jumps out dramatically to a programmer — especially those of us who typically build our UIs in code rather than using a visual design surface — is the new “full-screen content” concept.

This is particularly evident with UINavigationControllers. This picture shows the difference between the default mode (UIViewController.EdgesForExtendedLayout = UIRectEdge.All) and the “iOS 6″-style (UIViewController.EdgesForExtendedLayout = UIRectEdge.None).

You can see that in UIRectEdge.All mode, the current UIView‘s drawing rectangle covers the whole screen — you can see the diagonals extend under the navigation bar, toolbar, and even the status bar, and you can see the blue tint coming up through those elements (they are also blurred, which you cannot see in the image).

Breaking Bad Ending Prediction

Going on record with my Breaking Bad prediction:

EAAAAEqhoq0ty5977EFCIguikrRVYzZsL4CiNXNK7VKcLs8Ik5lmrtsI3cJPo19bq2HBZavatk0EalFyeqQx6w2K6RxIuLoRbuddMJ4qSiZgQ8l3VjB1JGUw1ucskXUxL/ZL7HFRGY0424JY/MH4pirH4yCJ/ORGW7fSyiPQNtEDkh2s5Qs8QivN0ueJi1p/v2c4AV7vHYpSqfBf7e6AFQ1DPsMsHOJf05kIvh7BUp/LKssRFoL9jGQ2uqT1R7FnAv9icRbpUOVIDZ74N63JAhGOuye9uNv2dYAb53H53RxWN9b2Em1kXlnKoflf2rEqa6UCNvVvPy+kgMuKQuAEy+/ut70=

Decrypt with:

var key = new Rfc2898DeriveBytes("BreakingBadEndingPrediction", "o6806642kbM7c5");
var bytes = Convert.FromBase64String(cipherText);
using (var msDecrypt = new MemoryStream(bytes))
{
aesAlg = new RijndaelManaged();
aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8);
aesAlg.IV = ReadByteArray(msDecrypt);
var decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
   using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
    using (StreamReader srDecrypt = new StreamReader(csDecrypt))
        return srDecrypt.ReadToEnd();
}
}

Kiteboarding: Four Days Since Our Last Tiger Shark Attack

I am holding a bar while floating in a murky bay, slowly drifting towards a shipping channel. If I pull on the bar, 6 things can happen, only 1 of which is good. Not to mention the tiger shark. The tiger shark doesn’t care whether I pull the bar or not, but still. So 7 things. I pull the bar.

For the past decade, I’ve had a cocktail-party story about learning to kiteboard — or rather, not learning to kiteboard — with an obscenely overpowered two-line kite and a guy behind me on a JetSki shouting encouragement as I get pulled downwind, in 20-yard increments, across a mile of San Francisco Bay. “Kiteboarding — it’s like bull-riding, but with more drowning.” Subsequent to that lesson (in which I was literally pulled out of one of my wetsuit booties) I thought “Well, I guess I’m too old for it.” Too out-of-shape and too brittle.

But dammit, they make it look so easy.

My friend Florian, who is an expert in getting off his ass, finally convinced me that what we needed to do was take a long weekend, fly to Maui, and take 3 days of lessons. So, here I was, floating like a nerdy dumpling off the beach in Maui, staring up at 86 square feet (8M^2) of kite bucking in the Force 5 winds, a few degrees from the brilliant tropical sun. At the moment, the kite was flying in its most unpowered state, presenting only its thin, inflated lip to the wind. When I pulled the bar, the kite would turn, catch more wind, and accelerate, exponentially increasing in power, which would be transferred down 20M of finger-slicing line to the harness fastened around my waist. And then:

  • The force would pull me out of line and past the board, which would act like a sea anchor and torque my knees perilously before popping off; or
  • My tentativeness would generate so little force that the kite only moved me another 40 or 50 yards closer to the shipping channel; or
  • The kite would turn too sharply and fly directly downwind, launching me into the air before crashing (this was mostly what happened to me in San Francisco); or
  • The kite would lift my butt out of the water, which would be so astonishing that I’d promptly crash; or
  • The kite would lift my butt out of the water, and then launch me into the air; or
  • The kite would lift my butt out of the water, by which time I would have re-turned the kite not-quite towards the vertical, achieving the proper balance between “launch me into the air” power and “sink back on your butt” stalling.

And then there was the tiger shark. Which isn’t a metaphor or one of those “You swim with sharks every time you get in the water” bravados. Florian’s rental board was bitten by a tiger shark, at that very beach, earlier in the week. Marine Biologists measured the bite radius and say it was about 12′. (“Measured the bite radius”: You know, just like Jaws ).

this was no boating accident

I tried not to think about the shark too much.

So the only bad thing I have to say about the experience is that it’s ruined my story. The 4-line kites they have today are literally 180 degrees from what I experienced in San Francisco: my disastrous time in the early 2000s was with kites that, when they crashed, automatically relaunched and tried to fly downwind. So after you crashed you had 5 or 10 seconds to get things under control and if you didn’t, the kite would relaunch, jerk you another 20 yards, crash, and give you another window in which to recover. The modern kites I learned on in Maui were the opposite: they are engineered to skid upwind until they stall, still in the water, and give you all the time in the world to get your bearings.

Ultimately, the hardest thing about kiteboarding for me was that I wasn’t aggressive enough with the kites! They were easy to fly and forgiving, but I had such bad memories about what could go wrong that I was too tentative with the power. Only once did I fly so aggressively that I fell forward rather than backward.

Another hard thing is that when you’re learning, you spend a lot of time using the kite to drag you into position, which involves being pulled through the water by your harness. The force of the water on your chest and all your gear is exhausting and frustrating, because you’re thinking “Why am I panting for breath? I haven’t done anything!”

By the end of my second day, I was getting up and riding for a few seconds. The third day I took a step back because of equipment trouble, and frankly, I was a little worn down from the weekend’s other activities, which included crossing the channel to Molokai to dive with hammerheads (I like sharks just fine when I have a mask on) and shutting down a bar in Ma’alea.

I don’t really know what comes next. I think I have 20 more hours of instruction left before it’s likely I could start doing it myself: 3 more days just getting up and riding consistently and then some time learning beach launches and landings, which are the most dangerous moments in the sport. The Big Island is a poor place to learn to kiteboard — there are no instructors and the only reliable place to kiteboard has a beginner-hostile offshore wind. Flying to Maui for another long weekend of instruction is a possible, but expensive option, but probably not for a few more months, at least.

But on my longest ride, which probably lasted about 20 seconds, I felt like I was looking at an open window. With these kites, physically the sport is open to even old brittle guys like me, and it’s clearly a sport where, once you know what you’re doing you can keep things in balance and not expend a lot of energy. So if I could learn it, I could have a decade or more of a sport that is just perfectly tuned to my sensibilities. So, yeah, I guess I’ll try again.

ChromeCast Xamarin Binding and Sample Source Code on GitHub

Due to popular demand…

Here is source code for a preliminary Xamarin.iOS binding for Google’s ChromeCast

and

Here is C# source code for a simple iOS app that casts a video URL

In order for this to work, you’ll need:

This is just source code, not a step-by-step walkthrough. Everything associated with this is in beta and I don’t want to invest a lot of time making things just so at this point.

You can read an overview of the programming model here.

# ChromeCast Home Media Server: Xamarin.iOS FTW!

As I blogged about last weekend, I got a ChromeCast and had a simple-enough time creating an iOS-binding library for Xamarin.iOS, allowing me to program the ChromeCast in C# (or F#, maybe next weekend…).

This weekend, I wrote a simple Home Media Server that allows me to stream… well, all my ChromeCast-compatible media, primarily mp4s. Here’s how I did it…

ChromeCast Programming: Intro

Essentially the ChromeCast is nothing but a Chrome browser on your TV. If you want to display HTML, no problem, but what you probably want to display is a great big video div:

<video id="vid" style="position:absolute;top:100;left:0;height:80%;width:100%">

But where does this HTML come from? Here’s the first kind-of-bummer about ChromeCast: Every ChromeCast application is associated with a GUID that Google provides you. Google maintains a map of GUID->URLs. And, since you have to send them your ChromeCast serial to get a GUID, it’s a safe bet they check the hardware, too. When you start an application with: session.StartSessionWithApplication("93d43262-ffff-ffff-ffff-fff9f0766cc1"), the ChromeCast always loads the associated URL (in my case, “http://10.0.1.35/XamCast”):

So, as a prerequisite, you need:

  • A ChromeCast that’s been “whitelisted” for development by Google;
  • A Google-supplied GUID that maps to a URL on your home network (a URL you decided during the “whitelist” application to Google)
  • A WebServer at that URL

It’s important to realize that what’s at that URL is not your media, but your “receiver app”: which might be plain HTML but which is likely to be HTML with some JavaScript using the ChromeCast Receiver API that allows you to manipulate things like volume and playback position, etc. I basically just use this file from Google’s demo, with minor tweaks.

Home Media Server : Intro

So if you want to stream your home media, you need a WebServer configured to serve your media. This doesn’t have to be the same as your App Server (it probably will be, but conceptually it doesn’t have to be):

The structure is straightforward:

  1. The mobile controller gets a list of media from the Media Server
  2. The application user selects a piece of media
  3. The controller sends the selected URL (and other data) to the ChromeCast
  4. The ChromeCast loads the media-URL from the Media Server

For me, the “App Server” and “Media Server” are the same thing: an Apache instance running on my desktop Mac.

ChromeCast Media-Serving : Components and Life-Cycle

This is a rough sequence diagram showing the steps in getting a piece of media playing on the ChromeCast using the Xamarin.iOS binding:

  1. Initialization
    1. Create a GCKContext;
    2. Create a GCKDeviceManager, passing the GCKContext;
    3. Create a GCKDeviceManagerListener; hand it to the GCKDeviceManager;
    4. Call GCKDeviceManager.StartScan
  2. Configuring a session
    1. When GCKDeviceManagerListener.CameOnline is called…
    2. Create a GCKApplicationSession;
    3. Create a GCKSessionDelegate, passing the GCKApplicationSession
  3. Playing media
    1. After GCKSessionDelegate.ApplicationSessionDidStart is called…
    2. Create a GCKMediaProtocolMessageStream;
    3. Get the Channel property of the GCKApplicationSession (type GCKApplicationChannel);
    4. Attach the GCKMediaProtocolMessageStream to the GCKApplicationChannel
    5. Create a GCKContentMetadata with the selected media’s URL
    6. Call GCKMediaProtocolMessageStream.LoadMediaWithContentId, passing in the GCKContentMetadata

Here’s the core code:

public override void ApplicationSessionDidStart()
{
    var channel = session.Channel; 
    if(channel == null)
    {
        Console.WriteLine("Channel is null");
    }
    else
    {
        Console.WriteLine("We have a channel");
        mpms = new GCKMediaProtocolMessageStream();
        Console.WriteLine("Initiated ramp");
        channel.AttachMessageStream(mpms);

        LoadMedia();
    }
}

private void LoadMedia()
{
    Console.WriteLine("Loading media...");
    var mediaUrl = Media.Url;
    var mediaContentId = mediaUrl.ToString();
    var dict = new NSDictionary();
    var mData = new GCKContentMetadata(Media.Title, Media.ThumbnailUrl, dict);

    Console.WriteLine(mData);
    var cmd = mpms.LoadMediaWithContentID(mediaContentId, mData, true);
    Console.WriteLine("Command executed?  " + cmd);
}

Plans

The core of a real home media server for the ChromeCast is the Web Server and the UI of the mobile application that browses it and chooses media. To turn this hack into a turnkey solution, you’d need to:

  • Run a public Chromecast application server that
    • Deferred the URL of the media server to the client
  • Write the media server, with all the necessary admin
  • Write a nice client app, that stored the mapping between the public ChromeCast app server and the (strictly-local) media server
  • Make a great user interface for selecting media
  • Make a great user interface for controlling the media

I have no plans on doing any of that stuff. What I plan on doing once ChromeCast and iOS 7 are out of beta is:

  • Make a nicer binding of the ChromeCast API and put it up for free on the Xamarin Component Store; and
  • Play around with serving media and blogging about anything interesting that comes up

Conclusion

The real thing that I wanted to do was see if Xamarin.iOS worked well with ChromeCast (resounding “Yes!”) and come up with a hack for my own use.

Achievement Unlocked.

ChromeCast Home Media Server with Xamarin

Code to follow…

whale_on_tv

For Immediate Release…

FOR IMMEDIATE RELEASE:

NEANY Inc. to Exhibit Unmanned Solutions at AUVSI’s Unmanned Systems North America 2013

~ Arrow UAV, Ground Control Station, and Unmanned Surface Vehicle will be on display~

Hollywood, MD – August 07, 2013 (myPressManager.com) –

NEANY Inc., an industry leader in providing time-sensitive tactical solutions for a variety of missions, is a proud supporter at this year’s AUVSI’s Unmanned Systems North America 2013 in Washington, DC August 12 – 15. Conference attendees will see firsthand NEANY’s flagship UAS, the Arrow, integrated with Raytheon’s Pyros™, a UAS weapon specially designed for tactical level missions, and the aXiom™ 9000 Series, Tachyon’s state-of the-art Beyond Line-of-Site communications system. NEANY’s display will also feature its latest autonomous surface vehicle, the DragonSpy, equipped with the ARES Inc. 7.62mm Externally Powered Gun (EPG) mounted on L-3 Communications IOS’s Advanced Remote Weapon Station (ARWS). The DragonSpy is ideal for providing rapid response capabilities in maritime/littoral environments. In addition, visitors will have the opportunity to operate one of NEANY’s signature ground control stations to further experience the capabilities of these systems.

NEANY Inc. is a minority-owned, SBA 8(a)-certified research, design, test and evaluation engineering firm specializing in unmanned systems with integrated payloads supporting a variety of global missions. These missions include homeland defense and security, border and port patrol, urban mapping, counter-narcotics applications, disaster preparedness, and Intelligence, Surveillance, and Reconnaissance (ISR). In addition to unmanned systems, NEANY’s expertise includes ground control stations, systems integration, rapid prototype fabrication, pilot training, and theater deployment and logistics. NEANY continues to demonstrate unprecedented in-theater expertise that includes deployment-to-extraction logistical support as nearly 50% of NEANY’s personnel are currently forward deployed. In a period where financial resources are limited, NEANY is confident in its ability to offer cost-effective unmanned solutions capable of supporting national and international defense applications.

NEANY will have literature and personnel on hand to demonstrate and discuss our full line of available products and systems. Please take time to visit NEANY at booth #2103.

For more information on the NEANY advantage, please visit www.neanyinc.com.

For more information on AUVSI’s Unmanned Systems North America 2013, please visit

div>