21

I am attempting to create an application that will initiate a call to a priority 1 contact on a call-center-like list.

Then, if that contact does not answer (let's forget the whole problem of answering machines here), I'd like to call the priority 2 contact, and so on, until one of them answers or I exhaust my list.

Is this possible?

I've tried the following:

  1. Hook into the CTCallCenter.CallEventHandler event, and checking the call state for CTCallStateConnected and CTCallStateDisconnected, and I get it to respond to the fact that the call disconnected, without ever connecting, and then attempt to initiate another call like I did the first, but this second attempt just sits dead in the water.
  2. Override the DidEnterBackground method, and periodically check the CTCall.CallState property, basically again trying to respond to a disconnect that was never connected, but this does not appear to work either

I also tried adding a short delay (1 second, 2.5 seconds and 10 seconds) after detecting the disconnected state before attempting the next dial, to allow for the phone application to "settle down" after aborting the call, this did not change anything.

Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
  • You might consider doing this via a Twilio number. They have example code for this sort of flow. – ceejayoz Jan 03 '12 at 20:09
  • 3
    I'll definitely look more at Twilio, but a cursory look tells me this is not what I seek. At the moment, the call has to originate on my phone and go to the priority-1 caller, so that he/she sees that it is me. Also, this app will be installed by other people, and making all those people set up their own twilio accounts for this is not within the scope of this app (please correct me if I understand something wrong here.) – Lasse V. Karlsen Jan 03 '12 at 20:39
  • I know this might be a long shot but did you try dispatching your second call after a period of time using `[self performSelector:<#(SEL)#> withObject:<#(id)#> afterDelay:<#(NSTimeInterval)#>]` Working with iOS for some time showed me that often you must dispatch events after a delay (specially does needing UI animation in your case switching to phone view). – Cyprian Jan 03 '12 at 21:40
  • This sounds like something you would use Google Voice to do. http://www.google.com/googlevoice/about.html – rwyland May 17 '12 at 02:48

5 Answers5

7

I'm of the opinion that this is better solved at the destination of the phone call. I would either have the phone company configure a "follow me" service, use Twilio or some other 3rd party service (as already suggested), or configure my own PBX using something like Asterisk (Asterisk includes the ability to configure "follow me" type behavior). It provides you much more flexibility and control, even if you did find a way to do this natively in iOS.

Having said that, I did get this to work in iOS assuming the following:

  1. Your app initiates the call.
  2. The phone app is opened, dials the number, and disconnects.
  3. The user explicitly returns to your app. If you managed to get the events while your app was backgrounded, I want to know more :-).
  4. On return of control to your app, the phone events are sent and a new call is initiated.

I have the following snippet of code in my UIApplicationDelegate didFinishLaunchingWithOptions method:

// In appdelegate header, ct is declared as @property (strong, nonatomic) CTCallCenter *ct; 
self.ct = [[CTCallCenter alloc] init];
self.ct.callEventHandler = ^(CTCall *call) {
    if (call.callState == CTCallStateConnected) {
        // do some state management to track the call
    } else if (call.callState == CTCallStateDisconnected) {
        // check that this is the expected call and setup the
        // new phone number
        NSURL *telURL = [NSURL URLWithString:myNewNumberURL];
        [application openURL:telURL];    
    }     
};

This will make the new call. I'm using the iOS 5 SDK; tested on an iPhone 4s.

EDIT:

Using Return to app behavior after phone call different in native code than UIWebView as a starting point, I've managed to get this to work. Note that I have punted on memory management for clarity. Assuming you use the web view technique for getting back to your app after the call is complete, try something like this in the call completed block:

else if (call.callState == CTCallStateDisconnected) {
    // check that this is the expected call and setup the
    // new phone number
    NSURL *telURL = [NSURL URLWithString:myNewNumberURL];
    dispatch_async(dispatch_get_main_queue(), ^{
        UIWebView *callWebview = [[UIWebView alloc] init]  ;
        [self.window.rootViewController.view addSubview:callWebview];
        [callWebview loadRequest:[NSURLRequest requestWithURL:telURL]]; 
        // and now callWebView sits around until the app is killed....so don't follow this to the letter.  
    });
}

However, this may not quite give you what you want either. The user will get an alert on each call request, providing an opportunity to cancel the call.

Community
  • 1
  • 1
MikeG
  • 4,015
  • 2
  • 27
  • 25
  • Unfortunately that doesn't meet our criteria either, but I think by now that (especially) you, and the others have sufficiently highlighted the same conclusion we came to, that this is indeed not something possible (or easily done). We have some ideas to work with, but our criteria is a completely unattended second call (ie. no manual accept or return to app) with no 3rd party services involved (like Twilio or similar). I'm going to accept this answer not because it solved it, but because it shows that this is quite possible impossible to do. Thanks for the help. – Lasse V. Karlsen May 19 '12 at 09:52
  • You can also use [[UIApplication sharedApplication] openURL:@"telprompt:0123456789"]; to get the same behaviour as the web view work-around (the prompt and returning to your app after the call). – Ricky Helgesson May 21 '12 at 10:18
0

I didn't take a deeper look at it, but the Deutsche Telekom SDK might contain what you're looking after:

http://www.developergarden.com/fileadmin/microsites/ApiProject/Dokumente/Dokumentation/ObjectiveC-SDK-2.0/en/interface_voice_call_service.html

I really am not sure though (don't have time to really look at it at the moment) - I just remembered I'd read somewhere that they have an iOS SDK that is supposed to also handle call management, so I'm posting the link here for you to find out (and hopefully tell us if it works).

fzwo
  • 9,842
  • 3
  • 37
  • 57
0
#pragma mark -
#pragma mark Call Handler Notification
-(void)notificationCallHandler {

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(callReceived:) name:CTCallStateIncoming object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(callEnded:) name:CTCallStateDisconnected object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(callConnected:) name:CTCallStateConnected object:nil];

}
-(void)callEnded:(NSNotification*)notification {
     NSLog(@"callEnded");

}

-(void)callReceived:(NSNotification*)notification {
     NSLog(@"callReceived");
}
-(void)callConnected:(NSNotification*)notification {
     NSLog(@"callConnected");
}

May this will help you

Kuldeep
  • 2,589
  • 1
  • 18
  • 28
  • No, because I already react to those, but my app is already in the background due to the phone app taking over, and I doubt I can set up a new call when I'm in the background. – Lasse V. Karlsen May 16 '12 at 13:01
  • http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Reference/CTCallCenter/Reference/Reference.html I think in background the block won't respond rather whenever it becomes active the block will respond the earlier call (As per apple documentation). – Kuldeep May 16 '12 at 13:04
0

if you wanna setup a new call, while app is in background, i dont see any proper way for this, a lil hack could be, getting location update (because u can get location updates while app is in background), and location service automatically wakes up your application when new location data arrives, and small amount of time is given to application in which u can execute some code, in that time you may start a new call.

u can read further here:
search this ''Starting the Significant-Change Location Service'' in this link Location Aware programming guide , and read the paragraph that is written after the code block.

waheeda
  • 1,097
  • 1
  • 9
  • 18
0

You could use http://labs.twilio.com/twimlets/findme. You could have the app call a Twilio number and it could use findme to call all the numbers in order.

Sam Baumgarten
  • 2,231
  • 3
  • 21
  • 46