UIRefreshControl: unrecognized selector sent to instance - absoluteURL - ios

Before i start, i have went through each and every question relating to this issue. didnt help.
I want to refresh the json contents of my tableView which are fetched from a website.
The URL for each category comes from a different file that has All the categories listed in it.
The code that fetches the content is this
func animalSelected(animal: Animal) {
var request: NSURLRequest = NSURLRequest(URL: animal.url!)
self.refresh(animal.url!)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(animal.url!, completionHandler: {data, response, error -> Void in
// println("Task completed")
if(error != nil) {
// If there is an error in the web request, print it to the console
println(error.localizedDescription)
}
var err: NSError?
var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSDictionary
if(err != nil) {
// If there is an error parsing JSON, print it to the console
println("JSON Error \(err!.localizedDescription)")
}
let results: NSArray = jsonResult["posts"] as NSArray
self.didReceiveResults(jsonResult)
})
task.resume()
delegate?.collapseSidePanels?()
}
func didReceiveResults(results: NSDictionary) {
var resultsArr: NSArray = results["posts"] as NSArray
dispatch_async(dispatch_get_main_queue(), {
self.tableData = resultsArr
self.tableView.reloadData()
})
}
My ViewDidLoad method and the refresh method is as shown below
override func viewDidLoad() {
super.viewDidLoad()
refresher = UIRefreshControl()
refresher.attributedTitle = NSAttributedString(string: "Pull to Refresh")
refresher!.addTarget(self, action: "refresh:", forControlEvents: UIControlEvents.ValueChanged)
self.tableView.addSubview(refresher)
}
func refresh(categoryUrl : NSURL) {
var request: NSURLRequest = NSURLRequest(URL: categoryUrl)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(categoryUrl, completionHandler: {data, response, error -> Void in
if(error != nil) {
// If there is an error in the web request, print it to the console
println(error.localizedDescription)
}
var err: NSError?
var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSDictionary
if(err != nil) {
// If there is an error parsing JSON, print it to the console
println("JSON Error \(err!.localizedDescription)")
}
let results: NSArray = jsonResult["posts"] as NSArray
self.didReceiveResults(jsonResult)
})
task.resume()
self.refresher.endRefreshing()
}
I need to refresh the contents of the same URL that has been selected i.e refresh the same category.
I get this error : [UIRefreshControl absoluteURL]: unrecognized selector sent to instance 0x7fa0b3d73750
I think it is something related to absoluteURL. Bt don't know what is it..
plsss plssssss plssss help

You're trying to get the absoluteURL of a UIRefreshControl that you think is actually an NSURL.
To be exact, your sender in refresh(categoryUrl: NSURL) is the UIRefreshControl not NSURL.

Related

how can i fix this error when i try to Using External Database and API's with swift

i try to using external database and api's. so i follow from this video in youtube
https://www.youtube.com/watch?v=Ixk93yx-v28
and i see this error
"Value of optional type 'NSURL?' not unwrapped; " on that line
func request(url:String,callback:(NSDictionary)->()) {
var nsURL = NSURL(string: url)
///////////////////////////on this line/////////////////////////////////
let task = NSURLSession.sharedSession().dataTaskWithURL(nsURL) {
/////////////////////////////////////////////////////////////////
(data,response,error) in
var error:NSError?
var response = NSJSONSerialization.JSONObjectWithData(data, options:NSJSONReadingOptions.MutableContainers, error: error) as NSDictionary
callback(response)
}
task.resume()
}
and when i try to fix by put ! in nsURL like this
xCode return this error "Extra argument 'error' in call "
func request(url:String,callback:(NSDictionary)->()) {
var nsURL = NSURL(string: url)
let task = NSURLSession.sharedSession().dataTaskWithURL(nsURL!) {
(data,response,error) in
var error:NSError?
////////////////////////////Error Here/////////////////////////////////////
var response = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: error) as NSDictionary
/////////////////////////////////////////////////////////////////////////////////
callback(response)
}
task.resume()
}
have any ideal ? sorry for my english
Update your function as shown below for swift 2.0:
func request(url:String,callback:(NSDictionary)->()) {
guard let nsURL = NSURL(string: url) else { return }
///////////////////////////on this line/////////////////////////////////
let task = NSURLSession.sharedSession().dataTaskWithURL(nsURL) {
/////////////////////////////////////////////////////////////////
(data, response, error) in
guard let data = data where error == nil else { return }
do {
if let response = try NSJSONSerialization.JSONObjectWithData(data, options:NSJSONReadingOptions.MutableContainers) as? NSDictionary {
callback(response)
}
} catch let error as NSError {
print("json error: \(error.localizedDescription)")
}
}
task.resume()
}

