Using the Caché Objective-C Binding



Similar documents
Using the Caché SQL Gateway

Using the Studio Source Control Hooks

Caché License Management

Try-Catch FAQ. Version February InterSystems Corporation 1 Memorial Drive Cambridge MA

Using Encrypted File Systems with Caché 5.0

Identifying Memory Fragmentation within the Microsoft IIS Environment

Caché Integration with a Network Appliance Filer

Ensemble X12 Development Guide

TIBCO ActiveMatrix BusinessWorks Plug-in for TIBCO Managed File Transfer Software Installation

INTRODUCTION TO OBJECTIVE-C CSCI 4448/5448: OBJECT-ORIENTED ANALYSIS & DESIGN LECTURE 12 09/29/2011

iphone Objective-C Exercises

Introduction to iphone Development

Creating SOAP and REST Services and Web Clients with Ensemble

NVIDIA CUDA GETTING STARTED GUIDE FOR MAC OS X

Using Caché with ODBC

Monitoring Ensemble. Version March InterSystems Corporation 1 Memorial Drive Cambridge MA

SimbaEngine SDK 9.4. Build a C++ ODBC Driver for SQL-Based Data Sources in 5 Days. Last Revised: October Simba Technologies Inc.

Java Web Services SDK

1 Introduction FrontBase is a high performance, scalable, SQL 92 compliant relational database server created in the for universal deployment.

NVIDIA CUDA GETTING STARTED GUIDE FOR MAC OS X

PetaLinux SDK User Guide. Application Development Guide

Xcode User Default Reference. (Legacy)

1 Changes in this release

Objective-C and Cocoa User Guide and Reference Manual. Version 5.0

TIBCO Enterprise Administrator Release Notes

CA Clarity Project & Portfolio Manager

Users Guide. Ribo 3.0

Customize Mobile Apps with MicroStrategy SDK: Custom Security, Plugins, and Extensions

SDK Code Examples Version 2.4.2

Oracle Enterprise Manager

SOA Software: Troubleshooting Guide for Agents

ios Team Administration Guide (Legacy)

EMC Documentum Content Services for SAP iviews for Related Content

Oracle Tuxedo Systems and Application Monitor (TSAM)

An Oracle White Paper June Security and the Oracle Database Cloud Service

Release Bulletin EDI Products 5.2.1

Data Access Guide. BusinessObjects 11. Windows and UNIX

Quick Start SAP Sybase IQ 16.0

MySQL Installer Guide

RTI Database Integration Service. Getting Started Guide

MA-WA1920: Enterprise iphone and ipad Programming

CA Workload Automation Agent for Databases

Password Management. Password Management Guide HMS 9700

FileMaker 11. ODBC and JDBC Guide

