0

I have this nagging problem that I just can't seem to fix. I'm trying to call a function within a particular class (called BMUserManagementService), but for some reason the completion handler in the data task is not executing. The method is below (getProfile):

    internal func getProfile(completion: @escaping (Bool?) -> Void) {
        guard let url = self.getProfileLogin else {
            fatalError("Can't find the URL to get a profile!")
        }
        print("unwrapped url: \(url)")

        let semaphore = DispatchSemaphore (value: 0)

        var request = URLRequest(url: URL(string: url)!,timeoutInterval: Double.infinity)
        request.addValue("bearer \(self.accessToken ?? "")", forHTTPHeaderField: "Authorization")
        request.addValue("application/json", forHTTPHeaderField: "Accept")
        request.httpMethod = "GET"

        print("Request built in getProfile")

        print(request)

        let task = URLSession.shared.dataTask(with: request) { data, response, error in

            print("GetProfile - inside the completion block for the data task...")

            if error != nil {
                //fatalError("Error: \(String(describing: error))")
                print("ERROR-A")
                return
            }

            guard let data = data else {
                //fatalError("Error encountered while to get a profile.  Error: \(String(describing: error))")
                print("ERROR-B")
                return
            }

            print(String(data: data, encoding: .utf8)!)

            let getProfile = try? JSONDecoder().decode(GetProfile.self, from: data)

            if let results = getProfile {
                if results.master == true {
                    self.getProfileId = results.id
                    completion(true)
                }
            } else {
                completion(false)
            }

            semaphore.signal()
        }

        task.resume()
        semaphore.wait()
    }

I'm calling this function from another view controller like this:

                    self.userManagementSvc?.pollUserManagementService(completion: { (status) in
                        guard let status = status else { return }
                        if status {
                            self.userManagementSvc?.getProfile(completion: { (status) in
                                guard let success = status else { return }
                                if success {
                                    self.userManagementSvc?.loginWithProfile(completion: { (status) in
                                        guard let success = status else { return }
                                        if success, let accessToken = self.userManagementSvc?.accessToken, let refreshToken = self.userManagementSvc?.refreshToken {
                                                self.accessToken = accessToken
                                                self.refreshToken = refreshToken
                                                self.userManagementSvc?.wasFirstTokenCreated = true
                                                self.videoPlayback.userSettings = self.userSettings
                                                DispatchQueue.main.async {
                                                    // Assign the access token with a linked profile ID to appData
                                                    self.videoPlayback.appData.jwtAccessToken = self.accessToken
                                                    self.videoPlayback.startPlaybackWithContent(vidi: self.bmVidi, content: currentContent, accessToken: self.accessToken, refreshToken: self.refreshToken)
                                                }
                                            }
                                    })
                                }
                            })
                        } else {
                            DispatchQueue.main.async { BMViewControllerManager.shared.getTopViewController()?.dismiss(animated: true) {
                                let alert = UIAlertController(title: NSLocalizedString("unableToAuthenticateTitle", comment: ""), message: NSLocalizedString("unableToAuthenticateDescription", comment: ""), preferredStyle: .alert)
                                let okAction = UIAlertAction(title: NSLocalizedString("okButtonTitle", comment: ""), style: .default) { (_) in
                                    DispatchQueue.main.async { BMViewControllerManager.shared.getTopViewController()?.dismiss(animated: true) {} }
                                }
                                alert.addAction(okAction)
                                DispatchQueue.main.async { BMViewControllerManager.shared.getTopViewController()?.present(alert, animated: true) {} }
                            } }
                        }
                        self.userManagementSvc?.pollingIterationsCount = 0
                    })

Why isn't the data task executing?

Please advise

JFortYork
  • 137
  • 10
  • 2
    Delete the semaphore. It's completely pointless when using a completion handler. And why is the passed `Bool` in the completion handler optional? Better pass a `Result` instance to be able to hand over also the errors. – vadian Mar 18 '20 at 21:16
  • Thank you, why does the semaphore cause this issue though? – JFortYork Mar 18 '20 at 21:20
  • The semaphore blocks the thread. – vadian Mar 18 '20 at 21:21
  • Ahhh...ok. I will try it and will respond back tomorrow. Please write an answer so that I can mark it as correct. – JFortYork Mar 18 '20 at 21:22

0 Answers0