Create an iBeacon Transmitter with the Raspberry Pi

iBeacon is the Apple trademark for a low-powered, low-cost transmitter that can notify nearby iOS 7 devices of its presence. It uses Bluetooth Low Energy (BLE), also called Bluetooth Smart, technology to transmit an advertisement that includes a universally unique identifier (UUID). Android devices can receive iBeacon advertisements and, fortunately for those of us who like to hack around, it doesn't take too much work to setup a Raspberry Pi to emit iBeacon advertisements.

Raspberry Pi transmitting as an iBeacon

Why would you want to do this? Well, if the act of configuring a Raspberry Pi itself isn't enough of a reward, consider some of the following use cases:

  • Host a digital scavenger hunt by placing iBeacons with different clues scattered around a conference.
  • Customize retail offers based on your location in a store and proximity to certain products.
  • Alert you while you sit at a bar enjoying your favorite craft beer when someone rides off with your bicycle outside.

I particularly enjoy the last use case. Simply tag your bag with a BLE transmitter and then, if it leaves the proximity/region, get alerted!

If you look around the Internet you'll find hundreds of additional use cases and ideas. The point is, this is cool technology with a lot of different applications and uses.

In this post we're going to look at how you can start to play around with this using that universal toy for the hacker: the Raspberry Pi.

Required Hardware

Here's the hardware I use. You don't have to purchase from Adafruit, but to have the best results I'd recommend you try to get the same hardware I used; otherwise your mileage may vary.

The WiFi and Pi Case are optional but I strongly encourage you to get them. They'll make your life a lot easier.

Setup the Raspberry Pi as an iBeacon Transmitter

Over the past week I've had to setup and configure numerous Raspberry Pi's as iBeacons. Yes, there are a lot of tutorials, but sadly none worked perfectly for me. As so often happens when you're on the bleeding edge, things change and instructions stagnate. Additionally, I think some of the tutorials are simply wrong or poorly document the process.

Here are the steps I've taken to, repeatedly, get Raspberry Pi's setup as iBeacon transmitters. If you follow these instructions with the above hardware I'm reasonably confident you can get this up and running with no problems.

Step 1: Download an Operating System Image

There are numerous OS images you can use with the Raspberry Pi. I chose to use the Raspbian Debian Wheezy image. The steps below work on the 2014-01-07 release.

Download the image from the official downloads page: http://www.raspberrypi.org/downloads/

Step 2: Write the Image to the SD Card

There are numerous tutorials available for this step.

If you're using a Mac I recommend Ray Viljoen's Raspberry PI SD Installer OS X script. Works great.

Step 3: Connect to the Raspberry Pi

Again, you have numerous options for connecting to the device. I personally like to use the Console Cable to connect directly from my Mac but you can also connect with Ethernet & SSH or connect a monitor and keyboard.

It's worth noting that your default user name is pi and password is raspberry.

Step 4: Initial Device Configuration

Once you connect to the device you should first configure a few settings. Run sudo raspi-config and complete the following six steps.

  1. Choose Expand Filesystem.
  2. You should Change User Password.
  3. Choose Internationalisation Options then I1 Change Locale. I removed the existing setting and chose enUS.UTF-8 UTF-8.
  4. Choose Internationalisation Options then I2 Change Timezone. Set accordingly.
  5. Choose Advanced Options then A2 Hostname. Choose something unique.
  6. Choose Advanced Options then A4 SSH. It's likely enabled already but you may as well make sure.

Reboot the Raspberry Pi (sudo shutdown -r now) and reconnect.

Step 5: Setup WiFi (Optional)

While not absolutely necessary, I always setup WiFi on my Raspberry Pi so that it doesn't require Ethernet or a console cable for me to connect via SSH. When you have a lot of devices this is particularly important.

I use the Miniature WifFi (802.11b/g/n) Module.

You'll need to update your interfaces so that your WiFi connects to your wireless router. Run sudo nano /etc/network/interfaces (or whatever editor you want to use) and update accordingly.

auto lo

iface lo inet loopback
iface eth0 inet dhcp

allow-hotplug wlan0
auto wlan0

iface wlan0 inet dhcp
  wpa-ssid "ssid"
  wpa-psk "password"

Be sure to set your own ssid and password values (and yes, capitalization matters).

