Search form

Documentation

About API Guide - iOS

Reference code

The reference code consists of service and client implementations of the About feature.

Classes used to send AboutData

Service class Description
AboutService Class the implements the org.alljoyn.About interface.
AboutIconService Class that implements the org.alljoyn.Icon interface.
PropertyStore Interface that supplies the list of properties required for Announce signal payload and GetAboutData().

Classes used to receive AboutData

Client class Description
AboutClient Helper class for discovering About Service that provides access to the Announcements and to the AboutService. It listens for Announcements sent using the org.alljoyn.About interface.
AboutIconClient Helper class that provides access to the AboutIconService.

Obtain the About feature

See the Building iOS/OS X section for instructions on compiling the About feature.

Build an application that uses About Service

The following steps provide the high-level process to build an application that will broadcast AboutData.

  1. Create the base for the AllJoyn™ application.
  2. Implement PropertyStore to produce an AboutData. (See Create a PropertyStore Implementation.)
  3. Instantiate a PropertyStore.
  4. Create and register the AboutService, providing it with the PropertyStore.
  5. Announce the AboutService.

Build an application that uses About Client

The following steps provide the high-level process to build an application that will receive AboutData.

  1. Create the base for the AllJoyn application.
  2. Create and register an AnnouncementReceiver providing it with the AnnounceListener.
  3. Create and use the AboutClient.

Setting Up the AllJoyn Framework

Every AllJoyn application requires a base set to be in place before implementing specific features that include creating a BusAttachment and connecting to the AllJoyn framework.

Create instance of BusAttachment

self.clientBusAttachment = ;
   if (status != ER_OK) {
      return status;
   }

   //    HardwareVersion
   status = [self.aboutPropertyStoreImpl setHardwareVersion:@"355.499. b"];
   if (status != ER_OK) {
      return status;
   }

   //    Description
   status = [self.aboutPropertyStoreImpl setDescription:@"This is an AllJoyn Application" 
      language:@"en"];
   if (status != ER_OK) {
      return status;
   }
   status = [self.aboutPropertyStoreImpl setDescription:@"Esta es una AllJoyn

   aplicación" language:@"sp"];
   if (status != ER_OK) {
      return status;
   }
   status = [self.aboutPropertyStoreImpl setDescription:@"C'est une AllJoyn application" 
      language:@"fr"];
   if (status != ER_OK) {
      return status;
   }

   //    Manufacturer
   status = [self.aboutPropertyStoreImpl setManufacturer:@"Company" language:@"en"];
   if (status != ER_OK) {
      return status;
   }
   status = [self.aboutPropertyStoreImpl setManufacturer:@"Empresa" language:@"sp"];
   if (status != ER_OK) {
      return status;
   }
   status = [self.aboutPropertyStoreImpl setManufacturer:@"Entreprise" language:@"fr"];
   if (status != ER_OK) {
      return status;
   }

   //    SupportedUrl
   status = [self.aboutPropertyStoreImpl setSupportUrl:@"http://www.allseenalliance.org"];
   if (status != ER_OK) {
      return status;
   }
      return status;
   }

Provision PropertyStore with default values

In the application, the PropertyStore instance you created will be loaded with the default values. In the sample implementation above, the PropertyStore instance is provided with a default values map.

The following subsections highlight provisioning fields according to their data type.

AppId field

The AppId field is an array of bytes. It is a globally unique identifier (GUID) encoded as an array of 16 bytes.

self.uniqueID = [[NSUUID UUID] UUIDString]; 

[self.aboutPropertyStoreImpl setAppId:self.uniqueID];

SupportedLanguages field

The SupportedLanguages field is a list of text strings. Some fields can have a language-dependent value that must be provided for each of the supported languages.

NSArray *languages = @[@"en", @"sp", @"fr"]; 

[self.aboutPropertyStoreImpl setSupportedLangs:languages];

Non-language-specific fields

Non-language-specific fields support a single supplied text string. Following is an example for the ModelNumber field on how to insert into the PropertyStore. The code below can be used with the field name being replaced by other field names listed in About data interface fields.

[self.aboutPropertyStoreImpl setModelNumber:@"Wxfy388i"];

Language-dependent fields

Language-dependent fields support a single supplied text string. Below is an example for the Description field on how to insert into the PropertyStore. The code below can be used with the field name being replaced by other field names listed in About data interface fields.

