📜 ⬆️ ⬇️

Some features of the implementation of background applications for iOS 4

The article will discuss the experience of implementing background applications for the iOS 4 platform as part of the work on the Viber project of Viber Inc. The first version of Viber was available to users of the AppStore on December 2, 2010. The number of users of the Viber for iPhone application in May 2011 exceeded 15 million users. The application has several interesting features:


The version for the Android operating system is now in a closed beta test.

Introduction


Before the release of iOS 4, developers of applications for the iPhone did not have the ability to perform tasks in the background and maintain a constant connection with the server to promptly notify users of events and update information for an application that is not currently running. The only limited way to notify users about events from the server was a push notification mechanism, which has the following disadvantages:
The ability to perform tasks in the background may be required for applications: a) related to navigation and (or) tracking a user’s movement (recording GPS trajectories); b) requiring prompt user notification of events on the server; c) playing music (for example, Internet radio).

Apple has implemented support for background task execution in the iOS 4 operating system. When implementing background task execution, the application developer faces considerable difficulties, the solution of which can be found mainly by experiment with the prompts of Apple official documentation.

In the series of articles it is planned to talk about empirically found ways to solve various problems related to performing tasks in the background when developing applications for the iOS 4 platform. This article will cover basic issues of performing tasks in the background using one of three types of background applications of the platform iOS 4 voip .
')
In iOS 4, three types of background applications are available (they can be used in an application at the same time):
When iOS translates an application to the background (the applicationDidEnterBackground method is called :) ), you can request additional time to complete the current task, for example, to download or download a file by sending a beginBackgroundTaskWithExpirationHandler: message to the UIAppication instance: with a parameter block that will be called shortly before Background application execution will expire. When the task is complete, you need to send the message endBackgroundTask:. The operating system gives about 10 minutes of time to work in the background.

Developers have another new feature related to the background execution of tasks: sending local notifications . The notification itself is very similar to remote push, but does not require a connection to the server and is sent by the application to itself. At the same time, an application that is currently running in the background can send such a notification immediately in order to attract the user's attention. For an application in the background, sending a local notification may be the only way to attract the user's attention. Local notification can be sent by the application at a predetermined time and (or) at a certain interval. When sending a local notification, the application itself can be turned off (for example, the alarm / timer). The maximum number of active notifications for an application cannot exceed 128 active notifications in a queue.

Background class voip


Let us consider in more detail some features of using the voip background class. First of all, it is the ability to permanently connect to the server to get up-to-date information about incoming calls and messages or other events that need to be reported to the user. As practice shows, remote push is often not enough. In the background, only one tcp socket can be used to communicate with the server, marked for iOS in a special way before returning from the applicationDidEnterBackground function :. At the same time, the application will be suspended, but the system will allocate time slots for operation in 3 cases: a) when incoming data appears on the socket; b) when network properties change that affect the availability of the server to which the socket is connected; c) by timer in a block of code exposed as a keep-alive handler, the minimum keep-alive interval is 10 minutes. To attract the user's attention during the processing of these events, you can use local notifications.

In addition to maintaining communication with the server in the background, the voip class provides another important opportunity: any application with the voip class in the parameters will be automatically launched in the background at system startup and re-launched in the background after the crashes. An important feature is that when running in the background, the UIApplicationDelegate applicationDidEnterBackground: method will not be called, so you must connect and mark the socket as VoIP before returning from the application: didFinishLaunchingWithOptions: method, otherwise the application will simply be suspended.

In order to make it clear to iOS which of the connections should be monitored in the background, there are several possibilities depending on which network API is used. In the case of the highest-level NSMutableURLRequest, it suffices to call the setNetworkServiceType: method with the NSURLNetworkServiceTypeVoIP parameter. If the work is at the NSInputStream / NSOutputStream level, then it is necessary to set the NSStreamNetworkServiceTypeVoIP value for the NSStreamNetworkServiceType property. In our application, the network layer is written to support the maximum number of platforms, so regular BSD sockets are used. There is no API for configuring BSD sockets as voip, so you need to create a couple of streams from an already connected socket using CFStreamCreatePairWithSocket and then set the kCFStreamNetworkServiceType property of the streams to kCFStreamNetworkServiceTypeVoIP.

The configuration of the voip socket must be completed before returning from the application: didFinishLaunchingWithOptions: and applicationDidEnterBackground: methods (as well as before returning from the keep-alive handler or changing the network properties in case it reconnects to the server), so you need to connect use synchronous API, which is often inconvenient, or connect to the server and configure the voip-socket in a separate stream, and block the main stream until the connection is completed. The easiest way to synchronize in this case is to use NSConditionLock. This is a high-level interface for posix conditional variables, which is much easier to use. A simple NSLock or posix mutex cannot be used, since it must be blocked in one thread and unlocked in another. Example connection code in the background:

// <br/>
enum { <br/>
EConnecting,<br/>
EConnected,<br/>
} ;<br/>
<br/>
// , <br/>
NSConditionLock * waitForConnectionLock = nil ;<br/>
<br/>
// , <br/>
// application:didFinishLaunchingWithOptions:, applicationDidEnterBackground: <br/>
// keep-alive <br/>
waitForConnectionLock = [ [ NSConditionLock alloc ] initWithCondition : EConnecting ] ;<br/>
<br/>
// <br/>
[ server performSelectorInBackground : @selector ( connect ) withObject : waitForConnectionLock ] ;<br/>
<br/>
// <br/>
…<br/>
// EConnected - <br/>
// - <br/>
if ( [ waitForConnectionLock lockWhenCondition : EConnected beforeDate : timeout ] ) { <br/>
[ waitForConnectionLock unlock ] ;<br/>
// -, , , <br/>
// voip <br/>
[ server markSocketAsVoIP ] ;<br/>
} <br/>
// <br/>
[ waitForConnectionLock release ] ;<br/>
// <br/>
return ;<br/>
<br/>
//----------------- <br/>
// connect <br/>
// , , EConnecting <br/>
[ waitForConnectionLock lock ] ;<br/>
// <br/>
…<br/>
// , EConnected <br/>
// <br/>
[ waitForConnectionLock unlockWithCondition : EConnected ] ;

The background class voip will be useful for any applications that need to promptly notify the user about events from the server or accumulate up-to-date information, not necessarily related to VoIP telephony.

Conclusion


In the next article we will take a closer look at the keep-alive handlers and network state changes, how to correctly calculate the connection timeout, just touch the playing of sound in the background.

Source: https://habr.com/ru/post/120402/


All Articles