iOS integration

2. How to use

2.1 Initialization

Before using any INSITEO class, you have to initialize ISInitProvider singleton: we will give you information to interact with our servers. A SITE_ID and an APPLICATION_VERSION will be generated in order to identify your application, a SERVER_URL will be created to communicate with our server. Using this information, you will be able to initialize the API.

Note : The ISInitProvider also requires a ISEServerType parameter. This can take the following values DEV_SERVER, TEST_SERVER and PROD_SERVER and is used to store the packages at the appropriate location on the device. Please make sure to use the proper value according to the URL server that was provided.

NEW Note : You have now to set an API key that you can found in your INSITEO account.

To initialize API, you must call startAPIWithServerUrl , with an id<ISPInitListener> passed as parameter. The onInitDone method will be called back on your listener when initialization is finished.

Note : You can also now use analytics with the analyticsAutoStart boolean parameter.

To initialize the API, you must use ISInitProvider as below:

//Set your API key
[ISInitProvider setAPIKey:@"MY-API-KEY"];

//And start the API
id<ISPCancelable> initTask = [[ISInitProvider instance] startAPIWithServerUrl:SERVER_URL andSiteId:SITE_ID andApplicationVersion:APPLICATION_VERSION andLanguage:LANGUAGE andForceDownload:NO andInitListener:aListener andServerType:PROD_SERVER andAnalyticsAutoStart:YES];
 
//The initTask object could be used to cancel the API initialization (see ISPCancelable protocol documentation).
 
(...)
 
//In your init listener:
- (void)onInitDone:(ISEInitAPIResult)result andError:(ISInsiteoError *)error {
    switch(result){
    case SUCCESS :
      //Init is ok
      break;
    case SUCCESS_NEW_DATA :
      //Init is ok and new packages are available
            break;
    case FAIL :
      //Init failed.
      //More information in error (see ISInsiteoError documentation)
            break;
    default:
            break;
    }
}

Note : startAPIWithServerUrl method is asynchronous. Be sure to provide a valid id<ISPInitListener>, to be notified of init ending.

If startAPIWithServerUrl returns:

  • SUCCESS, you can use INSITEO APIs straight away.
  • SUCCESS_NEW_DATA, it means that new data packages are available on INSITEO servers. You can then call the updatePackagesWithInitListener method on the ISInitProvider singleton in order to download and install new data (update is asynchronous, thus its result will be send to the listener, through the onDataUpdateDone callback).
  • FAIL, it means that INSITEO servers could not be reached. If you want to use an INSITEO module, you have to check if your application has enough data to run. This can be done using hasPackageWithPackageType on ISInitProvider singleton.

To update application data, use ISInitProvider as below:

//Notifications will be sent through following callbacks
id<ISPCancelable> initTask = [[ISInitProvider instance] updatePackagesWithInitListener:aListener];
 
//The initTask object could be used to cancel the API update (see ISPCancelable protocol documentation)
 
(...)
 
//Notifications will be sent to the listener through following callbacks:
- (void)onDownloadProgressWithProgress:(int)progress andTotal:(int)total {
    (...)
}
- (void)onInstallProgressWithProgress:(int)progress andTotal:(int)total {
    (...)
}
- (void)onDownloadPackageWillStart:(ISPackageType)packageType {
    (...)
}
- (void)onDataUpdateDone:(Boolean)success andError:(ISInsiteoError *)error {
    (...)
}

Note: updatePackagesWithInitListener method is asynchronous. Be sure to provide a valid id<ISPInitListener>, to be notified of initialization events.

When updating packages, the id<ISPInitListener> will receive notifications for packages download progress, and then for packages install progress (on UI thread). Once the update is finished, the id<ISPInitListener> will receive an onDataUpdateDone event.

When calling updatePackagesWithInitListener, an id<ISPCancelable> is returned. Call cancel on this object to cancel the current update.

3. Insiteo Map

3.1 Adding graphical objects on map

An ISMapView is provided and can be used to display a specific 2D map with specific interactive areas. The framework also provides advanced features such as additional rendering layouts management (promotional, special areas etc…) or specific events handling. Beware that you need to have installed at least the following packages:

  • A MAP_DATA package, which contains maps information such as zoom levels and scales.
  • And a TILES_PACKAGE package, which contains .3cm files that will be displayed.