If you're connected over Ethernet you'll likely want to restart with sudo shutdown -r now but if you're using your Console Cable you can simply restart the networking with sudo /etc/init.d/networking restart. If you then run ifconfig you should see you now have an IP address. At this point I typically start connecting using SSH.

Step 6: Install Required Libraries

There are a number of open source libraries and tools used in order to send the iBeacon data from the Raspberry Pi. Install the following libraries:

sudo apt-get install libusb-dev 
sudo apt-get install libdbus-1-dev 
sudo apt-get install libglib2.0-dev --fix-missing
sudo apt-get install libudev-dev 
sudo apt-get install libical-dev
sudo apt-get install libreadline-dev

This only takes a few minutes.

Step 7: Download, Make, & Install BlueZ Library

The BlueZ libraries provide support for the core Bluetooth layers and protocols. We have to download, make, and then install the libraries. Run the following commands sequentially:

sudo mkdir bluez
cd bluez
sudo wget www.kernel.org/pub/linux/bluetooth/bluez-5.18.tar.gz
sudo gunzip bluez-5.18.tar.gz
sudo tar xvf bluez-5.18.tar
cd bluez-5.18
sudo ./configure --disable-systemd
sudo make
sudo make install
sudo shutdown -r now

The sudo make command can take a long time to complete. Just let it run. As long as you've followed these instructions exactly as I've described it should complete without any problem.

makestep

Congratulations. You've successfully setup your Raspberry Pi to act as an iBeacon transmitter. Of course, it's not yet transmitting a signal so let's set that up now.

Setup the Raspberry Pi as an iBeacon Transmitter

At this point we need to start transmitting a signal. Here's where, depending on what you're looking to accomplish, you may decide to take a different path. For me, I want my Raspberry Pi iBeacon to do the following:

  • Initialize and broadcast a signal.
  • Advertise itself but don't allow connections.
  • Broadcast a unique transmission but let me have more than one identifiable iBeacons.

The broadcast has three important identifiers:

  • proximityUUID: a unique UUID that distinguishes your iBeacons from other iBeacons.
  • major: used to group related sets of iBeacons.
  • minor: used to identify a iBeacon within a group.

What's nice about the Raspberry Pi as a iBeacon is you can choose all these values yourself. Perhaps the easiest way to generate a UUID is to run the following command:

python -c 'import sys,uuid;sys.stdout.write(uuid.uuid4().hex)'|pbcopy && pbpaste && echo

You should get a value such as 636f3f8f64914bee95f7d8cc64a863b5 as the output. This is a 128-bit UUID that our app will use to look for our iBeacon.

Okay, let's reconnect (if needed) to our Raspberry Pi and run the following commands:

cd bluez/bluez-5.18
sudo tools/hciconfig hci0 up
sudo tools/hciconfig hci0 leadv 3
sudo tools/hciconfig hci0 noscan

Now, run tools/hciconfig and confirm it's up and running. Your output should look similar to this:

hci0:   Type: BR/EDR  Bus: USB
        BD Address: 00:1A:7D:DA:71:13  ACL MTU: 310:10  SCO MTU: 64:8
        UP RUNNING 
        RX bytes:1136 acl:0 sco:0 events:61 errors:0
        TX bytes:855 acl:0 sco:0 commands:61 errors:0

It's now time use the hcitool to configure the transmission to use our UUID. Additionally, for this initial device, we're going to set the major and minor values as 0 by attaching 00 00 00 00 to the end of our UUID. Finally, the last byte we'll add is the RSSI value of C8.

The command should look like the following:

sudo tools/hcitool -i hci0 cmd 0x08 0x0008 1E 02 01 1A 1A FF 4C 00 02 15 63 6F 3F 8F 64 91 4B EE 95 F7 D8 CC 64 A8 63 B5 00 00 00 00 C8

