Swift to Swift 2 and Cannot Invoke error. What is wrong? - ios

I am using an API that provided the following code that is supposed to provide the song currently playing on the radio station.
func getSongs() {
let url = NSURL(string: "http://api.vicradio.org/songs/current")!
let request = NSMutableURLRequest(URL: url)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request) { (data: NSData!, response: NSURLResponse!, error: NSError!) in
if error != nil {
// Handle error...
return
}
println(error)
println(response)
println(NSString(data: data, encoding: NSUTF8StringEncoding))
}
task.resume()
}
This code was written for Swift 1 I believe. I'm getting an error that says:
Cannot invoke "dataTaskWithRequest" with an argument of list type "NSMutableURLRequest, (NSData!, NSURLResponse!, NSError!) -> _ "
I'm rather new to Swift, so maybe someone could explain how I could correct this error?

Change:
(data: NSData!, response: NSURLResponse!, error: NSError!)
to:
(data: NSData?, response: NSURLResponse?, error: NSError?)

Related

SWIFT: session.dataTaskWithURL

I am trying to follow a tutorial on Swift, but the code does not work in Swift 3. Can anyone help update the code?
let url = NSURL(string: path)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url!) {
(data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
print(">>>>> \(data)")
}
I have tried following the suggestions by the compiler, and have changed several of the keywords. The code now looks like this:
let url = NSURL(string: path)
let session = URLSession.shared
let task = session.dataTaskWithURL(url! as URL) {
(data: NSData?, response: URLResponse?, error: NSError?) -> Void in
print(">>>>> \(data)")
}
The error message is:
Cannot convert value of type '(NSData?, URLResponse?, NSError?) -> Void' to expected argument type '(Data?, URLResponse?, Error?) -> Void'
Source Tutorial: Build a simple weather App https://www.youtube.com/watch?v=AoYTuhWZFqM&list=PLoN_ejT35AEjBQ33-L8h2IwG11amXssGk#t=540.527064
let url = URL(string:path)
let session = URLSession.shared
let task = session.dataTask(with: url!) { (data:Data?, response:URLResponse?, error:Error?) in
print()
}

I cannot fix EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) in Swift xcode 8.1 on Json

