I have a rest api and am getting all data via Json then putting it in a IOS TableView. My issue is that some data is being returned as NULL in Json
"vote_status":null
I am trying to get that NULL value in swift and change it to a string "0" but am having a hard time doing so . I have this so far
if var vote_status = Stream["vote_status"] as? String {
if (vote_status == (vote_status)[NSNull]) {
vote_status = "0"
}
}
However I get this compile error:
Cannot subscript a value of type 'String' with an index of type
'(NSNull).Type' (aka 'NSNull.Type')
I am doing this because nil and null does not seem to work so I can't do this.
if (vote_status == nil) ...
You just need to conditionally cast your dictionary value to String and use the Nil Coalescing Operator ?? to assign "0" in case of failure null:
let vote_status = Stream["vote_status"] as? String ?? "0"
Swift 3.0
func checkNull(obj : AnyObject?) -> AnyObject? {
if obj is NSNull {
return nil
} else {
return value
}
}
object.feature = checkNull(dict["feature"])
try this
vote_status is NSNull
You can try this
func checkForNull(value:AnyObject) -> String
{
if(value as! NSObject == NSNull() || value as! String == "")
{
return " "
}
else
{
return value as! String
}
}
Try something like this:
if let category = Stream["vote_status"] as? String {
print(category)
} else {
print(category)
}
Related
Below is the value from Api response in the form of Json:
isFavorite = true;
This is the way getting it in model class:
declaration:
var isFavorite:Bool = false
init(json:NSDictionary?)
{
if json != nil
{
self.isFavorite = ((json?.object(forKey: "isFavorite")) != nil)
}
}
this way always getting "true"
Earlier tried this way:
self.isFavorite = (json?.object(forKey: "isFavorite") as? Bool ?? false)
this way always getting "false"
I am not getting what is wrong i am doing in parsing this Bool
Update: Api response
isFavorite = true;
All JSON types in Swift are value types. So reference type NSDictionary is discouraged (anyway).
The native Swift way is
let isFavorite : Bool
init(json: [String:Any]) {
self.isFavorite = json["isFavorite"] as? Bool ?? false
}
But from the given (NSDictionary) output isFavorite = true; the value is apparently String. In this case you have to write
let isFavorite : Bool
init(json: [String:Any]) {
if let favorite = json["isFavorite"] as? String, favorite == "true" {
self.isFavorite = true
} else {
self.isFavorite = false
}
}
I am returning String values from API via Swift 4 JSON Codable method.
I know few values are "null" or nil, so to avoid crashes I am trying to implement code. Here is the code giving the subject error (on NSNull comparison):
if Cur[indexPath.row].cap == nil || Cur[indexPath.row].cap == NSNull {
print("Could not find the value")
CapVal = "N/A"
} else {
CapVal = Cur[indexPath.row].cap!
}
The error:
Binary operator '==' cannot be applied to operands of type 'String?' and 'NSNull.Type
I tried to cast it as String too: Cur[indexPath.row].cap as? String still got the same error.
If you are using JSONDecoder, both missing values and values that are explicitly designated as null will be returned as nil:
Consider this JSON:
{"foo": "a", "bar": null}
And this struct:
struct Result: Decodable {
var foo: String
var bar: String?
var baz: String?
}
If you use JSONDecoder, you can just do:
guard let result = try? JSONDecoder().decode(Result.self, from: data) else { ... }
let bar = result.bar ?? "N/A"
I know you were asking about Codable in Swift 4, but just for your reference, if you were using JSONSerialization, though, you could theoretically test for null, because JSONSerialization does return null values as NSNull:
guard let json = (try? JSONSerialization.jsonObject(with: data)) as? [String: Any] else { ... }
let bar = json["bar"]
if bar == nil || bar is NSNull {
// bar was either not found or `null`
} else {
// bar was found and was not `null`
}
Personally, though, I'd just optionally cast to string and use nil coalescing operator if the cast failed, e.g.
let bar = (json["bar"] as? String) ?? "N/A"
But, this is all moot with Swift 4's JSONDecoder.
I am parsing a JSON response and trying to check if one of my keys is null. How would I go about this? I have the following:
var routingNumber = (dic.value(forKey: "result") as! NSDictionary).value(forKey: "routingNumber") as! String
and this returns:
Could not cast value of type 'NSNull' (0x107d238c8) to 'NSString' (0x107329c40).
How would I check if the value is NSNULL?
if( something != NSNULL){
do something
}else{
do something else
}
You can extract value from dic like this.
if let value = (dict["key"] as? String)
{
//NOT NULL
}
else
{
//NULL
}
create below function
func isNsnullOrNil(object : AnyObject?) -> Bool
{
if (object is NSNull) || (object == nil)
{
return true
}
else
{
return false
}
}
call function where you want to check for null or nil value
if isNsnullOrNil((dic.value(forKey: "result") as! NSDictionary).value(forKey: "routingNumber"))
{
print("object is null or nil")
}
else
{
print("object is not null or nil")
}
I had this same problem once.
CHECK FOR IF NSNULL
if let result = dic["result"] as? NSDictionary {
// There is a dictionary
if let routingNumber = result["routingNumber"] as? String {
// There is a routingNumber
}
else if let routingNumber = result["routingNumber"] as? NSNull {
// There is routingNumber but Null
}
else {
// No routingNumber
}
}
That should do the trick.
if let result = dict["result"] as? [String:Any], let routingNumber = result["routingNumber"] as? String {
print("the routingNumber is \(routingNumber)")
} else {
print("nil")
}
I am playing With JSON for last two days and facing alot of curious problems and thanks to stack overflow it helps me. This is JSON featured key has two types of String values.
"featured":"1"
or
"featured": null,
I tried a lot to handle this but failed
Step 1:
if dict.objectForKey("featured") as? String != nil {
featured = dict.objectForKey("featured") as? String
}
Step 2:
let null = NSNull()
if dict.objectForKey("featured") as? String != null {
featured = dict.objectForKey("featured") as? String
}
Step 3:
if dict.objectForKey("featured") as? String != "" {
featured = dict.objectForKey("featured") as? String
}
but unfortunately can't found solution, you answer will be appreciated.
Try This
func nullToNil(value : AnyObject?) -> AnyObject? {
if value is NSNull {
return nil
} else {
return value
}
}
object.feature = nullToNil(dict["feature"])
Here, you can use this method, which will convert null value to nil and wont' cause crash in your app.
You can also use as?
object.feature = dict["feature"] as? NSNumber
Thanks.
Here is a working code, type cast operator(as?) will do the trick here. Null will not be typecasted into String, so the execution will go to failure block.
if let featured = dict["featured"] as? String {
print("Success")
}
else {
print("Failure")
}
Try this!
if let demoQuestion = dict.objectForKey("featured"){
let getValue: String = demoQuestion as! String
}
else {
print("JSON is returning nil")
}
Optional chaining with if let or its counterpart guard let is the way to go. All three steps combined (missing, wrong type - NSNull too, empty string):
guard let featured = dict.objectForKey("featured") as? String where !value.isEmpty else {
print("featured has wrong value")
}
// do what you need to do with featured
If you want to know more about optional chaining check out documentation
Hi you can use below function to remove null to empty string and prevent crashes
func removeNullFromDict (dict : NSMutableDictionary) -> NSMutableDictionary
{
let dic = dict;
for (key, value) in dict {
let val : NSObject = value as! NSObject;
if(val.isEqual(NSNull()))
{
dic.setValue("", forKey: (key as? String)!)
}
else
{
dic.setValue(value, forKey: key as! String)
}
}
return dic;
}
and before giving dict to any method call function in below way
let newdict = self.removeNullFromDict(dict: dict);
i did a static func to convert value from json to optional String.
class Tools{
static func setOptionalStr(value : Any?) -> String?{
guard let string = value as! String?, !string.isEmpty else {
return nil
}
return value as? String
}
}
In my controller
let urlStats: String? = Tools.setOptionalStr(value: json["UrlStats"])
i'm open to your feedback
I am trying to parse JSON with the following code:
func ltchandler(response: NSURLResponse!, data : NSData!, error : NSError!) { //Is passed the results of a NSURLRequest
if ((error) != nil) {
//Error Handling Stuff
} else {
if (NSString(data:data, encoding:NSUTF8StringEncoding) == "") {
//Error Handling Stuff
} else {
var data = NSData(data: data);
// Define JSON string
var JSONString = "\(data)"
// Get NSData using string
if let JSONData = JSONString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) {
// Parse JSONData into JSON object
var parsingError: NSError?
if let JSONObject = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &parsingError) as? [String: AnyObject] {
// If the parsing was successful grab the rate object
var rateObject: Double! = JSONObject["price"]?.doubleValue
// Make sure the rate object is the expected type
if let rate = rateObject as? Double! { // THIS IS NOT WORKING!!!
//Do stuff with data
} else {
println("Parsing Issue")
}
}
}
}
}
}
The line marked THIS IS NOT WORKING!!! is not being called.
From what I can tell, it cannot cast rateObject as a double - why not? It is not showing any errors.
To clarify, the expected behavior is that a double is created from the JSON object.
To strictly answer your question have you tried printing the rateObject. Also why are you casting to Double! rather than just Double in the problematic line?
Personally I don't use ! in almost all cases. You are better off using either non-optionals or proper optionals.
In the relevent section I would write:
// Make sure the rate object is the expected type
if let rate = JSONObject["price"]?.doubleValue {
//Do stuff with rate
} else {
print("Parsing Issue")
}
Of course if the JSONObject["price"] is not something with a doubleValue method or the method returns nil you will end up with nil and the else case being taken.
the code worked for me, try this code:
// if the value equals nil or any String, the instruction abort the if
// SWIFT 2.0 in xcode beta 5
if let rate = Double((JSONObject["price"] as? String)!){
// insert you code here
} else {
print("error message")
}