You might be wondering about some of the other values. Well, the whole thing breaks down like this:

  • Setup the add packet flags:

    1E
    02      # Number of bytes that follow in first AD structure
    01      # Flags AD type
    1A      # Flags value 0x1A = 000011010  
              bit 0 (OFF) LE Limited Discoverable Mode
              bit 1 (ON) LE General Discoverable Mode
              bit 2 (OFF) BR/EDR Not Supported
              bit 3 (ON) Simultaneous LE and BR/EDR to Same Device Capable (controller)
              bit 4 (ON) Simultaneous LE and BR/EDR to Same Device Capable (Host)
    1A      # Number of bytes that follow in second (and last) AD structure
    
  • Define vendor specific values:

    FF      # Manufacturer specific data AD type
    4C 00   # Company identifier code (0x004C == Apple)
    02      # Byte 0 of iBeacon advertisement indicator
    15      # Byte 1 of iBeacon advertisement indicator
    
  • Our specific UUID values:

    63 6F 3F 8F 64 91 4B EE 95 F7 D8 CC 64 A8 63 B5 # our iBeacon proximity uuid
    00 00   # Major 
    00 00   # Minor 
    C8 00   # Calibrated Tx power
    

Run the command. Congrats, you're broadcasting!

Detect Your iBeacon Signal

In a later post I'll show you how to write your own iOS application to detect iBeacon signals. For now, let's grab a free application to find our signal.

For an iOS device I recommend Locate iBeacon. It's easy to use. I don't have an Android, but I'm sure there are many out there.

When you open the app first select iBeacon Transmitter and hit the + symbol/button to configure our Raspberry Pi iBeacon.

  • Name: Choose a unique name
  • Proximity UUID: 636f3f8f-6491-4bee-95f7-d8cc64a863b5 (must he a hex version of our UUID)
  • Major: 0
  • Minor: 0
  • Power: (leave blank)

Save these values, then select the Locate iBeacons button. You should see your iBeacon!

Authorize Authorize Authorize

Of course, if you have more than one Raspberry Pi, you can get them both to broadcast. Follow the instructions above except change the mino value to 1 (01 00 in hex):

sudo tools/hcitool -i hci0 cmd 0x08 0x0008 1E 02 01 1A 1A FF 4C 00 02 15 63 6F 3F 8F 64 91 4B EE 95 F7 D8 CC 64 A8 63 B5 00 00 01 00 C8

Pretty awesome!

I hope you've found this article on configuring a Raspberry Pi as an iBeacon transmitter useful! If you have questions or issues please feel free to leave a comment.

Salesforce Did What? How We Built the Salesforce Toolkits for .NET

I had the great pleasure this week to speak at TechEd North America 2014 on how we built the Salesforce Toolkits for .NET. It was a blast, and I wouldn't be surprised if I was the first Salesforce employee to speak at TechEd. Many thanks to my friends at Microsoft for the opportunity.

Here is the video recording of the talk on Channel 9:

The highlight of the talk for me was that, rather than explain through slides, I built a brand new SDK during the talk and committed it live to Github in this repository. Take a look at the repository and use whatever your find valuable!

While I gave a quick overview of the toolkits and SDKs we built for Salesforce, the focus of the talk was on how they were built. Consequently, I broke the talk into different segments and focused on the following items:

Segment 1: Create a new project with authentication capabilities.

  • Portable class libraries
  • Extensibility
  • Async/Await

Segment 2: Create tests to validate our new library.

  • Functional tests
  • Unit tests

Segment 3: Allow our library to run with Mono.NET on non-Windows platforms.

  • Mono.NET & Xamarin
  • Continuous integration with Travis CI

Segment 4: Extend our library with additional functionality for developers.

  • Anonymous types
  • Dynamics

Segment 5: Package and deploy our library.

  • NuGet

Segment 6: How to grow community involvement with our project.

  • Community
  • Licenses
  • Issues, features, and bugs in Github
  • Pull requests

I hope you find this presentation valuable! I had a blast and thoroughly enjoyed it.

Uploading an Attachment to Salesforce with the SOAP and REST APIs

Earlier today a colleague asked me if I had an example of using Python to create an attachment in Salesforce. I didn't, but that didn't stop me from creating a couple. Sadly, our documentation here isn't the greatest. You can look at the Insert or Update Blob Data for the REST API or Attachment for our SOAP API. If you're like me, neither document is good enough; I had to continue to dig around to figure out exactly what I needed.

Nevertheless, I got it working. I'd like to share with you two examples: uploading attachments with the REST API and uploading attachments with the SOAP API. For both examples I will use Python.

Why Python?

Well, not only is it fun, but I think Python is also remarkably easy to read. It shouldn't be too much work for you to adjust to your language of choice.