I am studying the swift and I update the xcode to current version (8.1). So the source that I saved was changed. When I ran the code. It cracked and I cannot fixed it. It showed "EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)" on the last line. This is a code that I have studied from web.
Thank you very much.
let urlString = "http://swapi.co/api/people/1/"
let session = URLSession.shared
let url = URL(string: urlString)!
session.dataTask(with: url, completionHandler: { (data: Data?, response:URLResponse?, error: NSError?) -> Void in
if let responseData = data {
do {
let json = try JSONSerialization.jsonObject(with: responseData, options: JSONSerialization.ReadingOptions.allowFragments)
if let dict = json as? Dictionary<String, AnyObject> {
if let name = dict["name"] as? String, let height = dict["height"] as? String, let birth = dict["birth_year"] as? String, let hair = dict["hair_color"] as? String {
let person = SWPerson(name: name, height: height, birthYear: birth, hairColor: hair)
print(person.name)
print(person.height)
print(person.hairColor)
print(person.birthYear)
if let films = dict["films"] as? [String] {
for film in films {
print(film)
}
}
}
}
} catch {
print("Could not serialize")
}
}
} as! (Data?, URLResponse?, Error?) -> Void) .resume()
You can save much time if you simply read the documentation
Press ⇧⌘0 (zero, not O)
Type dataTask, select dataTask(with:completionHandler:) and press return.
You will get
func dataTask(with url: URL,
completionHandler: #escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask
Do you see the slightly difference in the error parameter?
So the correct syntax in your code is
session.dataTask(with: url, completionHandler: { (data: Data?, response:URLResponse?, error: Error?) -> Void in
...
}).resume()
There is no type cast at the end.
Further the type annotations in the completion block are not needed because the compiler infers the types. The error doesn't occur if you just write
session.dataTask(with: url, completionHandler: { (data, response, error) in
...
}).resume()
The shortest form is using the trailing closure syntax
session.dataTask(with: url) { (data, response, error) in
...
}.resume()

Swift 1.2 to swift 2: Cannot convert value of type to expected argument type

I'm trying to create a NSURLSession task based on a tutorial I found online (https://www.raywenderlich.com/85528/user-accounts-ios-ruby-rails-swift#next_section) and I am getting the following error:
Cannot convert value of type '(NSData!, NSURLResponse!, NSError!) -> ()' to expected argument type '(NSData?, NSURLResponse?, NSError?) -> Void
at this block of code:
let task = session.dataTaskWithRequest(request) { (data: NSData!, response: NSURLResponse!, error: NSError!) in
The function where the issue belongs to can be found here
func sendRequest(request: NSURLRequest, completion:(NSData!, NSError!) -> Void) -> () {
// Create a NSURLSession task
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request) { (data: NSData!, response: NSURLResponse!, error: NSError!) in
if error != nil {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
completion(data, error)
})
return
}
dispatch_async(dispatch_get_main_queue(), { () -> Void in
if let httpResponse = response as? NSHTTPURLResponse {
if httpResponse.statusCode == 200 {
completion(data, nil)
} else {
var jsonerror:NSError?
if let errorDict = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments, error:&jsonerror) as? NSDictionary {
let responseError : NSError = NSError(domain: "HTTPHelperError", code: httpResponse.statusCode, userInfo: errorDict as? [NSObject : AnyObject])
completion(data, responseError)
}
}
}
})
}
The full code block can be found here (https://codeshare.io/uJPcX) at line 68.
Change
data:NSData!, response: NSURLResponse!, error: NSError!
to
data: NSData?, response: NSURLResponse?, error: NSError?
when using data or response etc further down you may have to write is as data! to unwrap the variable, but be careful because if the variable is nil it will crash, so you must check that it is not nil first

Extra argument 'completionHandler' in call with NSURLSession.sharedSession()

I'm new to swift, I am trying to make a weather app in IOS using swift,
When I the NSURLSession and NSURLSession.sharedSession(), I cant run the app its showing this Extra argument 'completionHandler' in call, What may the cause of this error?
my code:
let sharedSession = NSURLSession.sharedSession()
let downloadTask: NSURLSessionDownloadTask = sharedSession.downloadTaskWithURL(forecastURL, completionHandler:
{ (location: NSURL!, response: NSURLResponse!, error: NSError!) -> Void! in
println(response)
})
downloadTask.resume()
Use dataTaskWithRequest.
Here is a sample how i download image
var dowloadTask = session.dataTaskWithRequest(urlRequest, completionHandler: { (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void in
// data to image
let image = UIImage(data: data)
if image != nil {
// do some stuff
// preview
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.image = image
})
}
})
dowloadTask.resume()
let sharedSession = NSURLSession.sharedSession()
let url = NSURL(string: "")
let task = sharedSession.downloadTaskWithURL(url!, completionHandler: {(location: NSURL!, response: NSURLResponse!, error: NSError!) in
println("Task completed")
})
task.resume()

Swift: How to pass in a closure as a function argument

I'm trying to figure out the syntax for passing in a closure (completion handler) as an argument to another function.
My two functions are:
Response Handler:
func responseHandler(response: NSURLResponse!, data: NSData!, error: NSError!) -> Void {
var err: NSError
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
println("AsSynchronous\(jsonResult)")
}
Query Function
public func queryAllFlightsWithClosure( ) {
queryType = .AllFlightsQuery
let urlPath = "/api/v1/flightplan/"
let urlString : String = "http://\(self.host):\(self.port)\(urlPath)"
var url : NSURL = NSURL(string: urlString)!
var request : NSURLRequest = NSURLRequest(URL: url)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler:responseHandler)
}
I'd like to modify the Query to something like:
public fund queryAllFlightsWithClosure( <CLOSURE>) {
so that I can externally pass the closure into the function. I know there is some support for training closures but I"m not sure if thats the way to go either. I can't seem to get the syntax correct...
I've tried:
public func queryAllFlightsWithClosure(completionHandler : {(response: NSURLResponse!, data: NSData!, error: NSError!) -> Void} ) {
but it keeps giving me an error
It might help defining a type alias for the closure:
public typealias MyClosure = (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void
that makes the function signature "lighter" and more readable:
public func queryAllFlightsWithClosure(completionHandler : MyClosure ) {
}
However, just replace MyClosure with what it is aliasing, and you have the right syntax:
public func queryAllFlightsWithClosure(completionHandler : (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void ) {
}
OOPS nevermind...
public func queryAllFlightsWithClosure(completionHandler : (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void ) {
took out the {} and it seems to work?

Resources