By default, the ISMapView will display a tiled map of the site, and provide basic functions on this map (such as move, center, and pinch to zoom). But it also allows you to display custom interactive objects on this map. This will be done using custom renderers and custom render touch objects using the id<ISPRTO> protocol.

The ISMapView will first draw the tiled map, and then will loop on all its renderers, calling invalidateWithLayer on each one. Each renderer owns a list of id<ISPRTO>. In its invalidateWithLayer method, the renderer will loop on this list, and call invalidateWithLayer on each id<ISPRTO>.

The ISMapView will also detect touches, and dispatch them to all id<ISPRTO>. A listener can be set on the map controller, to be notified of clicks on specific id<ISPRTO> class (see ISMapViewController) class documentation.

In order to use our MapAPI, you will need to instantiate our ISMapViewController:

//ISMapViewController initialization
ISMapViewController * mapViewController = [[ISMapViewController alloc] initWithMapListener:aListener andContentView:aContentView];

Note: You will need to initialize ISInitProvider before instantiating ISMapViewController.

Note 2: You will need to provide an id<ISPMapListener> to be notified of ISMapViewController events.

Note 3: You could also specify a content UIView in order to add the ISMapView on this view.

3.2 Create your own ISPRenderer

A renderer is a class that defines drawing behavior for a certain type of id<ISPRTO>. If you want to use your own customized renderer, you will need to create a class that implements the ISPRenderer protocol. Then you will be able to specify the renderer behavior through the invalidateWithLayer method for example. You will also have to set a priority to your renderer that will define the order in which they will be drawn (Renderer with highest priority will appear on top of the map).

To register a new renderer as a map's renderer, simply do like this:

//How to add a custom renderer
[mapViewController addRenderer:aRenderer]];

Note: All id<ISPRTO> of class corresponding to the custom renderer class, when added via ISMapViewController, will be put in custom renderer. See "Use your own ISPRTO" chapter below.

You will also need to implement an exhaustive list of functions described in the protocol. See the complete documentation for more details.

3.3 Create your own ISPRTO

To draw a customized rendering object on the map, you will need to create a class that implements the id<ISPRTO> protocol. Then you will be able to specify your object’s behavior through methods like:

//The method you will need to override in order to manually manage your object rendering
- (void)invalidateWithLayer:(ISLayer *)layer andRatio:(double)ratio andOffset:(CGPoint)offset andAngle:(float)angle andPriority:(int)priority andTilt:(Boolean)tilt;

NEW Note: The tilt parameter can now be used.

You could also define touch behavior through callbacks like:

//The method you will need to override in order to manually manage touch down events
- (ISETouchObjectResult)onTouchDown:(ISTouch *)touch;

You will also need to implement an exhaustive list of functions described in the protocol. Then you will be able to add an instance of this class in ISMapViewController, using the following methods:

//Methods you will need to call in order to add an RTO on the map
- (Boolean)addRTO:(id<ISPRTO>)rto;
- (Boolean)addRTO:(id<ISPRTO>)rto inZone:(int)zoneId;

The mapping for interactive areas is provided by INSITEO. When a zone is clicked on the screen, you will receive a notification via id<ISPMapListener> following callback:

//The method you will need to override handle touch events on interactive zones
- (void)onZoneClickedWithZone:(int)idZone andActionType:(int)actionType andActionParameter:(NSString *)actionParameter;

You can then add your id<ISPRTO> that will be displayed in this area.

3.4 Best pratices

//Cocos2d recommands to call these methods according to application state changes
- (void)applicationDidEnterBackground:(UIApplication *)application {
    [[CCDirector sharedDirector] stopAnimation];
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
    [[CCDirector sharedDirector] startAnimation];
}

- (void)applicationWillResignActive:(UIApplication *)application {
    [[CCDirector sharedDirector] pause];
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
    [[CCDirector sharedDirector] resume];
}

//We also recommend you to start and stop the map rendering according to the parent UIViewController state changes
- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [mapViewController startRendering];
}

- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    [mapViewController stopRendering];
}

3.5 Zone/POI associations

To get all related Insiteo zones for a given POI or to get all POIs related to a given Insiteo zone, you can use the ISDBHelperMap class.
    //Get all Zone/POI assocations for a given external identifier
    NSArray * zonesPois = [ISDBHelperMap getExternalZonePoisForExtIdPoi:externalPoiId];

    //Get all Zone/POI assocations for a given internal identifier
    NSArray * zonesPois = [ISDBHelperMap getZonePoisForIdPoi:poiId];

    //Get all external Zone/POI assocations for a given zone identifier
    NSArray * zonesPois = [ISDBHelperMap getZonePoisForIdZone:zoneId andExternal:YES];

    //Get all internal Zone/POI assocations for a given zone identifier
    NSArray * zonesPois = [ISDBHelperMap getZonePoisForIdZone:zoneId andExternal:NO];

NEW Note: The ISZonePoi has now its own external POI identifier field (see. ISZonePoi in the documentation).

4 Insiteo Location

4.1 Get your first location

You can use our LocationAPI to obtain location information. The LocationAPI needs initialization information in order to communicate with our servers. You can easily link this library to the INSITEO map, so the location can be displayed on it.

In order to use our LocationAPI, you will need to create an ISLocationProvider instance (or ISGfxLocationProvider instance if you want the location to be displayed automatically on the map). To receive location, you will need to start the ISLocationProvider, with a context and an id<ISPLocationListener>. This listener will receive location events. You also have to set flags indicating location behavior, and a default map identifier:

//Instanciate the location provider
ISGfxLocationProvider * locProvider = [[ISGfxLocationProvider alloc] init];
//And start it
[locProvider startLocation:(COMPASS|BLE|MEMS) andLocationListener:aListener];
       
//Add location renderer in controller, thus location is displayed on map
[mapViewController addRenderer:[locProvider renderer]];

Important: Please contact us to get the appropriate location settings.

Note: The API needs to be initialized.

NEW Note: You can now be notified when no registered beacons were detected, which probably means that the user started the location whereas he is not on site.

To use location-based services, such as Itinerary, GeoFencing or MeetMe you have to get the module from the location provider. If you want it to be displayed on an INSITEO map, do as below:

//Get the itinerary provider
ISGfxItineraryProvider * itineraryProvider = (ISGfxItineraryProvider *)[locProvider getLbsModule:LBS_MODULE_ITINERARY];
       
//Add renderer so itinerary is displayed on map
[mapViewController addRenderer:[itineraryProvider renderer]]; 
     
//Request an itinerary: response will be send to listener
[itineraryProvider requestItineraryWithStartPoint:CGPointMake(50, 50) andStartMapId:205 andEndPoint:CGPointMake(200, 100) andEndMapId:206 andListener:self andPMR:NO];

4.2 Itinerary recomputation

//Method called on the main thread
- (void)mainRecomputeItinerary {
    //Request an itinerary from the user current location
    [itineraryProvider requestItineraryFromCurrentLocationWithEndPoint:CGPointMake(200, 100) andEndMapId:2 andListener:itineraryListener andPMR:NO];
}

//Method called when the user position changed
- (void)onItineraryChangedWithRequest:(ISItineraryBaseRequest *)request andDistanceToItinerary:(float)distanceToItinerary {
    //You can check if the distance between the user location and the computed itineray needs a recomputation
    if (distanceToItinerary > MAX_RECOMPUTATION_DISTANCE) {
        //The recomputation needs to be done on the main thread
        [self performSelectorOnMainThread:@selector(mainRecomputeItinerary) withObject:nil waitUntilDone:NO];
    }
}

4.3 Available services

Available location-based services are:

  • LBS_MODULE_ITINERARY: this module computes the route between an arrival point, and a departure point (could be the user current location).
  • LBS_MODULE_MEETME: this module allow user to share its position with other users, and to get their location, in real time.
  • LBS_MODULE_GEOFENCING: this module detects when user location is in "active" areas, and notify the application that the user entered/stayed in/left these areas.

To use them, you have to request them from ISLocationProvider.