A few things worth nothing before we go to far:

  1. You will need to base64 encode your file.
  2. An attachment attaches to an object in Salesforce (i.e. Account, Contact, etc.). You'll need to know the Id (called the ParentId) to which you want to attach.
  3. Python has some great libraries that I'm going to use. This has the added benefit of keeping the code really simple and focused on the task of uploading the attachment.

Without further ado ...

Python and Attachments with the REST API

To run this script you'll need to do the following:

  • Create a text.txt file in the same directory as the Python script.
  • Add your user name, password, and security token.
  • Install simple_salesforce with pip install simple_salesforce. I recommend you first use virtualenv to manage your environment.
  • Update the instance value (or extract it from the login info).

The code is pretty straightforward. simple_salesforce is great when you want to quickly work with the REST API.

Python and Attachments with the SOAP API

To run this script you'll need to do the following:

  • Create a text.txt file in the same directory as the Python script.
  • Add your user name, password, and security token.
  • Install beatbox with pip install beatbox. I recommend you first use virtualenv to manage your environment.

Again, this code is pretty straightforward. beatbox is a fantastic way to interact with the SOAP API.

It's likely over time I'll learn more that I should add to this post. For now, I'll leave it as it is; hopefully someone finds it useful.

Enjoy!

Update Records with Python and the Salesforce Bulk API

It's time to take a little break from .NET and enjoy the many different programming languages you can use when integrating to the Salesforce1 Platform. But first, a public service announcement from Steve Marx:

This week a colleague of mine asked me if I could help him by writing a script to update data he has in Salesforce (okay, he asked me weeks ago, and I only got to it yesterday). In this particular case, he is tracking articles that are written by different members of our team and includes fields such as date published, published url, as well as the # of tweets, likes, and LinkedIn shares. Each week he's able to use Salesforce to produce dashboards and reports that demonstrate how well (or poorly) articles are doing. The complication was that all the social stats (i.e. # of tweets, likes, and shares) were aggregated manually.

A perfect opportunity for scripting, no?

It's really not that difficult. All three of these particular services provide a simple API that returns a JSON package with the counts we need. For example, let's say I want to see counts/shares for my post announcing the Salesforce Toolkits for .NET.

For Twitter, create the URL https://cdn.api.twitter.com/1/urls/count.json?url=http://www.wadewegner.com/2014/01/announcing-the-salesforce-toolkits-for-net/ and parse the following JSON:

{
    "count" : 144,
    "url" : "http://www.wadewegner.com/2014/01/announcing-the-salesforce-toolkits-for-net/"
}

For Facebook, create the URL http://graph.facebook.com/http://www.wadewegner.com/2014/01/announcing-the-salesforce-toolkits-for-net/ and parse the following JSON:

{
    "id": "http://www.wadewegner.com/2014/01/announcing-the-salesforce-toolkits-for-net/",
    "shares": 28
}

For LinkedIn, create the URL: http://www.linkedin.com/countserv/count/share?url=http://www.wadewegner.com/2014/01/announcing-the-salesforce-toolkits-for-net/ and parse the following JSON:

IN.Tags.Share.handleCount({
    "count":18,
    "fCnt":"18",
    "fCntPlusOne":"19",
    "url":"http://www.wadewegner.com/2014/01/announcing-the-salesforce-toolkits-for-net/"
});

Pretty simple, right?

So, now the challenge is using this information to update all the records in Salesforce. Let me quickly describe to you the two approaches I took. The first was fast and simple, but long term has some complications. The second took longer to create but ultimately provides the soundest approach.

Approach 1: Using the Salesforce REST API

I started with this approach. Basically, logged in using the Username-Password authentication flow, grabbed my access token, performed a SOQL query to get all the records with published URLs, looped through them, and then issues an update via the REST API with the proper social counts. Pretty simple.

The problem with this approach is that, eventually, I'm going to hit my REST API limits. Not only is my query an API call, but so too is every update. The plan is for this script to run many times throughout the day. It won't take too long for me to hit the limit.

Although it is a simple and elegant solution, ultimately it won't work.

Approach 2: Using the Salesforce Bulk API

As you'll see, this approach is a lot more involved. However, it's also rock solid and designed to beyond the scenarios supported by the REST API.

