I am receiving the error: Use of unresolved identifier 'json'
from this line: if let parseJSON = json {
This is the snippet of the code relevant to the error
let task = NSURLSession.sharedSession().dataTaskWithRequest(request){
data, response, error in
if error != nil {
print("error=\(error)")
return
}
do {
if let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary {
print(jsonResult)
}
} catch let error as NSError {
print(error.localizedDescription)
}
if let parseJSON = json {
var resultValue:String = parseJSON["status"] as String!;
print("Result: \(resultValue)")
if(resultValue=="Success")
{
//Login is sucessful
NSUserDefaults.standardUserDefaults().setBool(true,forKey:"isUserLoggedIn");
NSUserDefaults.standardUserDefaults().synchronize()
self.dismissViewControllerAnimated(true, completion: nil)
}
}
}
task.resume()
}
}
I reviewed this problem: Swift : Use of unresolved identifier 'json' but I do not know how I can fix my issue or where to put the variable of json
I think you meant to write if let parseJSON = jsonResult but anyways that is not gonna work either since the variables declared in the do are only visible at that scope. you need to move relevant code inside the do. You can assign the result of JSONSerialization directly to parsJSON.
You should also change this line var resultValue:String = parseJSON["status"] as String! to var resultValue:String = parseJSON["status"] as! String
Modify your code like this:
let task = NSURLSession.sharedSession().dataTaskWithRequest(request){
data, response, error in
if error != nil {
print("error=\(error)")
return
}
do {
if let parseJSON = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary {
print(parseJSON)
let resultValue:String = parseJSON["status"] as! String
print("Result: \(resultValue)")
if(resultValue=="Success")
{
//Login is sucessful
NSUserDefaults.standardUserDefaults().setBool(true,forKey:"isUserLoggedIn");
NSUserDefaults.standardUserDefaults().synchronize()
self.dismissViewControllerAnimated(true, completion: nil)
}
}
} catch let error as NSError {
print(error.localizedDescription)
}
}
task.resume()
}
}
Related
i did read a lot about functions with completion-handler, but now i have a problem how to call this function (downloadJSON) in the correct way. Which parameters do i have to give in the function and handle the result-data (json) in my own class, where the function was called.
This is the code from David Tran. Hi makes wonderful tutorials, but in the code there is no call of this function.
let request: URLRequest
lazy var configuration: URLSessionConfiguration = URLSessionConfiguration.default
lazy var session: URLSession = URLSession(configuration: self.configuration)
typealias JSONHandler = (JSON?, HTTPURLResponse?, Error?) -> Void
func downloadJSON(completion: #escaping JSONHandler)
{
let dataTask = session.dataTask(with: self.request) { (data, response, error) in
// OFF THE MAIN THREAD
// Error: missing http response
guard let httpResponse = response as? HTTPURLResponse else {
let userInfo = [NSLocalizedDescriptionKey : NSLocalizedString("Missing HTTP Response", comment: "")]
let error = NSError(domain: DANetworkingErrorDomain, code: MissingHTTPResponseError, userInfo: userInfo)
completion(nil, nil, error as Error)
return
}
if data == nil {
if let error = error {
completion(nil, httpResponse, error)
}
} else {
switch httpResponse.statusCode {
case 200:
// OK parse JSON into Foundation objects (array, dictionary..)
do {
let json = try JSONSerialization.jsonObject(with: data!, options: []) as? [String : Any]
completion(json, httpResponse, nil)
} catch let error as NSError {
completion(nil, httpResponse, error)
}
default:
print("Received HTTP response code: \(httpResponse.statusCode) - was not handled in NetworkProcessing.swift")
}
}
}
dataTask.resume()
}
Let Xcode help you. Type downlo and press return. Xcode completes the function
Press return again and you get the parameters
You have to replace the placeholders with parameter names for example
downloadJSON { (json, response, error) in
if let error = error {
print(error)
} else if let json = json {
print(json)
}
}
Note:
There is a fatal type mismatch error in your code: The result of the JSONSerialization line is [String:Any] but the first parameter of the completion handler is JSON
Hello I am having an error when parsing some JSON in Swift, my error is:
'Invalid conversion from throwing function of type '(_, _, _) throws -> Void' to non-throwing function type '(NSData?, NSURLResponse?, NSError?) -> Void'
I think this is something to do with catching an error somewhere but I cannot figure out where this would go could anyone help me please? Here is my source code:
import UIKit
import CoreData
class MasterViewController: UITableViewController {
var detailViewController: DetailViewController? = nil
override func viewDidLoad() {
super.viewDidLoad()
var appDel: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
var context: NSManagedObjectContext = appDel.managedObjectContext
let url = NSURL(string: "https://www.googleapis.com/blogger/v3/blogs/10861780/posts?key=AIzaSyBwmI4AzMnBmr7oSVeL0EHdzMjXV1aATnQ")
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url!, completionHandler: { (data, response, error) -> Void in
if error != nil {
print(error)
} else {
//print(NSString(data: data!, encoding: NSUTF8StringEncoding))
do {
let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions(rawValue: 0)) as! NSDictionary
if jsonResult.count > 0 {
if let items = jsonResult["items"] as? NSArray {
for items in items {
print(items)
if let title = items["title"] as? String {
if let content = items["content"] as? String {
var newPost: NSManagedObject = NSEntityDescription.insertNewObjectForEntityForName("Posts", inManagedObjectContext: context)
newPost.setValue(title, forKey: "title")
newPost.setValue(content, forKey: "content")
do {
try context.save()
}
}
}
}
}
}
} catch let error as NSError {
print(error)
}
var request = NSFetchRequest(entityName: "Posts")
request.returnsObjectsAsFaults = false
var results = try context.executeFetchRequest(request)
self.tableView.reloadData()
}
})
task.resume()
}
Thanks!
It looks like you haven't taken care of all the throwing functions using do-try-catch method.
According to the Swift 3 Documentation at https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/ErrorHandling.html
In your case, you seem to have forgotten to take care of the error thrown at var- results. Also, you haven't handled the throwing function session.dataTaskWithURL with a do-try-catch method.
You should not be getting this error if you modify your code as following:
override func viewDidLoad() {
super.viewDidLoad()
var appDel: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
var context: NSManagedObjectContext = appDel.managedObjectContext
let url = NSURL(string: "https://www.googleapis.com/blogger/v3/blogs/10861780/posts?key=AIzaSyBwmI4AzMnBmr7oSVeL0EHdzMjXV1aATnQ")
let session = NSURLSession.sharedSession()
do {
let task = try session.dataTaskWithURL(url!, completionHandler: { (data, response, error) -> Void in
if error != nil {
print(error)
} else {
//print(NSString(data: data!, encoding: NSUTF8StringEncoding))
do {
let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions(rawValue: 0)) as! NSDictionary
if jsonResult.count > 0 {
if let items = jsonResult["items"] as? NSArray {
for items in items {
print(items)
if let title = items["title"] as? String {
if let content = items["content"] as? String {
var newPost: NSManagedObject = NSEntityDescription.insertNewObjectForEntityForName("Posts", inManagedObjectContext: context)
newPost.setValue(title, forKey: "title")
newPost.setValue(content, forKey: "content")
do {
try context.save()
} catch let error1 as NSError { // this is for context.save
print(error1)
}
}
}
}
}
}
}
var request = NSFetchRequest(entityName: "Posts")
request.returnsObjectsAsFaults = false
do{
var results = try context.executeFetchRequest(request)
} catch let error2 as NSError { // this is for context.executeFetchRequest
print(error2)
}
self.tableView.reloadData()
}
})
task.resume()
} catch let error3 as NSError { // this is for session.dataTaskWithURL
print(error3)
}
}
Hope this helps ! Cheers !
I am currently trying to download, parse and print JSON from an URL.
So far I got to this point:
1) A class (JSONImport.swift), which handles my import:
var data = NSMutableData();
let url = NSURL(string:"http://headers.jsontest.com");
var session = NSURLSession.sharedSession();
var jsonError:NSError?;
var response : NSURLResponse?;
func startConnection(){
let task:NSURLSessionDataTask = session.dataTaskWithURL(url!, completionHandler:apiHandler)
task.resume();
self.apiHandler(data,response: response,error: jsonError);
}
func apiHandler(data:NSData?, response:NSURLResponse?, error:NSError?)
{
do{
let jsonData : NSDictionary = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary;
print(jsonData);
}
catch{
print("API error: \(error)");
}
}
My problem is, that the data in
do{
let jsonData : NSDictionary = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary;
print(jsonData);
}
remains empty.
When I debug,the connection starts successfully, with the given url as a parameter. But my jsonData variable doesn't get printed. Instead the catch block throws the error, stating that there is no data in my variable:
API error: Error Domain=NSCocoaErrorDomain Code=3840 "No value."
Can someone please help me with this?
What am I missing?
Thank you all very much in advance!
[Edited after switching from NSURL Connection to NSURLSession]
Here's an example on how to use NSURLSession with a very convenient "completion handler".
This function contains the network call and has the "completion handler" (a callback for when the data will be available):
func getDataFrom(urlString: String, completion: (data: NSData)->()) {
if let url = NSURL(string: urlString) {
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url) { (data, response, error) in
// print(response)
if let data = data {
completion(data: data)
} else {
print(error?.localizedDescription)
}
}
task.resume()
} else {
// URL is invalid
}
}
You can use it like this, inside a new function, with a "trailing closure":
func apiManager() {
getDataFrom("http://headers.jsontest.com") { (data) in
do {
let json = try NSJSONSerialization.JSONObjectWithData(data, options: [])
if let jsonDict = json as? NSDictionary {
print(jsonDict)
} else {
// JSON data wasn't a dictionary
}
}
catch let error as NSError {
print("API error: \(error.debugDescription)")
}
}
}
I have a tableview. cekilecek_data contains tableview datas. I get some datas from JSON and I want to append this datas to tableview. But I have to do this inside of jsonGetir(). However, it does not work. kodJSON and kodlarJSON are nil in viewDidLoad(). Also, cekilecek_data.append(kodJSON[1]) it doesn't add the datas to the table.
How do I fix it?
var cekilecek_data = ["Fenerbahçe", "Chelsea", "Arsenal"]
var kodlarJSON:String = ""
var kodJSON:[String] = []
func jsonGetir(){
let urls = NSURL(string: "http://gigayt.com/mackolik/deneme.php")
let sessions = NSURLSession.sharedSession().dataTaskWithURL(urls!){
data, response, error -> Void in
if (error != nil){ print(error) }
do {
if let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary {
kodlarJSON = jsonResult["kodlar"] as! String //101,102,103
kodJSON = kodlarJSON.componentsSeparatedByString(",")
cekilecek_data.append(kodJSON[1]) //Here doesn't work!
}
}
catch { print(error) }
}
sessions.resume()
}
Reload your tableview after you got data from server this way:
dispatch_async(dispatch_get_main_queue()) {
self.tableView.reloadData()
}
And your final code will be:
func jsonGetir(){
let urls = NSURL(string: "http://gigayt.com/mackolik/deneme.php")
let sessions = NSURLSession.sharedSession().dataTaskWithURL(urls!){
data, response, error -> Void in
if (error != nil){ print(error) }
do {
if let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary {
self.kodlarJSON = jsonResult["kodlar"] as! String //101,102,103
self.kodJSON = self.kodlarJSON.componentsSeparatedByString(",")
self.cekilecek_data.append(self.kodJSON[1]) //Here doesn't work!
}
dispatch_async(dispatch_get_main_queue()) {
self.tableView.reloadData() //Reload tableview here.
}
}
catch { print(error) }
}
sessions.resume()
}
With kodJSON = kodlarJson.componentsseparatedByString(",") you are creating an Array of only one object. Then with cekilecke_data.append(kodJSON[1]) you are trying to append your data with the second object from this array that you have only set one object to.
do {
if let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary {
kodlarJSON = jsonResult["kodlar"] as! String
kodJSON = kodlarJSON.componentsSeparatedByString(",")
// this line sets kodJSON:[String] to ["kodlar"]
cekilecek_data.append(kodJSON[1]) //Here doesn't work!
// this tries to append cekilecek_data from index [1] or second slot of kodJSON which only has one entry
}
}
if you change line to kodlarJSON = jsonResult["kod,lar"] as! String, it would work because kodJSON[1] would equal "lar"
Why am I unable to parse JSON from the HTTP response via the following code?
if let url = NSURL(string: "https://2ch.hk/b/threads.json") {
let task = NSURLSession.sharedSession().dataTaskWithURL(url) {
(data, response, error) in
var jsonError: NSError?
let jsonDict = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &jsonError) as [String: AnyObject]
if jsonError != nil {
return
}
// ...
}
task.resume()
}
Output
fatal error: unexpectedly found nil while unwrapping an Optional value
What am I doing wrong? How can I fix it?
Thanks in advance.
This is a bit late.... but I think you are trying to parse the error as well so add an else part and and the dictionary to be serialized will only be parsed if there is the data ... your code can be modified as follows
if let url = NSURL(string: "https://2ch.hk/b/threads.json") {
let task = NSURLSession.sharedSession().dataTaskWithURL(url) {
(data, response, error) in
if (jsonError != nil) {
return
} else {
var jsonError: NSError?
let jsonDict = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &jsonError) as [String: AnyObject]}
// ...
}
task.resume()
}