How to call presentViewController from inside class

南笙酒味 提交于 2020-01-01 18:59:10

问题


Inside my completion handler I am trying to return the http response code much like alert in JS. Once I get this sorted I hope to improve my if statement to identify a connection problem to the end user. I was looking at this article.

http://www.ioscreator.com/tutorials/display-an-alert-view-in-ios8-with-swift

I have also seen this answer Simple App Delegate method to show an UIAlertController (in Swift) but I get a similar method about the window not being named.

My code without all the noise is like this:

class NewsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

var tableView: UITableView!
var titleItems: NSMutableArray = []
var descritpionItems: NSMutableArray = []

class RemoteAPI {

    // base url
    let baseUrl = "http://api.dev/web/"
    // returned array of news titles + descriptions
    var newsTitle: NSMutableArray = []
    var newsDescription: NSMutableArray = []

    func getData(completionHandler: ((NSArray?, NSError?) -> Void)) -> Void {
        // get news feed url
        let url = NSURL(string: baseUrl + "news")
        // create session
        let session = NSURLSession.sharedSession()
        // set task
        let task = session.dataTaskWithURL(url!, completionHandler: { (data, response, error) -> Void in

            // if error isn't nil return error to getData
            if (error != nil) {
                return completionHandler(nil, error)
            }

            // check response
           if let httpResponse = response as? NSHTTPURLResponse {
                // if response doesn't equal 200 throw an alert
                 if httpResponse.statusCode != 200 {
                let alertController = UIAlertController(title: "Oh No!!", message: "Connection error",preferredStyle: UIAlertControllerStyle.Alert)

                alertController.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.Default,handler: nil))

                UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(alertController, animated: true, completion: nil)

                } else { // no error continue

            // convert data object to json
            let json = JSON(data: data)

            for var i = 0; i < json.count; ++i {
                // get news title from json object
                var title = json[i]["title"].string
                var blurb = json[i]["description"].string
                // add to dictionary
                self.newsTitle.addObject(title!)
                self.newsDescription.addObject(blurb!)
            }

            if (error != nil) {
                return completionHandler(nil, error)
            } else {
                return completionHandler([self.newsTitle,self.newsDescription], nil)
            }
        }
    }
    })
        task.resume()
    }
}

// get data
var api = RemoteAPI()

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    self.view.frame = CGRect(x: 5, y: 75, width: 365, height: 480)
    self.tableView = UITableView(frame:self.view!.frame)
    self.tableView!.delegate = self
    self.tableView!.dataSource = self
    self.tableView!.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
    self.view?.addSubview(self.tableView)

    api.getData({data, error -> Void in
        if (data != nil) {
            self.titleItems = self.api.newsTitle
            self.descritpionItems = self.api.newsDescription
            self.tableView!.reloadData()
        } else {
            println("API failed :-(")
            println(error)
        }
    })
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{

    return self.titleItems.count
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{

    var cell:UITableViewCell=UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "mycell")

    if let newsTitle = self.titleItems[indexPath.row] as? NSString {
        cell.textLabel?.text = newsTitle
    }
    if let newsDesc = self.descritpionItems[indexPath.row] as? NSString {
        cell.detailTextLabel?.text = newsDesc
    }
    return cell
}

}

I get an error of NewsViewController.RemoteAPI does not have member named presentViewController. I understand why, just not sure how to call this within the class being new to iOS


回答1:


Your class RemoteAPI does not have a method called presentViewController(). presentViewController() is a method on a UIViewController. This is why you are getting the error.

To call presentViewController(), call back to a UIViewController instance when your HTTP response finishes.

Inside your else block of api.getData(), you can access the error object. Here you can create your alert controller and then present it. This block of code is called a callback, and your view controller should be responsible for creating the alert controller that indicates an error.




回答2:


In my situation here, the following worked:

UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(alertController, animated: true, completion: nil)



回答3:


self.presentViewController(alertController, animated: true, completion: nil)

You missed external name of second parameter.

Move your alert code inside api call completion closure

api.getData({data, error -> Void in
    if (data != nil) {
        self.titleItems = self.api.newsTitle
        self.descritpionItems = self.api.newsDescription
        self.tableView!.reloadData()
    } else {
        println("API failed :-(")
        println(error)
        // here
    }
}


来源:https://stackoverflow.com/questions/29323449/how-to-call-presentviewcontroller-from-inside-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!