The Bulk API is optimized for loading or deleting large sets of data. You can use it to query, insert, update, upsert, or delete a large number of records asynchronously by submitting batches which are processed in the background by Salesforce.

The easiest way to use Bulk API is to enable it for processing records in Data Loader using CSV files. This avoids the need to write your own client application. However, you can also send it XML, which avoids having to construct or generate CSV files; perfect, in my opinion, for our scenario.

Okay, enough talk. Let's jump into the code.

Solution

To go really deep with the Bulk API, I recommend you review the Bulk API Developers Guide and watch the Fast Parallel Data Loading with the Bulk API presentation from Steve Bobrowski & Sean Regan.

There are, roughly, four steps involved in using the Bulk API:

  1. Logging in.

  2. Creating a job.

  3. Adding a batch. (Or multiple batches.)

  4. Closing the job (thereby starting it).

To facilitate these steps I created a file called async.py that had the four following methods.

You can see that this method does the following:

  • It constructs an XML string that includes the user name and password.
  • Defines some heads; in particular it includes the SOAPAction of login.
  • A requests post is made to the URL, passing the headers and the encoded data.
  • It returns the response to use.

Pretty simple and nothing surprising.

A few things worth noting here:

  • We pass in the instance which we derive from the login response. This is used to call against the correct Salesforce datacenter.
  • To successfully communicate with the API we need to validate ourselves with the sessionId, which was returned in the login response. This value is used in the header X-SFDC-Session to validate us against the API.
  • To create the job we have to specify an operation, i.e. insert, update, upsert, and so on.
  • We pass in the object we're working with. For example, we're using a custom object called Byline__c, so that's what we'll pass in.
  • There are two contentType values: CSV and XML. We need to specify which one we're using.

This creates the job. Next we have to add a batch.

This is likely the most important, and undocumented, step - particularly when using XML.

  • You will need to construct an XML string that includes all the objects you want to manipulate.
  • For the purposes of this method I found it easier to create an objects parameter on addBatch and pass it in. We'll walk through this in detail shortly.
  • Notice too that the url now includes the jobId that was returned from the createJob response.

Lastly we close the job.

As you can see, this is a pretty simple operation.

Before we pull it all together, let's look at one more method I've created to facilitate the Bulk API operation. The reason I didn't include this method above is you'll see it's very specific to the particular use case; i.e. we're looping through a lot of data and constructing the object data we'll eventually pass into the addBatch method.

Okay, there's a bit going on here. Once you look, though, you'll see that it's not too complex.

  • The first thing to point out is that I'm using a library called simple_salesforce that provides a set of methods for interacting with the Salesforce REST API. Yes, I'm combining SOAP and REST APIs!
  • I perform a SOQL query to get the records that have a published link. This is returned as a Python dictionary from the query_all method.
  • Since it's a dictionary I can easily get all the records and iterate through them all.
  • Using the URLs I identified above, I use requests to call each of the URLs to get the JSON responses. It's then simple to pull out the count or shares.
  • Lastly, we add the data we pulled from the JSON responses and add it to the objectXml string that is ultimately returned. It's worth noting that the Id value is required; everything else added to this object is updated in Salesforce.

Pretty simple!

Okay, let's pull this all together.

As you can see, we're simply calling our methods and evaluating the responses to get data that we pass into other methods.

  • Get the sessionId from the login. You could also grab the instance here with a simple regex.
  • Create a job and grab the jobId.
  • Create the objectXml data and pass it into addBatch to create the batch.
  • Close the batch, which starts the execution.

Now, let's look at the job execution. Login into Salesforce and click Setup -> Jobs, and Bulk Data Load Jobs.

Jobs

You can click the individual job to see the full details.

And that's a wrap! I hope this helps explain the process so that, when you attempt to do something like this yourself, it won't take you as long as it took me.

Announcing the Salesforce Accelerators for Windows Store Apps

Yesterday I was pleased to announce the Salesforce Accelerators for Windows Phone 8 Apps. Today I'm excited to tell you about the Salesforce Accelerators for Windows Store Apps:

These accelerators exist to make it easier for you to get started building Windows 8 store apps and work directly with the Salesforce Toolkits for .NET. Take a look at this short video to see just how easy it is to get started.

Let's look in greater detail at how all of this works.

Using the DeveloperForce.Windows8.Login NuGet

