Lightstreamer macOS Client  1.2.5
Native macOS Client library for Lightstreamer
Getting started with the iOS, tvOS and macOS Client libraries

The iOS, tvOS and macOS Client Libraries have been developed using the Java SE library as a starting point.Obtaining a connection and subscribing to a table is a simple and straightforward procedure:

Creating an instance of LSClient

To create an instance of LSClient simply alloc- and init-it, or use the factory method:

LSClient *client= [[LSClient alloc] init];

Or:

LSClient *client= [LSClient client];

Open the connection

To open the connection you must first define the connection specifications using an LSConnectionInfo object, for example:

LSConnectionInfo *connectionInfo= [LSConnectionInfo connectionInfoWithPushServerURL:@"http://push.lightstreamer.com" pushServerControlURL:nil user:nil password:nil adapter:@"DEMO"];

Done this, use the LSConnectionInfo object with the LSClient:

[client openConnectionWithInfo:connectionInfo delegate:self];

Please note that this call is blocking: it will not return until a connection has been established. Since this may take long, you may want to run it from a background thread, to avoid freezing the UI.

Exceptions vs NSError

Client library APIs are designed to throw (raise) exceptions in case of both programming and runtime errors. Anyway, an alternative pattern is also provided that better fits Cocoa and Cocoa Touch.
For every method that may throw an exception in presence of a runtime error, a corresponding non-exception-throwing version is provided. This alternative method has always the same name, semantics, return value and parameters, except for an additional NSError output parameter that may be used (if not nil) to store a runtime error. For example:

@try {
  [client openConnectionWithInfo:connectionInfo delegate:self];
} @catch (NSException *e) {
  // Exception handling
}


May be replaced by:

NSError *error= nil;
[client openConnectionWithInfo:connectionInfo delegate:self error:&error];
if (error) {
  // Error handling
}


Note that exceptions due to programming errors (such as use of invalid field names, wrong API call sequence, etc.) may still be thrown.

Listening for connection events

Your designated delegate will then receive an event when the session actually starts:

- (void) clientConnection:(LSClient *)client didStartSessionWithPolling:(BOOL)polling {
    ...
}


Once this happens, you can start define an LSTableInfo object that describes the table you want to subscribe:

LSTableInfo *tableInfo= [LSTableInfo tableInfoWithGroup:@"item1 item2 item3" mode:LSModeMerge schema:@"stock_name last_price min max" dataAdapter:@"QUOTE_ADAPTER" snapshot:YES];

And then subscribe it using the LSClient:

LSSubscribedTableKey *tableKey= [client subscribeTableWithExtendedInfo:tableInfo delegate:self useCommandLogic:NO];

If your code uses reference counting, remember to retain the obtained LSSubscribedTableKey object to later unsubscribe. Normally, real-time subscription share the life cycle of the session, so they are closed when the session ends, but the library is able to automatically resubscribe in case of reconnection (see below Automatic reconnections).

Listening for table events

Your designated table delegate will start to receive table updates as soon as they are sent from the Server:

- (void) table:(LSSubscribedTableKey *)tableKey itemPosition:(int)itemPosition itemName:(NSString *)itemName didUpdateWithInfo:(LSUpdateInfo *)updateInfo {
    ...
}


Congratulations! Your real-time subscription with Lightstreamer Server is now set up!

Using Mobile Push Notifications subscriptions

An MPN subscription is backed by a real-time subscription, thus you need an LSTableInfo object describing the table you want to subscribe. With MPN subscriptions there are some limitations, please check activateMPN:coalescing: (LSClient) for more information.
Once your LSTableInfo object is ready, you can create an LSMPNInfo object that includes the LSTableInfo and additionally describes how updates from the real-time subscription have to be delivered via mobile push (i.e. remote) notification:

LSMPNInfo *mpnInfo= [LSMPNInfo mpnInfoWithTableInfo:tableInfo sound:"Default" badge:@"AUTO" format:@"Stock ${stock_name} is now ${last_price}"];

You may then activate the MPN subscription:

LSMPNSubscription *mpnSubscription= [client activateMPN:mpnInfo coalescing:NO];

The obtained LSMPNSubscription object contains a permanent, global, unique key of the MPN subscription: LSMPNSubscription::mpnKey. It also provides services to obtain the status of the MPN subscription, modify it or deactivate it.
Note that MPN subscriptions are persistent: they survive the session and to be deactivated you must do an explicit call to deactivate (LSMPNSubscription), deactivateAllMPNs (LSClient) or deactivateMPNsWithStatus: (LSClient).

Close the connection

If your code uses reference counting, remember to close the connection before releasing the LSClient (it will not be released, otherwise):

[client closeConnection];

Automatic reconnections

The library has an advanced logic to automatically reconnect to the server in case of connection drops, timeouts, etc. The network availability is constantly monitored to attempt a reconnection only when it can be successful, and at the same time to preserve the device battery. At reconnection, the library will also automatically resubmit any subscription that was active when the connection dropped. This logic is active by default, and will stop trying only in presence of a clientConnection:didEndWithCause: (LSConnectionDelegate-p) event.
In view of this, avoid to manually manage the reconnection unless you have a strong reason to do so. If you really need to, close the connection during appropriate events to block the library's reconnection logic, e.g.:

- (void) clientConnection:(LSClient *)client didReceiveServerFailure:(LSPushServerException *)failure {
    [client closeConnection];
}


Or:

- (void) clientConnection:(LSClient *)client didReceiveConnectionFailure:(LSPushConnectionException *)failure {
    [client closeConnection];
}

Using more than one LSClient

The library allows the use of more than one LSClient instance at the same time. However, consider that more clients means more threads, bigger memory footprint and more overhead. Moreover, please recall that every operating system poses a hard limit on how many concurrent HTTP connections may be opened to the same end-point (i.e. host name and port). So, if you are going to use more than one LSClient to the same server check the LSConnectionInfo::maxConcurrentSessionsPerServerExceededPolicy parameter. With it, you can specify how the LSClient should behave in case this limit is exceeded. Finally, keep in mind that the library does not know a priori this limit, it simply confronts the number of open connections to the same server with the static parameter maxConcurrentSessionsPerServer (LSConnectionInfo), which is our best guess of this limit. Highering or loweing this parameter is possible although discouraged, and may lead to unexpected results.