[self.aboutPropertyStoreImpl setDescription:@"This is an AllJoyn application" language:@"en"];

[self.aboutPropertyStoreImpl setDescription:@"Esta es una AllJoyn aplicacion" language:@"sp"];

[self.aboutPropertyStoreImpl setDescription:@"C'est une AllJoyn application" language:@"fr"];

Create the AboutService object

For an application to send AboutData, it requires an instance of the AboutService class. AboutServiceImpl is an implementation wrapper around AllJoyn native calls that handle the interactions between About Service and About Client.

AboutService aboutService = AboutServiceImpl.getInstance();

Start Service mode

Register the relevant BusObjects and add the relevant interfaces to the Announcement's ObjectDescription.

[self.aboutServiceApi startWithBus:self.serviceBusAttachment 
   andPropertyStore:self.aboutPropertyStoreImpl];

Add an AboutIconService (optional)

An application that sends AboutData can be extended to broadcast a device. AboutServiceImpl is also an implementation wrapper around AllJoyn native calls that handle the interactions between applications that use the AboutIconClient class.

Provision for the Icon content and URL

An Icon is published directly as a byte array or a reference URL, and must be provisioned as follows:

uint8_t aboutIconContent[] = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44,
   0x52, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0A, 0x08, 0x02, 0x00, 0x00,

0x00, 0x02, 0x50, 0x58, 0xEA, 0x00,
   0x00, 0x00, 0x04, 0x67, 0x41, 0x4D, 0x41, 0x00, 0x00, 0xAF, 0xC8, 0x37, 0x05,

0x8A, 0xE9, 0x00, 0x00, 0x00, 0x19,
   0x74, 0x45, 0x58, 0x74, 0x53, 0x6F, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x00,

0x41, 0x64, 0x6F, 0x62, 0x65, 0x20,
   0x49, 0x6D, 0x61, 0x67, 0x65, 0x52, 0x65, 0x61, 0x64, 0x79, 0x71, 0xC9, 0x65,

0x3C, 0x00, 0x00, 0x00, 0x18, 0x49,
   0x44, 0x41, 0x54, 0x78, 0xDA, 0x62, 0xFC, 0x3F, 0x95, 0x9F, 0x01, 0x37, 0x60,

0x62, 0xC0, 0x0B, 0x46, 0xAA, 0x34,
   0x40, 0x80, 0x01, 0x00, 0x06, 0x7C, 0x01, 0xB7, 0xED, 0x4B, 0x53, 0x2C, 0x00,

0x00, 0x00, 0x00, 0x49, 0x45, 0x4E,
   0x44, 0xAE, 0x42, 0x60, 0x82 };

};

NSString *mimeType = @"image/png"; /* This should correspond 
   to the content */ NSString *url = @"http://tinyurl.com/llrqvrb"; 
   /* An alternate access to the Icon
*/

Create and register DeviceIcon object

Register the relevant BusObjects and add the relevant interfaces to the Announcement's ObjectDescription.

self.aboutIconService = [[AJNAboutIconService alloc] initWithBus:self.serviceBusAttachment 
   mimeType:mimeType url:url content:aboutIconContent csize:csize];

[self.aboutIconService registerAboutIconService];
[self.serviceBusAttachment advertiseName:([self.serviceBusAttachment uniqueName])
withTransportMask:(kAJNTransportMaskAny)];

Send the Announcement

[self.aboutServiceApi announce];

Unregister and delete AboutService and BusAttachment

When your process is done with the AboutService and no longer wishes to send announcements, unregister the process from the AllJoyn bus and then delete variables used.

// Stop AboutIcon
[self.serviceBusAttachment unregisterBusObject:self.aboutIconService];
self.aboutIconService = nil;

// Delete AboutServiceApi [self.aboutServiceApi destroyInstance]; 
   self.aboutServiceApi = nil;

// Delete AboutPropertyStoreImpl self.aboutPropertyStoreImpl = nil;

// Bus attachment cleanup
[self.serviceBusAttachment cancelAdvertisedName:[self.serviceBusAttachment 
   uniqueName] withTransportMask:kAJNTransportMaskAny];

[self.serviceBusAttachment unbindSessionFromPort:SERVICE_PORT];

// Delete AboutSessionPortListener
[self.serviceBusAttachment unregisterBusListener:self.aboutSessionPortListener];
self.aboutSessionPortListener = nil;

