1 Reply Latest reply on Sep 22, 2014 2:04 PM by Robin West

    LinkOS iOS Wrappers for Unity3D

    Chris Misztur

      This is going to be a work in process. 

      Props go to Zebra developers and their ISV team for helping!


      #import <ExternalAccessory/ExternalAccessory.h>
      #import "ZebraPrinterConnection.h"
      #import "MfiBtPrinterConnection.h"
      #import "TcpPrinterConnection.h"
      #import "ZebraPrinter.h"
      #import "ZebraPrinterFactory.h"
      #import "ToolsUtil.h"
      
      //object to JSON string
      NSString* objectToJson(NSObject* obj)
      {
        if( NSClassFromString( @"NSJSONSerialization" ) )
        {
              if( [NSJSONSerialization isValidJSONObject:obj] )
        {
        NSError *error = nil;
        NSData *jsonData = [NSJSONSerialization dataWithJSONObject:obj options:0 error:&error];
                  
        if( jsonData && !error )
        return [[[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding] autorelease];
        else
        NSLog( @"jsonData was null, error: %@", [error localizedDescription] );
              }
        }
          
       return @"{}";
      }
      
      //convert UTF8 NSString to a managed string
      char* cStringCopy(const char* string)
      {
          if(string == NULL)
              return NULL;
          
          char* res = (char*)malloc(strlen(string) + 1);
          strcpy(res, string);
          
          return res;
      }
      
      //convert managed string to NSSTring
      static NSString* CreateNSString(const char* string)
      {
          if(string != NULL)
              return [NSString stringWithUTF8String:string];
          else
              return [NSString stringWithUTF8String:""];
          
      }
      
      /*void runOnMainQueueWithoutDeadlocking(void (^block)(void))
      {
          if([NSThread isMainThread])
          {
              block();
          }
          else
          {
              dispatch_sync(dispatch_get_main_queue(),block);
          }
      }*/
      
      id<ZebraPrinterConnection, NSObject> getBluetoothPrinterConnection(NSString* serialNumber)
      {
          return [[MfiBtPrinterConnection alloc] initWithSerialNumber:serialNumber];
      }
      
      id<ZebraPrinterConnection, NSObject> getTcpPrinterConnection(NSString* address, NSInteger port)
      {
          return [[TcpPrinterConnection alloc] initWithAddress:address andWithPort:port];
      }
      
      extern "C"
      {
          
          int GetConnectedPrinterCount()
          {
              int count = 0;
              
              EAAccessoryManager *sam = [EAAccessoryManager sharedAccessoryManager];
              NSArray *connectedAccessories = [sam connectedAccessories];
              
              for (EAAccessory *accessory in connectedAccessories)
              {
                  if([accessory.protocolStrings indexOfObject:@"com.zebra.rawport"] != NSNotFound)
                  {
                      count++;
                  }
              }
              
              return count;
              
          }
          
          const char* GetConnectedPrinterSerialNumbers()
          {
              NSMutableArray *snArray = [[NSMutableArray alloc] init];
              
              EAAccessoryManager *sam = [EAAccessoryManager sharedAccessoryManager];
              NSArray *connectedAccessories = [sam connectedAccessories];
              
              for (EAAccessory *accessory in connectedAccessories)
              {
                  if([accessory.protocolStrings indexOfObject:@"com.zebra.rawport"] != NSNotFound)
                  {
                      [snArray addObject:[NSString stringWithString:accessory.serialNumber]];
                  }
              }
              
              NSString *json = objectToJson(snArray);
              
              return cStringCopy(json.UTF8String);
          }
          
          const char* GetFirstConnectedPrinterSerialNumber()
          {
              NSString *serialNumber = @"";
              
              EAAccessoryManager *sam = [EAAccessoryManager sharedAccessoryManager];
              NSArray *connectedAccessories = [sam connectedAccessories];
              
              for (EAAccessory *accessory in connectedAccessories)
              {
                  if([accessory.protocolStrings indexOfObject:@"com.zebra.rawport"] != NSNotFound)
                  {
                      serialNumber = accessory.serialNumber;
                      break;
                  }
              }
              
              return cStringCopy([serialNumber UTF8String]);
          }
          
          /*
          //BROKEN
          bool __SendZpl(const char* serialNumber, const char* zpl)
          {
              __block bool success = NO;
              
              dispatch_semaphore_t sema = dispatch_semaphore_create(0);
              
              dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                  @autoreleasepool {
                      id<ZebraPrinterConnection, NSObject> thePrinterConn = getBluetoothPrinterConnection(CreateNSString(serialNumber));
                      success = [thePrinterConn open];
                      
                      NSError *error = nil;
                      success = success && [thePrinterConn write:[CreateNSString(zpl) dataUsingEncoding:NSUTF8StringEncoding] error:&error];
                      success = success && !error;
                      
                      [thePrinterConn close];
                      [thePrinterConn release];
                  }
                  
                  dispatch_semaphore_signal(sema);
              });
              
              dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
              
              return success;
          }*/
          
          bool SendZpl(const char* serialNumber, const char* zpl)
          {
              __block bool success = NO;
              __block NSString *zplString = CreateNSString(zpl);
              __block NSString *serialNumberString = CreateNSString(serialNumber);
              
              dispatch_group_t group = dispatch_group_create();
              
              dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                  @autoreleasepool {
                      id<ZebraPrinterConnection, NSObject> thePrinterConn = getBluetoothPrinterConnection(serialNumberString);
                      success = [thePrinterConn open];
                      
                      NSError *error = nil;
                      NSLog(@"Start Printing");
                      
                      success = success && [thePrinterConn write:[zplString dataUsingEncoding:NSUTF8StringEncoding] error:&error];
                      NSLog(@"Done Printing");
                      success = success && !error;
                      
                      [thePrinterConn close];
                      [thePrinterConn release];
                  }
                  
              });
              
              dispatch_group_notify(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {
              });
              
              dispatch_release(group);
              
              return success;
          }
          
          //TODO
          bool PrintStoredFormat(const char* serialNumber, const char* formatPath)
          {
              __block bool success = NO;
              
              dispatch_semaphore_t sema = dispatch_semaphore_create(0);
              
              dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                  @autoreleasepool {
                      id<ZebraPrinterConnection, NSObject> thePrinterConn = getBluetoothPrinterConnection(CreateNSString(serialNumber));
                      success = [thePrinterConn open];
                      
                      if(success)
                      {
                          NSError *error = nil;
                          
                          id<ZebraPrinter,NSObject> printer = [ZebraPrinterFactory getInstance:thePrinterConn error:&error];
                          
                          if(printer && !error)
                          {
                              id<FormatUtil, NSObject> formatUtil = [printer getFormatUtil];
                              
                              success = success && [formatUtil printStoredFormat:CreateNSString(formatPath) withDictionary:nil error:&error];
                              success = success && !error;
                          }
                      }
                      
                      [thePrinterConn close];
                      [thePrinterConn release];
                  }
                  
                  dispatch_semaphore_signal(sema);
              });
              
              dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
              
              return success;
          }
          
          //TODO
          bool PrintConfigurationLabel(const char* serialNumber)
          {
              bool success = NO;
              
              id<ZebraPrinterConnection, NSObject> thePrinterConn = getBluetoothPrinterConnection(CreateNSString(serialNumber));
              success = [thePrinterConn open];
              //NSLog(@"printer connection open: %d", success);
              
              if(success)
              {
                  NSError *error = nil;
                  
                  id<ZebraPrinter,NSObject> printer = [ZebraPrinterFactory getInstance:thePrinterConn error:&error];
                  
                  if(printer!=nil && error == nil)
                  {
                      id<ToolsUtil, NSObject> toolsUtil = [printer getToolsUtil];
                      
                      success = success && [toolsUtil printConfigurationLabel:&error];
                      success = success && !error;
                  }
              }
              
              [thePrinterConn close];
              [thePrinterConn release];
              
              return success;
          }
          
      }
      
      
      

       

      using UnityEngine;
      using System.Collections;
      using System.Runtime.InteropServices;
      using System;
      
      public class ZebraAPI 
      {
          [DllImport("__Internal")]
          public static extern int GetConnectedPrinterCount();
          
          [DllImport("__Internal")]
          private static extern IntPtr getConnectedPrinterSerialNumbers();
          
          public static string GetConnectedPrinterSerialNumbers()
          {
              IntPtr ptr = getConnectedPrinterSerialNumbers();
              return  Marshal.PtrToStringAnsi(ptr);
          }
          
          [DllImport("__Internal")]
          private static extern IntPtr getFirstConnectedPrinterSerialNumber();
          
          public static string GetFirstConnectedPrinterSerialNumbers()
          {
              IntPtr ptr = getFirstConnectedPrinterSerialNumber();
              return  Marshal.PtrToStringAnsi(ptr);
          }
          
          [DllImport("__Internal")]
          public static extern bool SendZpl(string serialNumber, string zpl);
          
          [DllImport("__Internal")]
          public static extern bool PrintStoredFormat(string serialNumber, string formatPath);
          
          [DllImport("__Internal")]
          public static extern bool PrintConfigurationLabel(string serialNumber);
      }