Alamofire 请求或 Firebase 查询在非 UIViewController 中不起作用 Class

Alamofire request or Firebase query is not working in a non UIViewController Class

Imperial 尝试使用 alamofire 向网站执行请求,我的问题如下:

当我在 ViewController cocoaTOuch class viewDidLoad() 函数中使用相应的代码时,一切正常。(这里是代码)

super.viewDidLoad()
    let loginActionUrl = url

    do{
        let parameters = [
            "p_user":user,
            "p_password": password
        ]

        AF.request(loginActionUrl, method: .post, parameters: parameters).responseJSON
            {response in
                if let header = response.response?.allHeaderFields as? [String: String],
                    let responseUrl = response.request?.url{
                    let sessionCookies = HTTPCookie.cookies(withResponseHeaderFields: header, for: responseUrl)

                    ......

如果我在 swift(非 cocoa 触摸)class 上的私有函数内重复相同的代码,那么,我没有任何反应,调试时它会尝试执行两次request任务然后跳出{response in code block.

代码如下:

 private func checkInWithAeA(withLogIn: String, password: String) -> (Bool){
    var companyUSerRecognized: Bool = false
    var startIndex: String.Index!
   let loginActionUrl = url
    do{
    let parameters = [
        "p_user" : withLogIn,
        "p_password": password
    ]


    AF.request(loginActionUrl, method: .post, parameters: parameters).responseJSON
        {response in

            if let header = response.response?.allHeaderFields as? [String: String],
                                    let responseUrl = response.request?.url{
                let sessionCookies = HTTPCookie.cookies(withResponseHeaderFields: header, for: responseUrl)
                companyUSerRecognized = true
......

我现在不知道发生了什么,但这是我第二次遇到同样的问题。我正在尝试避免使用其他支持 classes 在 viewController 中设置太多代码,遵循最佳实践,但我已经尝试使用 firebase 来做到这一点,并且我有同样的问题,对数据库的查询只在 UIViewcontroller classes 中有效(在某些情况下),现在是一样的,当我在干净的 swift 文件中执行代码时,我无法获得任何结果.

这有什么限制吗?为什么我不能通过 UIViewControllerclass?

对实时数据库执行任何类似 alamofire 请求或 firebase 查询的操作

这里补充一点信息:

  var myConnectionController: ConnectionController = ConnectionController()
                let (companyUSerRecognized, error) = myConnectionController.chekUserIDandPassWord(forTheCompany: self.companyName, logInName: self.companyLogIn, password: self.companyPassword)

此调用 ConnectionController class(即 swift 普通 class)请求连接到网页。如果响应良好,则获得 true 并继续该过程。

调用的函数有switch语句:

 public func chekUserIDandPassWord(forTheCompany: String, logInName: String, password: String) -> (Bool, String){
    var companyUSerRecognized: Bool!
    var error: String!

    switch forTheCompany {
    case "(AEA)":
        companyUSerRecognized = checkInWithAeA(withLogIn: logInName, password: password)
        break

.....

这就是所谓的使用 AeA 签入。 (我刚才提到的功能)。我想要的是在 return 中获取连接的 cookie 检查它们,如果它们是好的,那么 returned 是真的。

我已经在 ViewController 的 viewDidLoad() 函数中完成了这个,事实上我可以用 SwiftSoup 等解析响应。但是如果我这样做我就做不到.

再次感谢

我通过查阅一些参考书目终于得出了解决方案。我没有注意到,任何 alamofire 调用都会打开一个管道。也就是说,我们显然在谈论异步操作。在 swift 中有两种处理此类操作的方法。一种是使用未来的对象。此选项允许通过在准备就绪时替换异步调用的结果来继续执行。根据情况,这不是很好。另一种是让执行等待异步调用的响应。这是通过闭包完成的。我选择了最后一个选项。

通过使用在异步调用块末尾调用的完成处理程序函数来执行更接近 return 异步调用所需的任何值。在这种情况下。这就是我所说的完成

private func checkInWithAeA(completion: @escaping (Bool)-> Void){
    let loginActionUrl = url1
    let postLoginUrl = url2
   let parameters = [
       "p_user" : logInName,
       "p_password": password
   ]

    AF.request(loginActionUrl, method: .post, parameters: parameters).responseData
               {(response) in
                if let header = response.response?.allHeaderFields as? [String: String],
                let responseUrl = response.request?.url{
                let sessionCookies = HTTPCookie.cookies(withResponseHeaderFields: header, for: responseUrl)
                    let cookieToSend = sessionCookies[0]

//调试 打印(cookieToSend) AF.session.configuration.httpCookieStorage?.setCookie(cookieToSend) 完成(真) }别的{ 完成(假) } } }

就是这样。希望对你有帮助

顺便说一句。我认为这与 firebase 查询的问题相同。

谢谢!