Swift - Returning a JSON object from API call in Model as Dictionary to use in View Controller

I have recently started experimenting with Swift and am new to more strongly typed programming languages.
I am trying to build a basic API call to http://openweathermap.org/api which will have a searchbox in the UIView that takes a city name and returns the relevant weather data.
My problem is figuring out how to return the JSON response I get back from my API call in my Model as a Dictionary that I can then use as a variable in my ViewController.
I have experimented with a variety of methods but continue to get a 'Dictionary not convertible to Void' error. From research and this article (Dictionary is not convertible to Void) it seems returning a closure might offer the answer but I am struggling to implement given that I only want to pass a cityname string parameter in my ViewController searchButton function.
Detailed code snippets below, thanks for help!
My API call in Model below which currently works at pulling down JSON object
class API {
func weatherSearch(#urlSearch: String) -> Dictionary<String,AnyObject>
{
let urlPath = "http://api.openweathermap.org/data/2.5/weather?q=" + urlSearch
let url = NSURL(string: urlPath)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url!, completionHandler: {data, response, error -> Void in
println("Task completed")
if(error != nil) {
// If there is an error in the web request, print it to the console
println(error.localizedDescription)
}
var err: NSError?
if let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as? NSDictionary {
var dataOut = jsonResult as Dictionary<String,AnyObject>
return dataOut
//omitted some additional error handling code
}
})
task.resume()
}
}
My ViewController where instantiate API and take input from Searchfield
#IBOutlet weak var searchField: UITextField!
#IBAction func searchButton() {
let api = API()
var dataOut = api.weatherSearch(urlSearch: searchField.text!)
println(dataOut)
self.performSegueWithIdentifier("Search", sender: nil)
}
Using the callback technique as hinted to by the comment above, try something like this
func weatherSearch(#urlSearch: String, callback: (Dictionary<String,AnyObject> -> ())) {
let urlPath = "http://api.openweathermap.org/data/2.5/weather?q=" + urlSearch
let url = NSURL(string: urlPath)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url!, completionHandler: {data, response, error -> Void in
println("Task completed")
if(error != nil) {
// If there is an error in the web request, print it to the console
println(error.localizedDescription)
}
var err: NSError?
if let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as? NSDictionary {
var dataOut = jsonResult as! Dictionary<String,AnyObject>
callback(dataOut)
//omitted some additional error handling code
}
})
task.resume()
}
weatherSearch(urlSearch: "endpoint here") { dictionary in
println(dictionary)
}

Delay in displaying data on tableView in ios swift

