Friday, May 25, 2012

Read and Write NFC Tags with PhoneGap

The phonegap-nfc plugin allows you to read and write NFC tags from a PhoneGap application using JavaScript.

The plugin originally supported Android. The latest release adds support for Blackberry 7.0.

After installing the plugin into your PhoneGap app (See README) it is easy to start scanning tags.

Create a function that will handle the NFC events.

function onNfc(nfcEvent) {
    // display the tag as JSON
    alert(JSON.stringify(nfcEvent.tag));
}

Create the optional success and failure callbacks. These callbacks are for success and failure of adding the listener.

function success(result) {
    console.log("Listening for NFC Messages");
}

function failure(reason) {
    alert("Failed to add NDEF listener");
}

Register listener. When the listener is added, the plugin will generate an NFC Event whenever a tag is scanned.

nfc.addNdefListener(onNfc, success, failure);

Deploy the application and scan a tag.

Example Project

The NFC Reader example project has been updated for Blackberry.

More info

The PhoneGap NFC API is documented in the README file.

Kevin wrote Building NFC applications with Android last year. Most of that information still applies.

Wednesday, May 23, 2012

The all-new Chariot Emerging Tech site

The all-new Chariot Emerging Tech Site

We at Chariot Solutions have been working steadily on a web site that pulls together all of our media. This site, Chariot Emerging Tech, is now live, and we will be adding more content to it regularly. Currently, it contains all of our screencasts, both internally and for events such as Philly Emerging Tech. It also contains all of our podcast episodes from the TechCast, DevNews, BusinessCast, and other feeds. We're looking at importing other media as well.
We hope this will be a helpful free resource for your tech research. Soon you'll see features on various technologies, such as Big Data, Mobile Application Development Frameworks and the Spring echosystem.
Enjoy,
Ken Rimple, Director of Education Services, Chariot Solutions

Thursday, May 17, 2012

Testing Spring Roo add-ons

This is a combination of a two-part article on Spring Roo and Testing I originally posted on rimple.com, where I write about Spring Roo topics periodically around my book, Spring Roo in Action., co-authored with InfoQ's Srini Penchikala..

You may find more information about writing Roo add-ons from my recent ETE / Richmond JUG presentation, Leaping Forward with Roo add-ons.

How to test Roo add-ons

I'm working on updates to several Roo add-ons, which I am going to be pushing out to the Silly Weasel Roo repository soon. Here are some challenges and how I overcame them.

Our examples work against the Silly Weasel Coffeescript add-on, which is an extension of the one I started in the book. Over time, we'll be ramping up the features of that add-on to support the major features of the Maven Plug-In itself.

Friday, May 4, 2012

Camera Access from Android Browser

The browser in Android 4 is able to take pictures from a web page and display them without any plugins or server interaction. This demo uses the Device API and File API to take and display a picture on a phone using the browser.

Try it on your Android phone http://don.github.com/html-cam/.

I wrote this demo after reading David Calhoun’s post about Android implementing device APIs.

This works on my Google Nexus S running Ice Cream Sandwich (4.0.4). The Device API works on Samsung Galaxy Tab 10.1 with Honeycomb (3.2) but the File APIs do not. YMMV.

Loading images from the gallery is finicky. Images load from the device but fail to load from Picasa albums. I had to alter the image blob and change data:base64 to data:image/jpeg;base64 to get photos from galleries to display.

I kludge the photo orientation based on the device orientation, clearly there is a better solution.

It's possible to run the browser out of memory. I'm guessing this is because a huge photo is encoded into a base64 string. Maybe window.URL.createObjectURL(file) would work better than reading the image with FileReader?

Adjusting the input tag can control the input types:

<input type="file" />
Browser prompts for camera, camcorder, sound recorder, 
  music track, or gallery

<input type="file" accept="image/*" />          
Browser prompts for camera or gallery   

<input type="file" accept="image/*;capture=camera" />           
Browser goes directly to the camera

For more info see the github project.

UPDATE 2012-05-06
It looks like Facebook's mobile website allows camera access from a browser on Android.

Friday, April 27, 2012

Securing Data in iOS

There are numerous ways to secure data that you are storing on an iOS device.

The Simple/Built-in Way

The simplest way is to take advantage of the iOS Data Protection (iOS 4+). This can be accomplished by setting an attribute on a file like this:

    [[NSFileManager defaultManager] createFileAtPath:[self filePath]
                    contents:[@"super secret file contents" dataUsingEncoding:NSUTF8StringEncoding]
                    attributes:[NSDictionary dictionaryWithObject:NSFileProtectionComplete
                                                           forKey:NSFileProtectionKey]];

