iOS Background Mode VOIP – Exploring with Experiments

In iOS, Most apps will get completely suspended in Background modes. If you want to know more about background mode, you can read this article Support for applications running in background – iOS .

VoIP Background Mode – VoIP stands for Voice over Internet protocol or internet telephony, when apps connects to server it keeps the connection open while in background and gets callbacks when apps gets something from connection. In InnovationM, We have explored the VoIP Background mode in different – different conditions & scenarios.

Let’s get started !

VoIP iOS Client Application

The easiest way to build VoIP app is by using the CFStreamCreatePairWithSocketToHost function. That means a lot of bridging to be able to use the NSInputStream and NSOutputStream classes afterwards. After the streams are configured we only need to open the connection on both.

- (IBAction)connect:(id)sender
{
    if (!self.inputStream)
    {
       // Configure the connections
        CFReadStreamRef readStream;
        CFWriteStreamRef writeStream;
        CFStreamCreatePairWithSocketToHost(NULL, @"192.168.1.14",@"6666", &readStream, &writeStream);

        self.sentPing = NO;
        self.communicationLog = [[NSMutableString alloc] init];
        self.inputStream = (__bridge_transfer NSInputStream *)readStream;
        self.outputStream = (__bridge_transfer NSOutputStream *)writeStream;
        [self.inputStream setProperty:NSStreamNetworkServiceTypeVoIP forKey:NSStreamNetworkServiceType];
     // Setting the self delegate in input/output stream
        [self.inputStream setDelegate:self];
        [self.outputStream setDelegate:self];
        [self.inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        [self.outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

        // Open the Connection
        [self.inputStream open];
        [self.outputStream open];

        // Set Keep Alive Timeout for 600 seconds Hadler
        [[UIApplication sharedApplication] setKeepAliveTimeout:600 handler:^{
            if (self.outputStream)
            {
                [self.outputStream write:pingString maxLength:strlen((char*)pingString)];
                [self addEvent:@"Ping sent"];
            }
        }];
    }
}

Now you need to add the stream delegate that will receive updates for the connection. Add this code anywhere in your class:

#pragma mark - NSStreamDelegate

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{
    switch (eventCode) {
        case NSStreamEventNone:
            // do nothing.
            break;

        case NSStreamEventEndEncountered:
            [self addEvent:@"Connection Closed"];
            break;

        case NSStreamEventErrorOccurred:
            [self addEvent:[NSString stringWithFormat:@"Had error: %@", aStream.streamError]];
            break;

        case NSStreamEventHasBytesAvailable:
            if (aStream == self.inputStream)
            {
                uint8_t buffer[1024];
                NSInteger bytesRead = [self.inputStream read:buffer maxLength:1024];
                NSString *stringRead = [[NSString alloc] initWithBytes:buffer length:bytesRead encoding:NSUTF8StringEncoding];
                stringRead = [stringRead stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];

                [self addEvent:[NSString stringWithFormat:@"Received: %@", stringRead]];

                if ([stringRead isEqualToString:@"notify"])
                {
                    UILocalNotification *notification = [[UILocalNotification alloc] init];
                    notification.alertBody = @"New VOIP call";
                    notification.alertAction = @"Answer";
                    [[UIApplication sharedApplication] presentLocalNotificationNow:notification];
                }
                else if ([stringRead isEqualToString:@"ping"])
                {
                    [self.outputStream write:pongString maxLength:strlen((char*)pongString)];
                }
            }
            break;

        case NSStreamEventHasSpaceAvailable:
            if (aStream == self.outputStream && !self.sentPing)
            {
                self.sentPing = YES;
                if (aStream == self.outputStream)
                {
                    [self.outputStream write:pingString maxLength:strlen((char*)pingString)];
                    [self addEvent:@"Ping sent"];
                }
            }
            break;

        case NSStreamEventOpenCompleted:
            if (aStream == self.inputStream)
            {
                [self addEvent:@"Connection Opened"];
            }
            break;

        default:
            break;
    }
}

Here, we need to add App Provides Voice over IP Service in background modes of info.plist.

VoIP

Server side configuration for VoIP 

Now we need to setup Server side configuration for connection with client. And for this we are using JAVA here. Initially we will setting up a socket connection which listening on a fix port.

ServerSocket ss;
Socket s;
MyServer()throws IOException
{
ss=new ServerSocket(4444);
System.out.println("Server Started");
while(true)
{
try
{
s=ss.accept();
System.out.println("Client is Connected");
}
catch (IOException e)
{
System.out.println("Accept failed: 4444");
}

Sending Data from server to client to check connection is live or not.

try
{
int ch = 0;
while(true)
{

System.out.println("Sending" +ch);
dout1=new DataOutputStream(s.getOutputStream());
dout1.writeUTF("for checking");
dout1.flush();
ch++;
}
}
catch(Exception oe)
{
System.out.println("Main expression"+oe);
}

Experiment Stages for VoIP Application 

  1. Socket Connection without VoIP Background Mode registered.
  2. Socket Connection with VoIP registered.
  3. iOS Application Terminated.
  4. VoIP App on boot time launch.

Socket Connection without VoIP Background Mode registered

When we made a simple socket connection App without registering it with VoIP Background mode then in foreground state of app connection running well. But when app gone in suspended mode Socket connection stopes sending data, it means NO Activity over connection. We have conclude that the connection resumes again when app comes in foreground state from suspended mode. Which clears to us that in suspended mode connection have not broken and it resumes when comes to foreground.

We observe the same behaviour of app as above in case of Socket Connection with other Background Mode registered with Application.

Socket Connection with VoIP registered

When we registered Socket connection app with VoIP Background mode then app’s Socket connection with server is continuos in foreground as well as background state of application. Actually when application goes in suspended mode control over the app takes by Apple iOS and when any communication detects then control with CPU cycles again given to the VoIP app.

iOS Application Terminated

If we kill the application whether it registered with VoIP or not. It breaks the connection And sending of data from server side stopped and it’s shows the Socket connection broken. this message shows up because we checked it via below java code on server side.

int i = 1;
		System.out.println("Thread Validity of socket");		
		while(i == 1)
		{
				if((s.isClosed()))
				{
					i=0;
					System.out.println("Socket connection broken");		

				}
				else
				{
					System.out.println("Socket connected");		
				}

VoIP App on boot time launch

In Apple iOS devices, on boot time launch OS awake all it’s own app (Which was built in the iOS devices and developed by Apple via their private API’s) only. But only one type of application which developed by iOS developers and awake by apple iOS itself at boot time launch , is VoIP applications. So if we reboot a iOS device then those applications are registered with VoIP background modes , launched by iOS itself.

Advertisements

About Arpit kulshrestha

Arpit K Kulshrestha Graduated in Computer Science with HONORS Degree in 2012. He is on mission to develop or to be a part of great mobile application which can enhance user experience and able to explore the world. 6 + Years of Apple Mobile Application Development Experience with a strong focus on Building Enterprise, Social Networking Applications and working with Objective-C, Xcode, Storyboard & Instruments. Working knowledge of Core iOS frameworks and skilled in debugging. He has developed apps using SOAP, REST, JSON and XML based Web Services. He is interested to pursue a career in Mobile Applications Development field and he is certain that his skills and work experience prepared him well for such role.
 He has been a specialist in Multimedia & Networking based iOS applications in these years. Have a good in depth knowledge in Network Programming models like TCP/IP. Have done several rich multimedia (Videos & Images) processing & manipulating applications in the same. 
He is accustomed to successfully juggling multiple projects and have an excellent track record of forging strong relationships with client. He work equally well in team-oriented and self-directed environments and find the challenges of the start-up setting stimulating. Specialties:- Map kit , Core Location , UIKit , Core Data , SQLite , Google API's , Facebook API's ,Cocoa 2D, Core Motion, Event Kit.
This entry was posted in iOS Development and tagged , , , . Bookmark the permalink.

One Response to iOS Background Mode VOIP – Exploring with Experiments

  1. sandeep says:

    hi wt is ping string and pong string above code?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s