Product Terminal

Since ProductLayerSDK 0.3 has added OS X support, let’s build a Mac command line utility which lets you quickly search for products by GTIN (the barcode number). This has gotten simpler by many orders of magnitude since as of late you can also integrate the SDK via CocoaPods.

All API calls require a valid API key which you can create on the Applications page of your developer profile. If you haven’t done so yet, please create an account for yourself. The same user account works for both developer.productlayer.com as well as prod.ly. As soon as you create a new application your account is upgraded to be a developer account.

Take note of the key, for all public tutorial we’ll be using this one. You are welcome to use it for testing as well, but bear in mind that it might stop working in the future. For production apps you definitely have to get one of your own.

e0037c2f-21b5-4346-9637-f81803fdff1e

Start out by creating a new OS X Command Line Tool. In Xcode, choose File – New Project. Choose the Command Line Tool option under OS X – Application.

New Command Line Tool

Give the project a short name, it will be an Objective-C project.

Project Name

OS X Command Line Tools are very simple, all their code is in the main.m. But before we proceed any further you need to add the ProductLayerSDK. Close the project. When we return it will be via work space.

In your terminal navigate to the place where you placed the xcodeproj. Create a new Podfile with the following contents:

platform :osx, '10.8'
pod 'ProductLayerSDK'

This states that your project is for Mac and you always want the latest version of the SDK.

$ pod install
Analyzing dependencies
Downloading dependencies
Installing DTFoundation (1.7.4)
Installing DTKeychain (1.0.0)
Installing ProductLayerSDK (0.3.0)
Generating Pods project
Integrating client project

[!] From now on use `prodterm.xcworkspace`.

Open the mentioned Xcode Workspace file and marvel at the ease of integration. CocoaPods makes this really simple. No longer do you need to work with multi-level git submodules.

Integrated ProductLayer SDK

The following code snippets all go into the above mentioned main.m within the curly braces of the autorelease pool.

int main(int argc, const char * argv[])
{
   @autoreleasepool
   {
 
      // print usage if there are too few parameters
      if (argc<2)
      {
         printf("Usage: prodterm \n");
         return 1;
      }
 
      // get GTIN from arguments
      NSString *GTIN = [NSString stringWithUTF8String:argv[1]];
 
      // continue here...
   }
 
   return 0;
}

If the tool is called with too few parameters we are printing out usage instructions. To pass a command line argument to a debugged command line tool, you specify it under Arguments in the scheme editor. Let’s enter the barcode number of Barcodes with iOS, a book by yours truly: 9781617292156

Screen Shot 2014-12-05 at 16.04.43

Add an import for ProductLayer.h at the top of main.m and then add this code to get a reference to the shared PLYServer and set your API key:

// configure server
PLYServer *server = [PLYServer sharedServer];
[server setAPIKey:@"e0037c2f-21b5-4346-9637-f81803fdff1e"];

Terminal apps do not have a UI and therefore no run loop. They start at the beginning of main() and end once you return from this function. API calls to ProductLayer might take some time and so we need to be able to wait before exiting the app until we result (or error) have been returned to us.

With the server reference set up, you can now make calls to Product Layer. Note how execution halts on the main thread until the completion handler block was executed. Signalling the semaphore (on background queue) lets the main thread proceed to exit the app with a successful status (0).

// semaphore to wait for completion of request
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
 
// look for GTIN of "Barcodes with iOS" book, in any language
[server performSearchForGTIN:GTIN
                    language:nil
                  completion:^(id result, NSError *error)
{
   if (!result)
   {
      printf("%s\n", [[error localizedDescription] UTF8String]);
 
      // unlock the semaphore so that the app continues
      dispatch_semaphore_signal(sema);
 
      return;
   }
 
   // there might always be multiple results without language
   // restriction, find the best one based on the user's language
   PLYProduct *bestProduct =
            PLYProductBestMatchingUserPreferredLanguages(result);
 
   printf("Found: '%s' in language '%s'\n",
           [bestProduct.name UTF8String],
           [bestProduct.language UTF8String]);
 
   // unlock the semaphore so that the app continues
   dispatch_semaphore_signal(sema);
}];
 
// wait for finishing of operation
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);

If there is a nil result then an error occurred and the error message is logged. Otherwise you have gotten an array of PLYProduct objects which match the passed barcode. Since you didn’t restrict the language there might be multiple language versions of the same product returned to you. A helper method looks at the users preferred languages and determines the best matching product from the array. This is simply output via printf.

Build&Run the tool and you will see the output on the console.

prodterm in action

Alternatively you can also find the built product prod term (Right-click on the product and “Show in Finder”) and use it in other places.

Conclusion

As you have seen it could not be simpler to integrate the ProductLayer SDK. In a few minutes you have a running app that is able to query our database. This tutorial focussed on OS X, but calling the API is the same on iOS. On the mobile platform you get additional help with several nifty view controllers. These we will explore in a future tutorial.

Oh, and did I mention that there is a great book to introduce you to the world of barcodes?

Submit a Comment

Your email address will not be published. Required fields are marked *