// Stop bus attachment
[self.serviceBusAttachment stop];
self.serviceBusAttachment = nil;

Implementing an Application that Uses AboutClient

To implement an application to receive AboutData, use the AboutClient class. By using the AboutClient class, your application is notified when About Service instances send announcements.

Verify the BusAttachment has been created, started and connected before implementing an About Client. See Setting Up the AllJoyn Framework for the code snippets. Code in this chapter references a variable self.clientBusAttachment (the BusAttachment variable name).

Setup to receive the Announce signal

In order to receive the Announce signal from an application using AboutService, a class implementation of AJNAnnouncementListener protocol must be created.

Create class to implement AJNAnnouncementListener protocol

This declaration of a class will allow for the signals to be received. It must implement the pure virtual function Announce.

@interface sampleClass <AJNAnnouncementListener>

- (void)announceWithVersion:(uint16_t)version 
                       port:(uint16_t)port
                    busName:(NSString *)busName 
         objectDescriptions:(NSMutableDictionary *)objectDescs
                  aboutData:(NSMutableDictionary **)aboutData {
// add your implementation here
}

Implement the Announce method that handles the Announce signal

With everything linked up using the AllJoyn framework, the method registered with the AllJoyn framework will be executed upon receipt of an Announce signal.

Because every application is different, as a developer you must process the AboutData and determine the following:

  • How it should be rendered in the UI.
  • When to request the data that is not contained in the Announce signal.
  • Any logic that is needed.

Register the AJNAnnouncementListener

When registering an announcement listener, specify which interfaces the application is interested in. The code below shows a listener registered to receive Announce signals that include an object implementing the INTERFACE_NAME interface.

self.announcementReceiver = [[AJNAnnouncementReceiver alloc]
initWithAnnouncementListener:self andBus:self.clientBusAttachment];

const char* interfaces[] = { [INTERFACE_NAME UTF8String] }; 

[self.announcementReceiver registerAnnouncementReceiverForInterfaces:interfaces
   withNumberOfInterfaces:1];

Using ping to determine presence

The AJNBusAttachment pingPeer member function can be used to determine if a device is responsive. Contents of an Announce signal can be stale so it may be useful to ping the device to see if it is still present and responsive before attempting to form a connection.

NOTE: The AJNBusAttachment pingPeer method makes a bus call. If pingPeer is called inside an AllJoyn callback, AJNBusAttachment enableConcurrentCallbacks must be called first.

// When pinging a remote bus name wait a max of 5 seconds
[self.clientBusAttachment enableConcurrentCallbacks];
QStatus status = [self.clientBusAttachment pingPeer:busName 
  withTimeout:5000];
if (ER_OK == status) {
   ...
}

Request non-announced data

If there is a need to request information that is not contained in the announcement (meaning they are not marked as announcable), complete the tasks in the following subsections.

Join a session

Create a session with the application by using the BusAttachment JoinSession API.

NOTE: The variables name and port are set from the AboutData from the Announce method.

AJNSessionOptions *opt = [[AJNSessionOptions alloc] 
initWithTrafficType:kAJNTrafficMessages supportsMultipoint:false 
proximity:kAJNProximityAny transportMask:kAJNTransportMaskAny];


self.sessionId = [self.clientBusAttachment 
      joinSessionWithName:[self.clientInformation.announcement busName]
            onPort:[self.clientInformation.announcement port]
            withDelegate:(nil) options:opt];

Create AboutClient

Generate an AJNAboutClient and create an instance passing in the BusAttachment that was created in Start and connect the BusAttachment.

AJNAboutClient *ajnAboutClient = [[AJNAboutClient alloc]
initWithBus:self.clientBusAttachment];

Create AJNAboutIconClient

Generate an AJNAboutIconClient and create an instance passing in the BusAttachment created in Start and connect the BusAttachment.

self.ajnAboutIconClient = [[AJNAboutIconClient alloc]
initWithBus:self.clientBusAttachment];

[self.ajnAboutIconClient urlFromBusName:announcementBusName url:&url 
sessionId:self.sessionID];

Shutdown

Once you are done using the About feature and the AllJoyn framework, free the variables used in the application.

self.clientBusAttachment = nil;
For future news and updates, please follow or visit https://t.co/MKr1Z9NPji
11 months 3 weeks ago