How To Customize An Orgsync App On Anorus Mobile Security Suite On A Microsoft Ipad Oracle 2.5 (Ios) On A Pc Orca 2.2 (Iphone) On An Android Orca2 (Ip

Silect Software s MP Author

Developing Ensemble Productions

TROUBLESHOOTING GUIDE

User Guidance. CimTrak Integrity & Compliance Suite

Nimsoft Monitor. dns_response Guide. v1.6 series

ODBC Driver User s Guide. Objectivity/SQL++ ODBC Driver User s Guide. Release 10.2

TIBCO Silver Fabric Continuity User s Guide

QAD Enterprise Applications. Training Guide Demand Management 6.1 Technical Training

CA DLP. Stored Data Integration Guide. Release rd Edition

Ahsay BackupBox v1.0. Deployment Guide. Ahsay TM Online Backup - Development Department

Intel Internet of Things (IoT) Developer Kit

NSPersistentDocument Core Data Tutorial for Mac OS X v10.4. (Retired Document)

How To Use The Correlog With The Cpl Powerpoint Powerpoint Cpl.Org Powerpoint.Org (Powerpoint) Powerpoint (Powerplst) And Powerpoint 2 (Powerstation) (Powerpoints) (Operations

White Paper BMC Remedy Action Request System Security

1 First Steps. 1.1 Introduction

SEER Enterprise Shared Database Administrator s Guide

Integrating VoltDB with Hadoop

Microsoft Dynamics GP. SmartList Builder User s Guide With Excel Report Builder

National Fire Incident Reporting System (NFIRS 5.0) Configuration Tool User's Guide

PN Connect:Enterprise Secure FTP Client Release Notes Version

Start Oracle Insurance Policy Administration. Activity Processing. Version

FileMaker 12. ODBC and JDBC Guide

Monitoring Replication

CA Clarity PPM. Connector for Microsoft SharePoint Product Guide. Service Pack

Novell ZENworks 10 Configuration Management SP3

CA Nimsoft Monitor. Probe Guide for Active Directory Server. ad_server v1.4 series

Implementing McAfee Device Control Security

eggon SDK for ios 7 Integration Instructions

Infor Cloud Printing Service Administration Guide

Tag Specification Document

Oracle WebCenter Sites. Backup and Recovery Guide 11g Release 1 (11.1.1)

Aradial Installation Guide

NetIQ AppManager for Self Monitoring UNIX and Linux Servers (AMHealthUNIX) Management Guide

Jobs Guide Identity Manager February 10, 2012

IBM WebSphere Partner Gateway V6.2.1 Advanced and Enterprise Editions

Working with the Cognos BI Server Using the Greenplum Database

Centrify Mobile Authentication Services

Oracle Agile Engineering Data Management

Oracle Cloud E

Software Distribution Reference

Accessing Your Database with JMP 10 JMP Discovery Conference 2012 Brian Corcoran SAS Institute

Intel System Event Log (SEL) Viewer Utility

FREQUENTLY ASKED QUESTIONS

Tutorial: BlackBerry Object API Application Development. Sybase Unwired Platform 2.2 SP04

OpenLDAP Oracle Enterprise Gateway Integration Guide

TaskCentre v4.5 Run Crystal Report Tool White Paper

Installing a Plug-in

An Introduction to Modern Software Development Tools Creating A Simple GUI-Based Tool Appleʼs XCode Version 3.2.6

Kofax Export Connector for Microsoft SharePoint

System Planning, Deployment, and Best Practices Guide

InfoSphere Master Data Management operational server v11.x OSGi best practices and troubleshooting guide

IGEL Universal Management. Installation Guide

MySQL and Virtualization Guide

User Document. Adobe Acrobat 7.0 for Microsoft Windows Group Policy Objects and Active Directory

Backup Exec Cloud Storage for Nirvanix Installation Guide. Release 2.0

Transcription:

Using the Caché Objective-C Binding Version 2014.1 25 March 2014 InterSystems Corporation 1 Memorial Drive Cambridge MA 02142 www.intersystems.com

Using the Caché Objective-C Binding Caché Version 2014.1 25 March 2014 Copyright 2014 InterSystems Corporation All rights reserved. This book was assembled and formatted in Adobe Page Description Format (PDF) using tools and information from the following sources: Oracle Corporation, RenderX, Inc., Adobe Systems, and the World Wide Web Consortium at www.w3c.org. The primary document development tools were special-purpose XML-processing applications built by InterSystems using Caché and Java.,,,, Caché WEBLINK, and Distributed Cache Protocol are registered trademarks of InterSystems Corporation.,, InterSystems Jalapeño Technology, Enterprise Cache Protocol, ECP, and InterSystems Zen are trademarks of InterSystems Corporation. All other brand or product names used herein are trademarks or registered trademarks of their respective companies or organizations. This document contains trade secret and confidential information which is the property of InterSystems Corporation, One Memorial Drive, Cambridge, MA 02142, or its affiliates, and is furnished for the sole purpose of the operation and maintenance of the products of InterSystems Corporation. No part of this publication is to be used for any other purpose, and this publication is not to be reproduced, copied, disclosed, transmitted, stored in a retrieval system or translated into any human or computer language, in any form, by any means, in whole or in part, without the express prior written consent of InterSystems Corporation. The copying, use and disposition of this document and the software programs described herein is prohibited except to the limited extent set forth in the standard software license agreement(s) of InterSystems Corporation covering such programs and related documentation. InterSystems Corporation makes no representations and warranties concerning such software programs other than those set forth in such standard software license agreement(s). In addition, the liability of InterSystems Corporation for any losses or damages relating to or arising out of the use of such software programs is limited in the manner set forth in such standard software license agreement(s). THE FOREGOING IS A GENERAL SUMMARY OF THE RESTRICTIONS AND LIMITATIONS IMPOSED BY INTERSYSTEMS CORPORATION ON THE USE OF, AND LIABILITY ARISING FROM, ITS COMPUTER SOFTWARE. FOR COMPLETE INFORMATION REFERENCE SHOULD BE MADE TO THE STANDARD SOFTWARE LICENSE AGREEMENT(S) OF INTERSYSTEMS CORPORATION, COPIES OF WHICH WILL BE MADE AVAILABLE UPON REQUEST. InterSystems Corporation disclaims responsibility for errors which may appear in this document, and it reserves the right, in its sole discretion and without notice, to make substitutions and modifications in the products and practices described in this document. For Support questions about any InterSystems products, contact: InterSystems Worldwide Customer Support Tel: +1 617 621-0700 Fax: +1 617 374-9391 Email: support@intersystems.com

Table of Contents About This Book... 1 1 Introduction... 3 1.1 Requirements... 3 1.2 The Caché Objective-C Binding... 3 2 First Steps... 5 2.1 Connecting the Binding to Caché... 5 2.1.1 Secure Connection... 5 2.1.2 Disconnecting... 6 2.2 Simple Example of Accessing a Sample Class... 6 2.2.1 Putting it All Together... 6 2.2.2 Compiling and Building... 8 2.2.3 Compiling SimpleExample with Xcode... 8 2.2.4 Setting up DYLD_LIBRARY_PATH... 9 3 Reference... 11 3.1 Release/Retain Rules... 11 3.1.1 Autorelease Pool... 11 3.2 Objects... 11 3.2.1 Creating a New Object... 12 3.3 Properties... 12 3.3.1 Key/Value Coding... 13 3.3.2 Key/Value Observing... 13 3.4 Methods... 13 3.4.1 Instance Methods... 13 3.4.2 Class Methods... 13 3.5 Queries... 13 3.5.1 Class Queries... 13 3.5.2 Dynamic SQL... 14 3.6 Transactions... 14 4 Error Checking and Debugging... 15 4.1 Debugging... 15 4.2 Objective-C Header Generator... 15 4.2.1 Command Line Tool... 15 4.2.2 Generating Headers Programmatically... 16 4.3 Getting a Stack Trace from an NSException... 16 4.3.1 Include the ExceptionHandling Framework... 16 4.3.2 Enable Stack Traces... 16 4.3.3 Decoding the Stack Trace... 17 4.3.4 Do Not Use @throw in Your Application... 17 Using the Caché Objective-C Binding iii

About This Book The Caché Objective-C binding is implemented in Objective-C and Objective-C++, and utilizes the Caché C++ binding and the underlying ODBC driver as a transport. It is packaged as an Apple framework that can either be embedded into the Cocoa application bundle or installed in one of the Apple framework directories. Who This Book Is For In order to use this book, you should be reasonably familiar with Mac OS X and have some experience with Objective-C. Organization of This Book This book is organized as follows: The chapter Introduction describes the system requirements and architecture of the Objective-C binding. The chapter First Steps gives step by step instructions for writing and compiling an Objective-C binding application. The chapter Reference provides a reference for the behavior of the Objective-C binding. The chapter Error Checking and Debugging describes various tools and procedures that may help you to find or avoid problems in your Objective-C applications. Related Information The following Caché language bindings are also available for use on most operating systems: Using C++ with Caché Using Java with Caché Using the Caché Objective-C Binding 1

1 Introduction For a Mac OS X developer these days, the toolset of choice is the excellent Apple Xcode development environment, along with the Cocoa framework and Objective-C. While Xcode used to support other languages (such as Java), Apple has recently disclosed that Objective-C is the language of choice for Cocoa and Mac development, and that Cocoa-Java support will likely be dropped. The goal of the Objective-C binding is to bring the power and ease of Caché objects to Mac developers in their familiar Cocoa-Objective-C environment. 1.1 Requirements In order to make use of the Objective-C binding for Caché, you need a Mac (either Intel or PowerPC) running Mac OS X 10.4 (Tiger) (or later) and a copy of Xcode 2.2 (or later) installed. Xcode is available either on the OS install CD or as a free download from the Apple Developer Connection (registration required). For Intel/Mac development, you will want to ensure that you have at least version 2.2.1. You will also need to have a copy of Caché 5.1 (or later) installed on your system, as well as a copy of the Objective-C binding itself. 1.2 The Caché Objective-C Binding The Caché Objective-C binding is implemented in Objective-C, Objective-C++, and utilizes the C++ binding and the underlying ODBC driver as a transport. It is packaged as an Apple framework that can either be embedded into the Cocoa application bundle or installed in one of the Apple framework directories (such as /Library/Frameworks or ~/Library/Frameworks). The binding projects objects dynamically, that is, there is no requirement for a code generator to generate projection classes to the local language (although such a tool does exist which can help cut down on runtime errors). Any registered Caché objects can be utilized via the Objective-C binding; all class methods, stored procedures, and queries can also be called; and, in addition, dynamic SQL queries can be executed. The Objective-C binding framework is built as a Universal Binary, which means it can be deployed and run on both PowerPCand Intel-based Macs. Using the Caché Objective-C Binding 3

2 First Steps The first step to using the Caché Objective-C binding is to create a project, either a command line, pure Objective-C program (or library framework) or a GUI Cocoa Application in Xcode. In either case, you will need to ensure that you have the framework specified in the link options (using -framework or by adding the Caché Objective-C binding to the Xcode project) and that your Objective-C source files also include the framework headers: #import <ObjectiveCache/ObjectiveCache.h> 2.1 Connecting the Binding to Caché The next step is to create a connection between the Objective-C binding and a host Caché system. This follows the model established by the C++ binding in that the connection is separated from the logical database: @try // First, connect to Cache ISCConnection* conn = [[ISCConnection alloc] init:@"127.0.0.1[1972]:samples" user:@"_system" passwd:@"sys"]; ISCDatabase* db = [[ISCDatabase alloc] initwithconnection:conn]; @catch (NSException* localexception) NSLog(@"Connection failed: %@", localexception); We always want to wrap calls to the Objective-C binding inside @try/@catch blocks so that the binding will always raise an NSException upon encountering an error. 2.1.1 Secure Connection A secure connection can be made using the -init:principal:level method: @try // First, connect to Cache ISCConnection* conn = [[ISCConnection alloc] init:"127.0.0.1[1972]:samples" principal:@"abc" level:99]; ISCDatabase* db = [[ISCDatabase alloc] initwithconnection:conn]; @catch (NSException* localexception) NSLog(@"Connection failed: %@", localexception); Once connected, the Objective-C binding can be used as described later. Using the Caché Objective-C Binding 5

First Steps 2.1.2 Disconnecting The database object must be destroyed before the disconnect method is called. For example: [db release]; [conn disconnect]; The database has a reference to the connection object, which will cause the physical connection to be kept alive even after the connection object goes out of scope. If you release the database object and then the connection object, they disconnect for themselves. If you disconnect while still using the binding, you get errors! 2.2 Simple Example of Accessing a Sample Class The following simple example demonstrates how the Objective-C binding can be used to access one of the sample classes provided with Caché in the SAMPLES namespace: @try /* Next, open an existing instance of the Sample.Person object and then we retrieve a couple of values. */ obj = [db openid:@"sample.person" ident:@"101"]; if (nil = obj) NSString* cls = [obj get_classname]; NSString* name = [obj Name]; int age = [obj Age]; NSDate* dob = [obj DOB]; @catch (NSException* localexception) NSLog(@"Connection failed: %@", localexception); Values can be updated and saved in a similar manner: [obj setname:@"jobs,steven"]; [obj _Save:1]; Instance methods can be called very easily: int answer = [obj Addition:1 :2]; 2.2.1 Putting it All Together To generate the header files for the Caché classes, run the following commands from the framework/commands directory: Run:./objc_generator -u_system -psys -s127.0.0.1[1972]:samples Sample.Person Run:./objc_generator -u_system -psys -s127.0.0.1[1972]:samples Sample.Address Here is the code all put together, along with the boiler plate Objective-C code that you would need to set up an autorelease pool. Cocoa applications get an autorelease pool from the main run loop, so setting one up is not necessary unless you are creating a new thread. 6 Using the Caché Objective-C Binding

Simple Example of Accessing a Sample Class /* -*- ObjC -*- * * Copyright (c) 2006 InterSystems, Corp. * Cambridge, Massachusetts, U.S.A. All rights reserved. * Confidential, unpublished property of InterSystems. * * SimpleExample.m: Objective-C binding simple example * */ #import <ObjectiveCache/ObjectiveCache.h> #import "Sample_Person.h" #import "Sample_Address.h" /*! * Create a new person object */ NSString* CreatePerson(ISCDatabase* db) NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; // First, we will create a new person Sample_Person* obj = [db create:@"sample.person"]; NSLog(@"Created an instance of %@", [obj get_classname]); // Now, we populate it [obj setname:@"jobs,steve"]; [obj setdob:[nsdate datewithstring:@"1955-02-24 00:00:00-0900"]]; [obj setssn:@"123-45-6789"]; Sample_Address* addr = [obj Office]; [addr setstreet:@"1 Infinite Loop"]; [addr setcity:@"cupertino"]; [addr setstate:@"ca"]; [addr setzip:@"95014"]; // And save... [obj _Save:1]; NSString* objid = [[obj _Id] retain]; NSLog(@"Saved as id %@", objid); // The Objective-C binding returns autoreleased objects, so we // do not need to release anything. [pool release]; return [objid autorelease]; /*! * Display a person object */ void ShowPerson(ISCDatabase* db, NSString* objid) // Open the object: Sample_Person* obj = [db openid:@"sample.person" ident:objid]; if (nil!= obj) NSString* cls = [obj get_classname]; NSString* name = [obj Name]; int age = [obj Age]; NSDate* dob = [obj DOB]; NSLog(@"Object(%@/%@), Name = %@, Age = %d, DoB = %@", objid, cls, name, age, dob); // Or we could just do this and call an instance method [obj PrintPerson]; else NSLog(@"Person %@ not found!", objid); Using the Caché Objective-C Binding 7

First Steps /*! * Delete a person object */ void DeletePerson(ISCDatabase* db, NSString* objid) Sample_Person* clsproxy = [db openclass:@"sample.person"]; [clsproxy _DeleteId:objid :-1]; NSLog(@"Deleted person id %@", objid); /** * Main entry point for unit tests * * @param argc Number of arguments * @param argv Argument vector * @return Exit code for this process */ int main(int argc, char** argv) NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @try NSString* server = @"127.0.0.1[1972]:SAMPLES"; NSString* user = @"_SYSTEM"; NSString* passwd = @"SYS"; ISCConnection* conn = [[ISCConnection alloc] autorelease]; ISCDatabase* db = [[ISCDatabase alloc] autorelease]; [conn init:server user:user passwd:passwd]; [db initwithconnection:conn]; NSLog(@"Connected to: %@ as %@", server, user); NSString* objid = CreatePerson(db); ShowPerson(db, objid); DeletePerson(db, objid); @catch (NSException* localexception) NSLog(@"SimpleExample failed: %@", localexception); [pool release]; return 0; 2.2.2 Compiling and Building The simple example SimpleExample.m can be compiled from a shell script or makefile with a command similar to the following: gcc -framework AppKit -framework ObjectiveCache -L/Library/Frameworks/ObjectiveCache.framework/Libraries -o./simpleexample SimpleExample.m where the -F and -L options specify that the ObjectiveCache framework was installed in /tmp/frameworks. -fnext-runtime and -fobjc-exceptions are default values and can be omitted. -L for libraries seems to be mandatory. 2.2.3 Compiling SimpleExample with Xcode In order to compile and run this example using Xcode you may need to do the following: In Xcode Project Settings, adjust Other Linker Flags to be: 8 Using the Caché Objective-C Binding

Simple Example of Accessing a Sample Class -framework ObjectiveCache -framework AppKit -L/Library/Frameworks/ObjectiveCache.framework/Libraries In the Project window select Executables > (your executable name) select Menu File > Get Info select the Arguments tab add the following variable to the environment: DYLD_LIBRARY_PATH=/Library/Frameworks/ObjectiveCache.framework/Libraries 2.2.4 Setting up DYLD_LIBRARY_PATH If the framework is not installed in a standard location (such as /Library/Frameworks, ~/Library/Frameworks), then DYLD_LIBRARY_PATH needs to be set so that Mac OS X can find the ODBC and C++ libraries at runtime: export DYLD_LIBRARY_PATH=$LOCATION_OF_OBJECTIVECACHE_FRAMEWORK/Libraries where the variable LOCATION_OF_OBJECTIVECACHE_FRAMEWORK is set to the location of the ObjectiveCache framework directory. In Xcode, set DYLD_LIBRARY_PATH in the executable's properties page as follows: Go to Xcode > Groups & File > Executables double click the executable or "get info" select the Arguments tab Add the following variables in the environment: Name Value DYLD_LIBRARY_PATH LOCATION_OF_OBJECTIVECACHE_FRAMEWORK/Libraries Using the Caché Objective-C Binding 9

3 Reference This section provides a reference for the behavior of the Caché Objective-C binding. 3.1 Release/Retain Rules As with the standard Objective-C language rules for release/retain, the Objective-C binding always returns autoreleased objects, with the exception of any cases where you explicitly call alloc (for example, when constructing the ISCDatabase and ISCConnection objects). In these cases, you are responsible for explicitly releasing them or autoreleasing them. 3.1.1 Autorelease Pool As with any Objective-C application, you need to have an autorelease pool set up. For Cocoa applications, the main run loop sets one up for the main thread. For any additional threads you create, you need to explicitly create a pool, as follows: NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; And when you are done: [pool release] If you are working in a loop, or under any other condition that can cause a large number of objects to be created, you should ensure that the memory is not released until you release the pool. For example, you may wish to use a nested autorelease pool inside a loop to prevent a buildup of unreleased memory. 3.2 Objects Any registered Caché object can be accessed via the Caché Objective-C binding. Broadly speaking, there are three main types of objects: Registered: An object that can be created and has an _instance_. Persistent: An object opened from the database (also registered). Serial: A persistent object that has no identity of its own; it is always embedded in another (usually persistent) object. In general, objects are brought into being in one of three ways: Using the Caché Objective-C Binding 11

Reference Creating Opening Swizzling Swizzled objects are brought into scope by referencing a property in another object or by calling a method and getting back an object from it. 3.2.1 Creating a New Object A new instance of an object, be it registered or persistent, can be created as follows, which essentially invokes the class method =%New()= on the specified class and returns the reference: id obj = [db create:@"sample.person"]; The object properties are set to their initial expressions; you may now set properties, get properties, call methods. The returned object is autoreleased, which means that it goes out of scope when the current autorelease pool is released. At this point, if the object has not been saved (in the case of a persistent object), then the changes will be lost. Some classes allow a parameter to be passed to the =%OnNew()= method via the call to %New, you can use -create:argument to invoke this: id obj = [db create:@"sample.person" argument:@"an argument"]; The actual argument depends on the class that you are creating. 3.2.1.1 Persistent Objects A persistent object can be opened from the database, using a database id as follows: id obj = [db openid:@"sample.person" ident:@"101"]; This particular example would open the instance of Sample.Person with the ID 101. As with registered objects, any changes that you make are lost once the object is autoreleased, unless you save them, as follows: [obj _Save:1] This invokes %Save with a parameter of 1, which indicates a deep save. A shallow save (meaning just save the immediate object instance of obj) would be invoked by passing 0 (zero) to -_Save. 3.3 Properties Properties can be set and fetched via the Caché Objective-C binding, using the following patterns: NSString* name = [obj Name]; And to set a property: [obj Name:@"Jobs,Steve"]; Once a persistent object has been modified, it must be saved via a call to -_Save: or the changes are lost. If you attempt to set a calculated (read-only) property, an NSException is raised with the appropriate error from the Caché server. 12 Using the Caché Objective-C Binding

Methods 3.3.1 Key/Value Coding The Caché Objective-C binding also supports Key/Value Coding (KVC), which is heavily utilized by the Cocoa Bindings. This means that you can bind UI controls directly to instances of Caché objects. This is a very powerful feature that can save many thousands of lines of coding. 3.3.2 Key/Value Observing In addition to Key/Value Coding, the Caché Objective-C binding also supports Key/Value Observing, which allows you to register observers for changes made to Caché objects that are currently _open_. Again, coupled with Cocoa bindings, this allows for powerful and flexible UIs to be easily built. 3.4 Methods The Caché Objective-C binding allows for both instance and class method to be invoked from the Objective-C application to the Caché server. 3.4.1 Instance Methods Once you have an open object, you can invoke an instance method as if it were an Objective-C method. For multiple parameters, the additional parameters are unnamed. You just need supply the : (colon) placeholder. For example: int answer = [obj Addition:1 :2]; 3.4.2 Class Methods Since class methods do not require an instance of a class to be invoked, but in the Caché Objective-C binding we need a context in which to invoke a class method, we introduce the notion of a _class proxy_. A class proxy is essentially the same as the normal object proxies, except that there are no properties or instance methods. Only class methods and class queries can be called. id proxy = [db openclass:@"sample.person"]; [proxy PrintPerson]; You can also use a regular instance object to invoke a class method. 3.5 Queries 3.5.1 Class Queries There are two means by which class queries can be invoked. Either directly against the ISCDatabase object or via a class proxy object (see previous section on calling Class Methods). Using a Class Proxy A class query can be easily called against a class proxy or, indeed, an open object instance: Using the Caché Objective-C Binding 13

Reference id proxy = [db openclass:@"sample.person"]; id query = [proxy ByName:@"Jobs"]; int row = 0; [query execute]; while ([query fetch]) NSLog(@"Row %d: %@", ++row, [query stringvalueatindex:1]); Against the ISCDatabase Object It is also possible to invoke a class query directly against the ISCDatabase instance, although you need to individually bind each parameter: id query = [db prepare:@"sample.person" procedure:@"byname"]; int row = 0; [query setstring:@"jobs"]; [query execute]; while ([query fetch]) NSLog(@"Row %d: %@", ++row, [query stringvalueatindex:1]); Once you have acquired the query object, the traversal mechanism is exactly the same. 3.5.2 Dynamic SQL A Dynamic SQL query can be invoked against the ISCDatabase object using the -prepare: method; any parameters can then be bound before invoking the query: id query = [db prepare:@"select * FROM SAMPLE.PERSON WHERE NAME %STARTSWITH?"]; int row = 0; [query setstring:@"jobs"]; [query execute]; while ([query fetch]) NSLog(@"Row %d: %@", ++row, [query stringvalueatindex:1]); 3.6 Transactions The Caché Objective-C binding gives you complete control over transactions via a set of four functions defined in ISC- Database: -(void)transactionstart; -(void)transactioncommit; -(void)transactionrollback; -(int)transactionlevel; You can use these functions to wrap up any database operations (object operations or direct SQL) in transactions that can be committed or rolled back as desired. Transactions can also be nested. 14 Using the Caché Objective-C Binding

4 Error Checking and Debugging 4.1 Debugging The Caché Objective-C binding provides a mechanism for better understanding what is going on under the hood when things go wrong. A flag, ISCDebugLevel can be used to specify different levels of debug logging to the console (via NSLog). ISCDebugLevel can either be set by setting the environment variable ISCDebugLevel, or by setting the global int variable ISCDebugLevel (defined in ObjectiveCache.h) to an integer between 0 and 5. The higher the level, the more verbose the debug information. The levels are defined as: ISC_DEBUG_ALWAYS ISC_DEBUG_WARNING ISC_DEBUG_INFO ISC_DEBUG_FINE ISC_DEBUG_FINER ISC_DEBUG_FINEST 0 1 2 3 4 5 Log always Log warnings only Log information Log fine level debug information Log fine level debug information Log fine level debug information In general, setting ISCDebugLevel to 0 (zero) will shut off all logging (except for anything at ISC_DEBUG_ALWAYS). Although setting the environment variable ISCDebugLevel only takes effect before the process is started, you can modify the global variable ISCDebugLevel on the fly and it will have immediately effect. 4.2 Objective-C Header Generator While the Caché Objective-C binding is completely dynamic, it is often desirable to be able to generate Objective-C headers from Caché classes. This can be done either via a command line tool shipped as part of the framework, or programmatically by calling a method on ISCDatabase. 4.2.1 Command Line Tool The framework has a command line header generator tool that can be used to generate Objective-C.h files from Caché classes on the server. It is tucked it into the framework directory: Using the Caché Objective-C Binding 15

Error Checking and Debugging./ObjectiveCache.framework/Commands/objc_generator It can be invoked as follows: objc_generator [<option>...] <classes...> Where <classes> is a list of classes separated by spaces. The options are as follows: -d Generate dependent classes -f Force generation of the header files -o dir Generate headers into the specified directory -s Connect to the specified Cache' server (e.g. 127.0.0.1[1972]:SAMPLES) -u User to connect as -p Password By default, unless the -f option is given, the generator will only update the target.h file if it has really changed (thus preventing unnecessary source control updates). Also, no unnecessary date/time/version information is generated in the header. 4.2.2 Generating Headers Programmatically There may be cases where it is desirable to be able to generate headers from an Objective-C program, for example perhaps an Xcode plugin. The framework exposes a method to do this, implemented in the ISCDatabase class: - (NSDictionary*)Database generateheaders:(nsarray*)classes dependents:(bool)yn When called, this returns an NSDictionary of strings keyed by class names, where the class names correspond to the list of classes headers were requested for using the NSArray "classes" parameter. If dependents is specified as YES, then it will also generate headers for dependent classes. The strings stored in the NSDictionary are the actual header files, suitable for writing out to disk. 4.3 Getting a Stack Trace from an NSException Whenever your application gets an NSException, there is a way by which you can extract a stack trace from it for diagnostics/debugging purposes. There are a couple of steps required: 4.3.1 Include the ExceptionHandling Framework You will need to add a #import in your Objective-C sources: #import <ExceptionHandling/NSExceptionHandler.h> For a console application, you will need to add: -framework ExceptionHandling For a Cocoa application, you will need to add the ExceptionHandling framework (found in /Library/Frameworks) to your Xcode project. 4.3.2 Enable Stack Traces Adding the following line of code to your =main()=, ideally this will be the first line of code executed, will ensure that stack traces get logged for all NSExceptions that are raised. 16 Using the Caché Objective-C Binding

Getting a Stack Trace from an NSException [[NSExceptionHandler defaultexceptionhandler] setexceptionhandlingmask:nslogandhandleeveryexceptionmask]; 4.3.3 Decoding the Stack Trace Once stack traces have been enabled, they are accessible via the userinfo part of the NSException object. NSString* stk = [[exception userinfo] objectforkey:nsstacktracekey]; You can utilize the command line tool =atos(1)= to convert the hex exception values into a meaningful stacktrace as follows: /*! * Print a stack trace for the given exception. The stack trace is displayed * on stdout. */ void PrintStackTrace(NSException* exception) NSString* stk = [[exception userinfo] objectforkey:nsstacktracekey]; NSTask* ls = [[NSTask alloc] init]; NSString* pid = [[NSNumber numberwithint:getpid()] stringvalue]; NSMutableArray* args = [NSMutableArray arraywithcapacity:20]; [args addobject:@"-p"]; [args addobject:pid]; [args addobjectsfromarray:[stk componentsseparatedbystring:@" "]]; // NOTE: function addresses are separated by double spaces, not a single // space. [ls setlaunchpath:@"/usr/bin/atos"]; [ls setarguments:args]; [ls launch]; [ls waituntilexit]; [ls release]; 4.3.4 Do Not Use @throw in Your Application Although the @throw keyword is part of the new exception handling logic in Objective-C, exceptions thrown with it do not have a stack trace. If your application needs to throw its own exceptions, you should use -[NSException raise] instead: NSException* exception = [NSException exceptionwithname:@"nsgenericexception" reason:@"this is an exception!" userinfo:nil]; [exception raise]; Using the Caché Objective-C Binding 17