Using the DeveloperForce.Windows8.Login NuGet is pretty straightforward and only involves a few steps.

  1. Setup a Connected App in Salesforce (instructions here). Be sure to Enable OAuth Settings, at least choose Full access (full) and set the Callback URL to sfdc://success.

  2. Install the NuGet Package via the command line ...

    Install-Package DeveloperForce.Windows8.Login
    

    ... or using Manage NuGet Packages in Visual Studio. When you install this NuGet package you also get the DeveloperForce.Force and DeveloperForce.Common NuGet packages, which are defined as dependencies.

  3. Open MainPage_SFDC.xaml.cs and change the ConsumerKey value to the one specified by your Connected App.

  4. Open MainPage.xaml.cs wire up the Page_Loaded event. (You can also do this from the designer, as shown in the video.)

  5. Make the MainPage_Loaded asynchronous and call the GetAccessToken method.

  6. Run the application.

As you can see, using the NuGet is quite simple and takes away the guess work and trouble of setting up the user login experience. Nevertheless, it's worth noting a few things about how it all works.

  • App_SFDC.xaml.cs is a partial class that extends the functionality of App by defining three public properties: AccessToken, RefreshToken, and InstanceUrl. These values are returned to us and set after the user logs in. Having these as public properties gives us the ability to share these around the app so that we can use them when making subsequent REST API calls.

  • MainPage_SFDC.xaml.cs is a partial class that extends the default MainPage.xaml.cs through the GetAccessToken method. It contains all the logic for interacting with the WebAuthenticationBroker which manages the authentication process for Windows Store Apps.

  • The GetAccessToken method first creates a set of URIs for the login process. It then initiates the WebAuthenticationBroker process by calling AuthenticateAsync. If the response comes back as a success the response URI is decoded and the AccessToken, RefreshToken, and InstanceUrl values are specified in the app variable.

  • Once the login process completes the MainPage.xaml is loaded.

That's all it takes. After you login you'll be back on a blank MainPage.xaml but you'll have your AccessToken available to use when calling the Salesforce1 Platform REST APIs, which is a great transition to the DeveloperForce.Windows8.Samples.Accounts NuGet package accelerator.

Using the DeveloperForce.Windows8.Samples.Accounts NuGet

An access token is worthless if you don't do anything with it.

Using the DeveloperForce.Windows8.Samples.Accounts NuGet makes it easy to create a page where you can query and view your account information. It is designed to demonstrate how to use the access token and instance url retrieved during the login process.

To use this NuGet, just follow these quick steps:

  1. Install the NuGet Package via the command line ...

    Install-Package DeveloperForce.Windows8.Samples.Accounts
    

    ... or using Manage NuGet Packages in Visual Studio.

  2. After calling GetAccessToken navigate the user to the newly added AccountsPage.xaml.

That's it! Now run it and see it in action.

As with the previous accelerator, it will help if you know a few things about how this works. Here's the code that makes it function.

  • You can see that we first set our app variables so that we can get values like AccessToken and InstanceUrl.

  • Next we create an instance of the ForceClient.

  • We perform an asynchronous query using a simple SOQL select statement.

  • Lastly, we take the records and bind them to an accounts grid on the page.

It's as simple as that!

