-1

I trying to make a calling app for my project and I want to add a function that keeps checking if someone if calling. My app uses Firebase where I have a key for each users to check if he made a call or not.

There's two problem I am facing here, the first one is, as I said, that I want my function to keep checking anywhere in the app for an incoming call. The other problem is that i have a viewcontroller that I want to pop up when someone is calling. I have found this code on github but it uses navigationcontroller which I am not using in my app :

extension UIViewController{
func presentViewControllerFromVisibleViewController(viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)? = nil) {
    if let navigationController = self as? UINavigationController, let topViewController = navigationController.topViewController {
        topViewController.presentViewControllerFromVisibleViewController(viewControllerToPresent: viewControllerToPresent, animated: true, completion: completion)
    } else if (presentedViewController != nil) {
        presentedViewController!.presentViewControllerFromVisibleViewController(viewControllerToPresent: viewControllerToPresent, animated: true, completion: completion)
    } else {
        present(viewControllerToPresent, animated: true, completion: completion)
    }
}
}
halfer
  • 19,824
  • 17
  • 99
  • 186
alex
  • 79
  • 2
  • 14
  • Are you using CallKit? – ryantxr Aug 12 '17 at 20:42
  • @ryantxr no i am using an api – alex Aug 12 '17 at 21:15
  • 1
    Hi Alex. We don't expect posts to feature _perfect_ English, but if you can make them as readable as possible, that is much appreciated by readers here. It looks like your posts are all written in lower case - note that sentences should start with a capital, and when referring to yourself, "I" should also be capitalised. If you can make those changes in your future posts, that would be great! – halfer Aug 13 '17 at 09:50

2 Answers2

1

For your question on monitoring when incoming calls occur and to be called as a result, see this answer. It's probably what you need (I've never tried it, however). The example shows creating a CXCallObserver and setting your AppDelegate as delegate.

For your second question, I'd first try this answer which leverages the window.rootViewController so you can do this from your AppDelegate. Generally, the root VC is your friend when trying to do UI your AppDelegate. :)

A better answer based on Alex's added comments:

I'd first look at how to set up an observer to your Firebase model so that you can get a callback. If you don't have a way to do that, I'd use KVO on the Firebase model property. But to do exactly as you're requesting, and to do so lazily from AppDelegate (rather than from a singleton), see this code:

// In AppDelegate

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool
{
    self.timerToCheckForCalls = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timerFired), userInfo: nil, repeats: true)
}

func timerFired()
{
    let didCall = // TODO: query your Firebase model...
    guard didCall == true else
    {
        return
    }

    self.displayCallerView()
}

func displayCallerView()
{
    // See below link.
}

See this answer for how to present your view controller, even when your app might be showing an action sheet, alert, etc... which I think you'd especially value since you need to display the caller regardless of what your app is doing.

Note while user is scrolling a UITextView, the timer won't fire yet. There may be other situations where the timer could be delayed too. So it really would be best to observe your Firebase model or receive a KVO callback than to use a timer.

Smartcat
  • 2,834
  • 1
  • 13
  • 25
  • thanks for your answer, but i am not using CallKit i am using an api – alex Aug 12 '17 at 21:16
  • Do you need help adapting a similar strategy using your call API? If so, what API are you using? – Smartcat Aug 12 '17 at 21:30
  • i am working with twilio, but i am not going to use it yet, all i need is for that function to check a key called " calling" witch its value is set to false in the firebase database and do that across the entire app, so basiclly the function will be called repetitively anywhere in the app and when someone make a call the key will be changed to true and a view will popup with the name of the caller and when the user accept only then the api will do its work and connect the two users. hope you get the idea – alex Aug 12 '17 at 21:44
1

If you want to make a function that can be called from anywhere, use a singleton pattern. You can also use that to store your special view controller.

Bear in mind that this code SHOULD NOT considered fully functioning code and will need to be customized by you to suit your needs.

class MyClass {
    let shared = MyClass()
    var viewController: SpecialViewController?
    func checkForCall() {
        // do function stuff
    }

    func getSpecialViewController() {
        let storyBoard = UIStoryboard.init(name: "main", bundle: nil)
        // keep it so we don't have to instantiate it every time
        if viewController == nil {
            viewController = storyBoard.instantiateViewController(withIdentifier: "SomeViewController")
        }
        return viewController
    }

}

// Make an extension for UIViewController so that they can all
// use this function
extension UIViewController {
    func presentSpecialViewController() {
        let vc = MyClass.shared.getSpecialViewController()
        present(vc, animated: false, completion: nil)
    }
}

Somewhere in your code:

// in some function
MyClass.shared.checkForCall()

Somewhere else in code:

presentSpecialViewController()
ryantxr
  • 4,119
  • 1
  • 11
  • 25