Twilio QuickStarter project issue in ios - ios

i have downloaded the twilio quickstarter project and followed the docx and create the function for chat and pass the url to the given place in project, now when i run the app the app crashes with this error,Thread 10: EXC_BREAKPOINT (code=1, subcode=0x1048d85b0). This error comes in their code when it try to seralize the data from the request. How can i get out from this issue?. This is the code where issue is occurring,
struct TokenUtils {
static func retrieveToken(url: String, completion: #escaping (String?, String?, Error?) -> Void) {
if let requestURL = URL(string: url) {
let session = URLSession(configuration: URLSessionConfiguration.default)
let task = session.dataTask(with: requestURL, completionHandler: { (data, response, error) in
if let data = data {
do {
let json = try JSONSerialization.jsonObject(with: data, options: []) as! [String:String]
let token = json["token"]
let identity = json["identity"]
completion(token, identity, error)
}
catch let error as NSError {
completion(nil, nil, error)
}
} else {
completion(nil, nil, error)
}
})
task.resume()
}
}
}
This is what it shows in debugger,

Related

How to download a .zip file in Swift without NSURLSession?

I'm trying to download a zip file to the user's phone storage in an iOS app. Is it possible to do this without NSURLSession?
Yes, there are multiple tools but you should still try and use URL session.
A very easy way to do this is using Data. But it blocks your thread so you need to work a bit with queues to make it work properly (Otherwise your app MAY crash).
A very simple, non-safe, thread-blocking way would be:
func saveFile(atRemoteURL remoteURL: URL, to localURL: URL) {
let data = try! Data(contentsOf: remoteURL)
try! data.write(to: localURL)
}
But doing it a bit more stable should look something like this:
private func downloadIteam(atURL url: URL, completion: ((_ data: Data?, _ error: Error?) -> Void)?) {
let queue = DispatchQueue(label: "downloading_file")
queue.async {
do {
let data = try Data(contentsOf: url)
completion?(data, nil)
} catch {
completion?(nil, error)
}
}
}
private func saveDataToDocuments(_ data: Data, to: String, completion: ((_ resultPath: URL?, _ error: Error?) -> Void)?) {
let path = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent(to)
let queue = DispatchQueue(label: "saving_file")
queue.async {
do {
let folderPath: String = path.deletingLastPathComponent().path
if !FileManager.default.fileExists(atPath: folderPath) {
try FileManager.default.createDirectory(atPath: folderPath, withIntermediateDirectories: true, attributes: nil)
}
try data.write(to: path)
completion?(path, nil)
} catch {
completion?(nil, error)
}
}
}
public func downloadFileAndSaveItToDocuments(urlToRemoteFile: URL, completion: #escaping (_ file: (relativePath: String, fullPath: URL)?, _ error: Error?) -> Void) {
let fileName = urlToRemoteFile.lastPathComponent
let relativePath = "downloads/" + fileName
func finish(fullPath: URL?, error: Error?) {
DispatchQueue.main.async {
if let path = fullPath {
completion((relativePath, path), error)
} else {
completion(nil, error)
}
}
}
downloadIteam(atURL: urlToRemoteFile) { (data, error) in
guard let data = data else {
completion(nil, error)
return
}
saveDataToDocuments(data, to: relativePath) { (url, saveError) in
finish(fullPath: url, error: saveError ?? error)
}
}
}
I hope the code is self-documented enough.

Parse image from web json