It is my hope that these accelerators help get you over the initial hurdles that exist when building new applications that integrate with Salesforce. As always, if you have additional ideas (or find bugs!) you can open a new issue on Github or (if you're so inclinded) take a tab at it yourself and send me a pull request.

I hope this helps!

Announcing the Salesforce Accelerators for Windows Phone 8 Apps

I am pleased to announce the Salesforce Accelerators for Windows Phone 8 Apps, a set of assets designed to make it easier to create new applications using the Salesforce Toolkits for .NET:

The Salesforce Toolkits for .NET, released earlier this year, allow you to interact with the Force.com and Chatter REST APIs using native .NET code on multiple platforms and devices. Many developers and companies have already benefited from these libraries and have built new ASP.NET web applications, Windows Phone 8 apps, and even Windows 8 store apps.

Nevertheless, one of the requests I kept receiving was to create additional tools and samples that make it easier to get started; little nuggets of code that accelerate the process. These accelerators are the answer to those requests and deliver functionality through small, composable NuGet packages.

This short video shows how quick and easy it is to build a Windows Phone 8 app that connects to Salesforce.

Let's dig a little deeper and look at exactly what is happening.

Using the DeveloperForce.WindowsPhone8.Login NuGet

Using the DeveloperForce.WindowsPhone8.Login NuGet is pretty straightforward and only involves a few steps.

  1. Setup a Connected App in Salesforce (instructions here). Be sure to Enable OAuth Settings, at least choose Full access (full) and set the Callback URL to sfdc://success.

  2. Install the NuGet Package via the command line ...

    Install-Package DeveloperForce.WindowsPhone8.Login
    

    ... or using Manage NuGet Packages in Visual Studio. When you install this NuGet package you also get the DeveloperForce.Force and DeveloperForce.Common NuGet packages, which are defined as dependencies.

  3. Set LoginPage.xaml (installed with the NuGet) as the default page by changing Navigation Page in WMAppManifest.xml to Pages\LoginPage.xaml

  4. Open Pages\LoginPage.xaml.cs and change the ConsumerKey value to the one specified by your Connected App.

  5. Run the application.

As you can see, using the NuGet is quite simple and takes away the guess work and trouble of setting up the user login experience. Nevertheless, it's worth noting a few things about how it all works.

  • App_SFDC.xaml.cs is a partial class that extends the functionality of App by defining three public properties: AccessToken, RefreshToken, and InstanceUrl. These values are returned to us and set after the user logs in. Having these as public properties gives us the ability to share these around the app so that we can use them when making subsequent REST API calls.

  • The LoginPage.xaml has a WebBrowser control. The user will log into Salesforce from within this control.

  • There is a set of constants defined at the top of the LoginPage.xaml.cs: AuthorizationEndpointUrl, ConsumerKey, CallbackUrl, and ApiVersion. The only value you must change is ConsumerKey as by default it is set to nonsense.

  • The LoginPage constructor enables scripts on the WebBrowser control. This is required for the login process to work.

  • The OnNavigatedTo event fires when the user is navigated to the login page. It constructs a URL to the Salesforce login page (using a helper from the DeveloperForce.Common NuGet) and then navigates the WebBrowser control to the page. This is where the user logs in and authorizes the application.

  • After the user logs in the WebBrowser_Navigating method is fired. If the return URI has the "sfdc://success" callback URI then we know that the login has been successful. The returned querystring contains the AccessToken, RefreshToken, and InstanceUrl; these values are grabbed and stored as global variables.

  • Lastly, the user is redirected back to the MainPage.xaml after a successful login. (Which you can see on line 18 in the code snippet above.)

That's all it takes. After you login you'll be back on a blank MainPage.xaml but you'll have your AccessToken available to use when calling the Salesforce1 Platform REST APIs, which is a great transition to the DeveloperForce.WindowsPhone8.Samples.Accounts NuGet package accelerator.

Using the DeveloperForce.WindowsPhone8.Samples.Accounts NuGet

An access token is worthless if you don't do anything with it.

Using the DeveloperForce.WindowsPhone8.Samples.Accounts NuGet makes it easy to create a page where you can query and view your account information. It is designed to demonstrate how to use the access token and instance url retrieved during the login process.

To use this NuGet, just follow these quick steps:

  1. Install the NuGet Package via the command line ...

    Install-Package DeveloperForce.WindowsPhone8.Samples.Accounts
    

    ... or using Manage NuGet Packages in Visual Studio.

  2. Instead of navigating the user to the MainPage.xaml after logging in, navigate them to Pages\AccountsPage.xaml. In the WebBrowser_Navigating event on LoginPage.xaml.cs change URI as follows:

That's it! Now run it and see it in action.

As with the previous accelerator, it will help if you know a few things about how this works. Here's the code that makes it function.

  • You can see that we first ensure we have the InstanceUrl and AccessToken variables available.

  • Next we create an instance of the ForceClient.

  • We perform an asynchronous query using a simple SOQL select statement.

  • Lastly, we take the records and bind them to an accounts list on the page.

It's as simple as that!

It is my hope that these accelerators help get you over the initial hurdles that exist when building new applications that integrate with Salesforce. As always, if you have additional ideas (or find bugs!) you can open a new issue on Github or (if you're so inclinded) take a tab at it yourself and send me a pull request.

I hope this helps!