0

I currently have been looking ay many similar questions. However most of them are outdated using old versions of swift. Such as these:

Swift: Testing optionals for nil

swift how can I check for NULL values coming from Json

Value type of "Any" has no member 'objectforKey' Swift 3 conversion

How to retrieve a value from JSON Object Swift 4

I have found several questions that are more relevant however the problems addressed are very specific.

In theory the operation seems very simple. If a value is null change it to empty string ""

Here is a sample of the data I am working with:

{
  "waybill" : "",
  "city" : "",
  "name" : "TESTING ",
  "external_branch" : "",
  "address" : "",
  "name_from" : "",
  "date" : "2018-09-14",
  "province" : "",
  "dept" : "A\/P",
  "signature" : "",
  "name_to" : "",
  "trans_num" : 11,
  "created_user" : "jsilvest",
  "modified_datetime" : "0000-00-00 00:00:00",
  "signature_timestamp" : "0000-00-00 00:00:00",
  "mail_type" : "",
  "comments" : null,
  "received_name" : "TESTING",
  "modified_user" : "",
  "created_datetime" : "2018-09-14 14:03:18",
  "country" : ""
}

Notice how comments is null and not an empty string "".

There are many more data sets in the same format with the same outcome of comments null.

This is causing my app to crash and I am trying to create a conditional to change the null value to "".

Here are some of my attempts:

let updateJson:String  = jsonData[IndexPath][forKey:"customer"] as! String // ERROR cannot convert type of any object

if jsonData(forKey: "comments") == NSNull {
     //ERROR Cannot call value of non function type 'json'
}

I am beginning to think after reading that using NSDictionary is not the correct method to use.

Here is the function I use to query the API for the JSON data.

static func queryAPI(query: String, completionHandler: @escaping (NSDictionary?, Error?) -> ()) -> () {

let url = GlobalVar.API_URL + query
let currentToken = #############

let headers: HTTPHeaders = [
    "Content-Type": "application/json",
    "Source": "########",
    "Authorization": "########" + currentToken
]

print("currentToken: \(currentToken)")

Alamofire.request(url, headers: headers).responseJSON { response in
    switch response.result {
    case .success(let value):
        let jsonData = value as! NSDictionary
        completionHandler(jsonData, nil)
    case .failure(let error):
        completionHandler(nil, error)
    }

}

}

Any help would be great!

Thanks

EDIT UPDATE ----- SOLVED

Since I am very new to IOS and swift development. I have created a melting pot of incorrect use of NSDictionary as mentioned in Ashely Mills answer. Unknown to me at the time that this is an incorrect way and error prone.

When loading the json data i had into my table using the code below:

        for (_, value) in jsonData["data"] {
            self.mail.append(Mailing(transnum: value["trans_num"].int!, from: value["name_from"].string!, to: value["name_to"].string!, department: value["dept"].string!, trackingId: value["waybill"].string!, receivedDate: value["date"].string!, deliveryDate: value["date"].string!, comments: value["comments"].string!, signedFor: false, signature: value["signature"].string!, expanded: false))
        }

I was receiving an error :Unexpectedly found null while unwrapping. As stated above this is due to the null value produced by comments in the json.

In order for me to avoid restructuring my entire app which I have built incorrectly using NSDictionary.

I attempted to create loops and checks to change the null data to an empty string. After hours of trying and no success due to NSDictionary I was able to solve the problem with a simple solve :

From the code above the line here inside the for

comments: value["comments"].string!

changed to

comments: value["comments"].stringValue

Gets rid of my error and the data loads successfully.

Julian Silvestri
  • 1,970
  • 1
  • 15
  • 33

1 Answers1

0

OK, firstly don't use NSDictionary (or NSArray) in Swift, you're throwing away type information.

So you should be saying…

let jsonData = value as! [String: Any]
completionHandler(jsonData, nil)

Then to check for a value in a dictionary…

let comments = jsonData["comments"]

and then

NSNull is the class, so you either need to test…

if comments is NSNull

or

if comments == NSNull() // instance of NSNull
Ashley Mills
  • 50,474
  • 16
  • 129
  • 160
  • Could you elaborate your answer more? After adding in your suggestion I get: Cannot call value of non-function type 'JSON' – Julian Silvestri Sep 17 '18 at 19:56
  • You have more problems than finding `NSNull` values - it sounds like you don't know what your object types are or how to get a value from a dictionary. I've update my answer. – Ashley Mills Sep 17 '18 at 20:04
  • What should I use instead of NSDictionary or NSArray? Sorry still new to swift and IOS. Yes there are lots of problems! thank you for providing some help, I will be working through it – Julian Silvestri Sep 17 '18 at 20:19
  • Use Swift `Dictionary` and `Array`. These are key types and you won't go far without them. Please find and read the relevant Apple docs. – Ashley Mills Sep 17 '18 at 20:19
  • 1
    I was able to solve my issue. Check edit. Thank you for taking the time to help – Julian Silvestri Sep 19 '18 at 16:05