I have a json file that looks something like this:
{
"adTitle": "My Title",
"adURL": "https://mylink.com/",
"adImageURL": "http://mywebsite/bannerx#3x.png"
}
I get the JSON value from website: http://mywebsite.com/file.json
The problem is that the ad somehow doesn't load the adImageURL, so when I press the UIImageView, but when I press the area that then UIImageView should be, it open my adURL. This is the code I use for JSON:
var imageURL:String = "http://mywebsite/bannerx#3x.png"
var adURL:String = "https://mylink.com/"
func loadAdvertisement() {
// Set up the URL request
let todoEndpoint: String = "http://mywebsite.com/file.json"
guard let url = URL(string: todoEndpoint) else {
print("Error: cannot create URL")
return
}
let urlRequest = URLRequest(url: url)
// set up the session
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
// make the request
let task = session.dataTask(with: urlRequest) {
(data, response, error) in
// check for any errors
guard error == nil else {
// print("error calling GET on /todos/1")
// print(error!)
return
}
// make sure we got data
guard let responseData = data else {
print("Error: did not receive data")
return
}
// parse the result as JSON, since that's what the API provides
do {
guard (try JSONSerialization.jsonObject(with: responseData, options: []) as? [String: AnyObject]) != nil else {
print("error trying to convert data to JSON")
return
}
let json = try JSONSerialization.jsonObject(with: responseData, options:.allowFragments) as! [String:AnyObject]
if (json != nil) {
self.imageURL = (json["adImageURL"] as? String)!
self.adURL = (json["adURL"] as? String)!
print(self.imageURL)
print(self.adURL)
DispatchQueue.main.async { () -> Void in
self.loadAdImage(self.imageURL)
}
}
} catch {
print("error trying to convert data to JSON")
return
}
}
task.resume()
// let jsonURL = URL(string: "http://mywebsite.com/file.json")
// self.getDataFromUrl(jsonURL!, completion: (data:Data?, response:URLResponse?, error:Error?)) -> Void
}
func loadAdImage(_ url:String) {
getDataFromUrl(URL(string: url)!) { (data, response, error) in
DispatchQueue.main.async { () -> Void in
guard let data = data, error == nil else { return }
print(response?.suggestedFilename ?? "")
print("Download Finished")
self.advertImageView.image = UIImage(data: data)
}
}
}
func getDataFromUrl(_ url:URL, completion: #escaping ((_ data: Data?, _ response: URLResponse?, _ error: NSError? ) -> Void)) {
URLSession.shared.dataTask(with: url) { (data:Data?, response:URLResponse?, error:Error?) in
completion(data, response, error as NSError?)
}.resume()
}
In the event LOG, is prints out both of the print("error trying to convert data to JSON") commands. I have used this code before in my project, and it worked just fine, but I have no idea why it wont work anymore.
Add the message to catch and check what actually error you are getting like this way:
do {
let json = try JSONSerialization.jsonObject(with: responseData, options:.allowFragments) as! [String:AnyObject]
} catch let message {
print("error trying to convert data to JSON" + "\(message)")
return
}

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 3: not working with completion handler in iOS

I have created one function using completion handler in NSObject class for consumption of web services. However I am not getting a way to call that function with handler return.
func getUser(url:String, completionHandler: #escaping (NSDictionary?, NSError?) -> ()) {
let config = URLSessionConfiguration.default // Session Configuration
let session = URLSession(configuration: config) // Load configuration into Session
let url = URL(string: url)!
let task = session.dataTask(with: url, completionHandler: {
(data, response, error) in
if error != nil {
completionHandler(nil, error as NSError?)
} else {
do {
if let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [NSDictionary: Any] {
completionHandler(json as NSDictionary?,nil)
}
} catch {
print("error in JSONSerialization")
}
}
})
task.resume()
}
You should make sure that your completionHandler is called in every cases: for example, when the JSONSerialization throws, you catch and print the error, but you're not calling your completionHandler. The same if the JSON result is nil
ADDING
You can handle it in this way:
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [NSDictionary: Any]
completionHandler(json,nil)
} catch(let error) {
print(error)
completionHandler(nil, error)
}

Extra argument 'error' in call. Compilation error in Swift 2.0

I am currently trying to learn about Swift 2.0 and OAuth integration via this sample application: https://github.com/soundcloud/iOSOAuthDemo
The following snippet below is causing me problems and causing the application to fail in its compilation.
private func requestMe(token: String) {
let url = NSURL(string: "https://api.soundcloud.com/me.json?oauth_token=\(token)")!
let request = NSURLRequest(URL: url)
let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration(),
delegate: nil, delegateQueue: NSOperationQueue.mainQueue())
let dataTask = session.dataTaskWithURL(url) { (data, response, error) -> Void in
if let jsonOutput = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: nil) as? [String:AnyObject] {
self.displayMe(jsonOutput)
}
}
dataTask.resume()
}
However when compiling my error handling looks as though it has changed in this version of Swift (2.0) and is causing the following error:
Extra argument 'error' in call with the compilation.
I have reviewed the following stack posting on this issue: Swift: Extra argument 'error' in call
and adjusted my code to try and correct the error handling as such:
let dataTask = session.dataTaskWithURL(url) { (data, response, error) -> Void in
if let jsonOutput = NSJSONSerialization.JSONObjectWithData(data, options: nil) as? [String:AnyObject] {
self.displayMe(jsonOutput)
}
}
catch let error as NSError {
print(error);}
dataTask.resume()
}
I have also tried changing:
(data, options: nil, error: nil)
to
(data:NSData?, error:NSError?)
However neither of these resolving the issue. Can someone guide me as to what is probably a silly mistake I am making with this error handling.
Thanks in advance!,
There were several problems with your code: you added catch but forgot do and try. Also you can't pass nil as an option parameter anymore for NSJSONSerialization, and you have to safely unwrap the data optional.
Here's a fixed version:
let dataTask = session.dataTaskWithURL(url) { (data, response, error) -> Void in
do {
if let myData = data, let jsonOutput = try NSJSONSerialization.JSONObjectWithData(myData, options: []) as? [String:AnyObject] {
self.displayMe(jsonOutput)
}
} catch let error as NSError {
print(error)
}
}
dataTask.resume()

Resources