Hi,
I'm trying to parse data on to the listview and am able to get it and
display it on the tableView but the problem is it is taking hell lot
of time to display it on the tableview. Please find the my code below.
func jsonParsing()
{
activityIndicatorView.startAnimating()
let session = NSURLSession.sharedSession()
let request = NSMutableURLRequest (URL: deviceListURL)
request.HTTPMethod = "GET"
let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
if error != nil {
// If there is an error in the web request, print it to the console
println(error.localizedDescription)
}
var err: NSError?
if(data != nil) {
var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as! NSMutableArray
//println("Data: \(jsonResult)")
var dataDict: NSDictionary
for dataDict : AnyObject in jsonResult {
var device_id: NSString = dataDict.objectForKey("deviceId") as! NSString
var device_name: NSString = dataDict.objectForKey("deviceName") as! NSString
var device_status: NSInteger = dataDict.objectForKey("status") as! NSInteger
let dictionary = [self.deviceID: device_id, self.deviceName: device_name, self.Status: device_status]
self.myObject.addObject(dictionary)
}
println("My object = %#", self.myObject)
println(self.myObject.count)
if self.myObject.count != 0 {
self.reloadTable()
}
}
if err != nil {
// If there is an error parsing JSON, print it to the console
println("JSON Error \(err!.localizedDescription)")
}
})
task.resume()
}
The completion handler is running in a background queue, not the main thread. UI updates have to happen on the main thread, though.
Try calling reloadTable() on the main thread:
dispatch_sync(dispatch_get_main_queue(), {
self.reloadTable()
})
(I just typed this in here untested, so I hope it works this way)

Cannot load JSON from php/mysql in Swift

I'm trying to build an IOS App for my php/mysql website. The problem is I can't get the following code working with my created JSON output. But the same code works with other APIs like :
http://www.telize.com/geoip
Here is my code:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// Playground - noun: a place where people can play
let urlPath = "https://www.example.com/API_OUT.php?API_KEY=785d...e5f5"
let url: NSURL = NSURL(string: urlPath)!
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url, completionHandler: {data, response, error -> Void in
println("Task completed")
if((error) != nil) {
// If there is an error in the web request, print it to the console
println(error.localizedDescription)
}
var err: NSError?
var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSDictionary
if(err != nil) {
// If there is an error parsing JSON, print it to the console
println("JSON Error \(err!.localizedDescription)")
} else {
println(jsonResult)
}
})
task.resume()
}
}
This JSON is an array, not a dictionary (unlike your original JSON, which was a dictionary). Thus your assignment of this new JSON to a dictionary will fail.
I would suggest (a) use NSArray rather than NSDictionary; and (b) use if let ... syntax rather than just let, to gracefully handle these errors in the future.
Thus, that yields:
var parseError: NSError?
if let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &parseError) as? NSArray {
println(jsonResult)
} else {
// If there is an error parsing JSON, print it to the console
println("JSON Error \(parseError?.localizedDescription)")
}

NSURLSessionDataTask does not return data from request

I'm trying to make a request to a server, which should return data that I can use in the rest of my application. Here is my code:
func makeNewUser() -> NSDictionary {
var full_url = getFullUrl("makeNewUser")
var toReturn: NSDictionary = NSDictionary()
var request: NSURLRequest = NSURLRequest(URL:full_url)
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession.sharedSession()
let task : NSURLSessionDataTask = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
println(response)
var err: NSError?
var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSDictionary
if(err != nil) {
// If there is an error parsing JSON, print it to the console
println("JSON Error \(err!.localizedDescription)")
}
toReturn = jsonResult
});
task.resume()
self.delegate?.didReceiveAPIResults(toReturn)
println(toReturn)
return toReturn
}
I am sending toReturn data to a delegate function in the caller, but it is not available. I believe the reason for this is because the request is asynchronous. What is the proper way for me to handle this so that the caller knows to wait for this data before continuing?
move the delegate call into the session completion block:
func makeNewUser() {
var full_url = getFullUrl("makeNewUser")
var toReturn: NSDictionary = NSDictionary()
var request: NSURLRequest = NSURLRequest(URL:full_url)
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession.sharedSession()
let task : NSURLSessionDataTask = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
println(response)
var err: NSError?
var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSDictionary
if(err != nil) {
// If there is an error parsing JSON, print it to the console
println("JSON Error \(err!.localizedDescription)")
}
self.delegate?.didReceiveAPIResults(jsonResult) // <<-----
});
task.resume()
}
And you just have to be aware that the result is not immediately available. You don't want to block the function (and UI) on long running operations like network requests anyway.

Resources