There are several different levels of file protection. The following was taken from the NSFileManager class reference from Apple:

  • NSFileProtectionNone - no file protection
  • NSFileProtectionComplete - file is encrypted when the device is locked or booting
  • NSFileProtectionCompleteUnlessOpen - file is encrypted and can only be opened when the device is unlocked. Once open, the file can continue to accessed even if the user locks the device.
  • NSFileProtectionCompleteUntilFirstUserAuthentication - The file is stored in an encrypted format on disk and cannot be accessed until after the device has booted. After the user unlocks the device for the first time, your application can access the file and continue to access it even if the user subsequently locks the device.

A Core Data sqlite store can also be encrypted by setting the NSFileProtectionKey file attribute to one of the above values (after you create your persistent store coordinator).

However, an important thing to realize is that this type of data protection requires the device to have a passcode set on it (http://support.apple.com/kb/HT4175).

CommonCrypto

What if you really need to insure that your data is protected regardless of whether the device has a passcode set? One way is to use the CommonCrypto libraries from Apple. This can be fairly complex. There is a great write up here from Rob Napier on what's involved. Fortunately, he has also provided a wrapper that greatly simplifies this process here. Using this library (or writing your own), you can encrypt your data and store it wherever you need. If you are using Core Data, you could write an NSValueTransformer for the Core Data entity attributes that require encryption using CommonCrypto or the RNCrypto library to encrypt/decrypt the attribute values.

SQLCipher

One more way to protect your data, specifically data that you want to store in a SQLite database, would be to use SQLCipher. SQLCipher encrypts/decrypts data at the page level and is transparent to your application code. You still use the standard SQLite APIs, with one additional method call when accessing the database (passing your key to sqlite). There are excellent instructions on setting it up for use in an iOS project here.

You can build SQLCipher as a set of static libraries by following the same iOS instructions with some modifications and additions. Here are the high level steps:

  1. Instead of creating a view based iOS project, create a static library project
  2. Follow the balance of the steps for including SQLCipher in your project
  3. Add a new "Aggregate" build target
  4. Add a "Run Script" build phase and paste the following script into it. This will build both the simulator and iOS based targets for the libcrypto, libsqlcipher, and libssl libraries.
  5. xcodebuild -project ${PROJECT_NAME}.xcodeproj -sdk iphonesimulator -target ${PROJECT_NAME} -configuration ${CONFIGURATION} clean build CONFIGURATION_BUILD_DIR=${BUILD_DIR}/${CONFIGURATION}-iphonesimulator
    
    xcodebuild -project ${PROJECT_NAME}.xcodeproj -sdk iphoneos -target ${PROJECT_NAME} -configuration ${CONFIGURATION} clean build CONFIGURATION_BUILD_DIR=${BUILD_DIR}/${CONFIGURATION}-iphoneos
    
  6. Add another "Run Script" build phase and paste the following script into it. This will merge the simulator and iOS builds into one for each library. These three libraries are what would be added to a project using SQLCipher.
  7. CRYPTO_LIB="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/libcrypto.a" &&
    SQLCIPHER_LIB="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/libsqlcipher.a" &&
    SSL_LIB="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/libssl.a" &&
    
    DEVICE_CRYPTO_LIB="${BUILD_DIR}/${CONFIGURATION}-iphoneos/libcrypto.a" &&
    DEVICE_SQLCIPHER_LIB="${BUILD_DIR}/${CONFIGURATION}-iphoneos/libsqlcipher.a" &&
    DEVICE_SSL_LIB="${BUILD_DIR}/${CONFIGURATION}-iphoneos/libssl.a" &&
    
    UNIVERSAL_LIBRARY_DIR="${BUILD_DIR}/${CONFIGURATION}-iphoneuniversal" &&
    
    
    # Create framework directory structure.
    rm -rf "${UNIVERSAL_LIBRARY_DIR}" &&
    mkdir -p "${UNIVERSAL_LIBRARY_DIR}" &&
    
    # Generate universal binary for the device and simulator.
    lipo "${CRYPTO_LIB}" "${DEVICE_CRYPTO_LIB}" -create -output "${UNIVERSAL_LIBRARY_DIR}/libcrypto" &&
    lipo "${SQLCIPHER_LIB}" "${DEVICE_SQLCIPHER_LIB}" -create -output "${UNIVERSAL_LIBRARY_DIR}/libsqlcipher" &&
    lipo "${SSL_LIB}" "${DEVICE_SSL_LIB}" -create -output "${UNIVERSAL_LIBRARY_DIR}/libssl"
    

Once completed, you can build your new aggregate target and there should be 3 libraries located in a subdirectory within your project build directory. Just add these to your XCode project as you would any other library and you are good to go.

Monday, April 9, 2012

Sunday, April 1, 2012

Notes from the Phorum -- Cloud means something a little different to everyone

Enterprise

Enterprise users get dinged for cloud-washing: buying VMware and saying they're running a cloud.  But many of them do want to offer a "private cloud".  Some of the differences?  Automation, standard cloud "machine" configurations, self-service provisioning, a single cloud for all business units, calculating runtime costs and charging projects for them.  Some of the obstacles?  Lack of automation in existing processes, trying to bring complex legacy applications on board, trying to migrate existing staff and tools "to the cloud".  A key recommendation was when building a private cloud, start it as a totally separate effort that offers capabilities to the business, and strive to reach the point where they will go to you instead of a third-party cloud.

But why run a private cloud?  The number one reason the business prefers the cloud is that it facilitates speed and agility -- effectively taking much of the budgeting and procurement out of a project.  And if you try a project and it doesn't work, you shut down the cloud instances and wash your hands with much less regret.  As for IT, a well-implemented private cloud can further increase the utilization of hardware over virtualization alone, and the automation allows fewer administrators for the same quantity of hardware.  Plus you're offering the business capabilities, instead of hurdles.

Along those lines, there was significant discussion of the changing role of IT as a business moves more toward the cloud.  Instead of the detailed management of servers, virtualization consoles, and execution environments, it becomes managing multiple sets of capabilities -- one-off hardware required for legacy applications, virtual machines, private cloud, public cloud, etc.  While you might promote the cloud for mainstream projects, there will always be some with special requirements that place it somewhere else along that spectrum, and the goal is more to shepherd each project to the right home.

With all that said, there was a lot of enthusiasm for public cloud offerings.  While the security of a public cloud service is still the number one concern, even among businesses that are using the cloud, there were many arguments made that such concerns are no longer insurmountable.  Cloud vendors have fewer hardware and software platforms to maintain, and more motivation to do it right (given the cost of a failure).  Plus there's no guarantee that internal employees are less likely to make security mistakes.  "Do you truly believe your company manages their machines better than the next company?  How about, better than a vendor whose business is the cloud?"

Startups

On the other hand, one attendee quipped, "the only thing Enterprise is to me is a rental car company."  The advice to startups came from a totally different direction.  Use the cloud in every possible way -- only be smart about it.

On Software as a Service: Why buy a box of software and a machine to run it, when you can use a lower-cost online service that you don't have to manage and gives you regular feature updates automatically?

On Infrastructure as a Service: No VC will fund you if your business plan shows boxes instead of Amazon.

On Platform as a Service: You could come up with specific requirements, build the perfect software, find the ways to customize it just like you need, and integrate it with other systems.  But we've done that already and poof! this great platform emerged.  Why not just take advantage of that instead?  (Granted, this was SalesForce.com talking.)

In fact, one of the challenges quoted was that there are so many good-looking services that are easy to adopt, you may find yourselves three months down the road before you realize it's not really what you want after all.  So the pearl of wisdom was to define your requirements well in advance, and then find the right combination of services to support them.  Another was to think carefully before you start custom-integrating all these services.  You're better off changing your process to fit the service than spending truckloads of time on custom integration.  Plus there are companies out there who do that already.

Developers

Of course you can build applications for the cloud.  But one point was to realize that's what you're doing going in.  You won't necessarily have multiple machines on the same network segment (or even with multicast capability at all!), different "identical" machines may perform differently, machines or resources may go down at any time, common services like e-mail might not be available, you may be limited in what database it's convenient to use, and so on.

And the cloud isn't automatically cheaper -- in many cases you have to be careful about shutting machines down whenever they're not really in use in order to realize the potential cost savings.  (As an aside, one blog breathlessly proclaims that Amazon has reduced the EC2 price-per-compute-unit by 15% over the course of six years.  Conveniently overlooked: Moore's Law suggests that you should receive 1600% more hardware power per dollar over the same period of time.)  In other cases, the time and cost savings comes from adopting a runtime platform instead of cloud infrastructure (a VM).

Final Thoughts

Overall though, the message was largely the same for everyone -- there are benefits to be reaped from the cloud, but you have to be wise about it.  Plan first, don't just meander toward the cloud and assume you'll get to the right place in time.  you may, but it may be a lot more time than you're counting on.