Alan Tingey
Alan Tingey

Reputation: 971

Old Swift to Swift 3

A while back I created a function to take a json and print it to the terminal. It worked perfectly but it was two years ago so when I have copied it in for my latest project it is full of errors :/ I have resolved most of them but I still have two outstanding issues as follows:

var arr = JSONSerialization.JSONObjectWithData(data!, options: nil, error: nil) as! NSArray

The above line complains about "Extra Argument 'error' in call.

for var i = 0 ; i < (arr as NSArray).count ; i += 1

The above line says "C-Style for statement has been removed in swift 3"

Any help on resolving these two would be great.

Full Function Code Below:

func jsonParsing()
{

    let prefs:UserDefaults = UserDefaults.standard
    var webaddress = prefs.value(forKey: "WEBADDRESS") as! String


    let url2 = URL(string: webaddress + "straightred/jsonfixture/")

    let data = try? Data(contentsOf: url2!)

    var arr = JSONSerialization.JSONObjectWithData(data!, options: nil, error: nil) as! NSArray

    arrDict = []

    for var i = 0 ; i < (arr as NSArray).count ; i += 1
    {
        arrDict.addObject((arr as NSArray) .objectAtIndex(i))
    }

    print(arrDict);

}

Upvotes: 0

Views: 127

Answers (8)

vadian
vadian

Reputation: 285260

First of all, do not use NSArray in Swift, use Swift native collection types.

Second of all, do not load data synchronously from a remote URL, use URLSession

Third of all, you don't need the loop, just assign the received array to arrDict

  • Declare arrDict as Swift array of dictionaries

    var arrDict = [[String:Any]]()
    
  • This code uses the proper method of UserDefaults and a do - catch block, the options parameter of jsonObject(with can be omitted.

    func jsonParsing()
    {
        let prefs = UserDefaults.standard
        let webaddress = prefs.string(forKey: "WEBADDRESS")!
        let url2 = URL(string: webaddress + "straightred/jsonfixture/")!
    
        let task = URLSession.shared.dataTask(with: url2) { [unowned self] (data, response, error) in
            if let error = error {
                print(error)
                return
            }
            do {
                let arr = try JSONSerialization.jsonObject(with:data!) as! [[String:Any]]
                self.arrDict = arr
                print(self.arrDict)
    
            } catch {
                print(error)
            }
        }
        task.resume()
    }
    

Upvotes: 2

luckyShubhra
luckyShubhra

Reputation: 2751

func jsonParsing()
{

let prefs:UserDefaults = UserDefaults.standard
var webaddress = prefs.value(forKey: "WEBADDRESS") as! String


let url2 = URL(string: webaddress + "straightred/jsonfixture/")

let data = try? Data(contentsOf: url2!)

var arr = try JSONSerialization.jsonObject(with: data!) as! [Any] // if Array of any type, if array of dictionaries cast it to [[String:Any]]

arrDict = []

for value in arr { // instead of iterating over your array you can simply copy it to arrDict. I added for loop for your refernce.
   arrDict.addObject(name) 
 } 
print(arrDict);

}

JSON serialization methods have been updated. C style for loops are deprecated use enumeration to enumerate over your complete array. I wont support using Objective-C classes in your Swift class. Dont caste your arrays to NSArray or NDDictionary.

Upvotes: 0

Berlin
Berlin

Reputation: 2201

In Swift 3, try this code for son parsing




func jsonParsing()(){
    //check if strUrl not nill then enter this block
    if strUrl != nil{


        var request = URLRequest(url: URL(string: strUrl!)!)//get requet from urlRequest
        let session = URLSession.shared //creat session object

        request.httpMethod = "GET" // set http method

        //get data from url using session.datatask methos
        session.dataTask(with: request) {data, response, error in
            if error != nil{
                print(error!.localizedDescription)
                return
            }
            do{
                //get json result and store in dictionary
                let dicJsonResult = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSDictionary
                let arrData = dicJsonResult["data"] as! NSArray // set friend list in array
                self.tblView.reloadData()
            }
            catch
            {
                print(error.localizedDescription)
            }
            }.resume()
    }else{
        print("No more friends")
    }
}

Upvotes: 0

sarosh mirza
sarosh mirza

Reputation: 702

For the first one you need to add do try catch

    do {
    var arr : Array<AnyObject> = JSONSerialization.jsonObject(with: data!)) as! NSArray
    // do your works
    } catch {
    print("Got error: \(error)")
}

For the second one you need to have your for loops in the following way

for i in 0..<arr.count {
  //do your stuff here
}

Upvotes: 1

David Pasztor
David Pasztor

Reputation: 54785

This is your full function in valid Swift 3 syntax.

Be aware that JSONSerialization.jsonObject can now throw. You can just use the for element in collection syntax, you don't need to specify the indexes yourself and the C style for loop has been removed from Swift 3, if you really need a C style for loop, you have to use stride.

Using NSArray is discouraged in Swift, if you really want to use non-explicit types, use Array<Any>, but when possible use explicit types.

Also make sure that you handle the optional unwrapping correctly and when using force unwrapping/force casting, you won't get a runtime error.

func jsonParsing(){

    let prefs:UserDefaults = UserDefaults.standard
    var webaddress = prefs.value(forKey: "WEBADDRESS") as! String


    let url2 = URL(string: webaddress + "straightred/jsonfixture/")

    let data = try? Data(contentsOf: url2!)

    var arr = (try? JSONSerialization.jsonObject(with: data!)) as! NSArray

    var arrDict = [Any]()

    for current in arr {
        arrDict.append(current)
    }

    print(arrDict)

}

Upvotes: 0

mag_zbc
mag_zbc

Reputation: 6992

JSONSerialization no longer takes an error reference as aparameter, now it throws exception

var arr : Array<AnyObject> = try JSONSerialization.jsonObject(with: data, options: nil)

As for the loop, the C-style loops were completely removed in Swift 3 so use

for object in arr {
    // do stuff
}

or

for i in 0<..arr.count {
    // do stuff
}

Upvotes: 1

Jaydeep Vora
Jaydeep Vora

Reputation: 6223

Swift 3.1

for JSON serialization try like this:

 do {
       var arr = try  JSONSerialization.jsonObject(with: data, options: []) as! NSArray

   } catch {

  }

for Loop syntax use like this

 for i in 0..<arr.count {
         // Do your stuff       
 }

Upvotes: 0

Alex Ioja-Yang
Alex Ioja-Yang

Reputation: 1533

For loop format:

for i in 0..<arr.count {
    ...code here...
} 

Upvotes: 0

Related Questions