Chirag Hirpara
Chirag Hirpara

Reputation: 101

How to remove a string containing "<null>" from an NSDictionary

I have dictionary of user information, that is getting filled from web service. There are some fields that content is private so it contains NULL. How do I convert value to an empty string wherever there is the value null as in dictionary below:

{
"about_me" = "<null>";
"contact_number" = 123456798798;
"display_name" = "err";
followers = 0;
following = 4;
gender = "-";
posts = 0;
"user_id" = 18;
username = charge;
website = "<null>";
}

Upvotes: 1

Views: 4195

Answers (6)

Anita Nagori
Anita Nagori

Reputation: 747

In swift-4 rather then remove you can replace null values to empty string by using following method

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);

Upvotes: 0

Rashesh Bosamiya
Rashesh Bosamiya

Reputation: 629

Swift 3.0/4.0 Solution

Following is the solution, when JSON have sub-dictionaries. This will go-through all the dictionaries, sub-dictionaries of JSON and remove NULL(NSNull) key-value pair from the JSON.

extension Dictionary {

    func removeNull() -> Dictionary {
        let mainDict = NSMutableDictionary.init(dictionary: self)
        for _dict in mainDict {
            if _dict.value is NSNull {
                mainDict.removeObject(forKey: _dict.key)
            }
            if _dict.value is NSDictionary {
                let test1 = (_dict.value as! NSDictionary).filter({ $0.value is NSNull }).map({ $0 })
                let mutableDict = NSMutableDictionary.init(dictionary: _dict.value as! NSDictionary)
                for test in test1 {
                    mutableDict.removeObject(forKey: test.key)
                }
                mainDict.removeObject(forKey: _dict.key)
                mainDict.setValue(mutableDict, forKey: _dict.key as? String ?? "")
            }
            if _dict.value is NSArray {
                let mutableArray = NSMutableArray.init(object: _dict.value)
                for (index,element) in mutableArray.enumerated() where element is NSDictionary {
                    let test1 = (element as! NSDictionary).filter({ $0.value is NSNull }).map({ $0 })
                    let mutableDict = NSMutableDictionary.init(dictionary: element as! NSDictionary)
                    for test in test1 {
                        mutableDict.removeObject(forKey: test.key)
                    }
                    mutableArray.replaceObject(at: index, with: mutableDict)
                }
                mainDict.removeObject(forKey: _dict.key)
                mainDict.setValue(mutableArray, forKey: _dict.key as? String ?? "")
            }
        }
        return mainDict as! Dictionary<Key, Value>
    }
 }

Upvotes: 1

Meseery
Meseery

Reputation: 1855

A more advanced solution :

@interface NSObject (NULLValidation)
- (BOOL)isNull ;
@end

@implementation NSObject (NULLValidation)

- (BOOL)isNull{
    if (!self) return YES;
    else if (self == [NSNull null]) return YES;
    else if ([self isKindOfClass:[NSString class]]) {
        return ([((NSString *)self)isEqualToString : @""]
                || [((NSString *)self)isEqualToString : @"null"]
                || [((NSString *)self)isEqualToString : @"<null>"]
                || [((NSString *)self)isEqualToString : @"(null)"]
                );
    }
    return NO;

}
@end


@interface NSDictionary (NullReplacement)
- (NSDictionary *) dictionaryByReplacingNullsWithString:(NSString*)string;
@end

@implementation NSDictionary (NullReplacement)

- (NSDictionary *) dictionaryByReplacingNullsWithString:(NSString*)string {
     NSMutableDictionary *replaced = [NSMutableDictionary dictionaryWithDictionary: self];

     NSString *blank = string;

    [self enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        if ([obj isNull]) {
            [replaced setObject:blank forKey: key];
        }
        else if ([obj isKindOfClass: [NSDictionary class]]) {
            [replaced setObject: [(NSDictionary *) obj dictionaryByReplacingNullsWithString:string] forKey: key];
        }
    }];

    return replaced ;
}
@end

Upvotes: 3

Jonathan.
Jonathan.

Reputation: 55544

The simplest way to do this is to loop through a mutable copy of the dictionary and if the value is
null set the value to the value you want.

NSMutableDictionary *mutableDict = [dict mutableCopy];
for (NSString *key in [dict allKeys]) {
    if ([dict[key] isEqual:[NSNull null]]) {
        mutableDict[key] = @"";//or [NSNull null] or whatever value you want to change it to
    }
}
dict = [mutableDict copy];

If the value in the dictionary is actually "<null>", replace the conditional with [dict[key] isEqualToString:@"<null>"]

(assuming you're using ARC, otherwise you need to release the copy'd dictionaries)

Upvotes: 3

Rukshan
Rukshan

Reputation: 8066

You have an Dictionary not an array. Maybe you have an array of dictionaries. Enumerate through the array and do the null check for each dictionary's Key Value pairs.

You have a parsed NSDictionary probably from a JSON repsonse. Probably the JSON contains null values, and the JSON parser you're using turns null into [NSNull null], and it doesn't work if you're trying to compare a string against that NSNull. In this case, try this:

if ([yourDictionary objectForKey:@"website"]== [NSNull null]) {
    // handle here
}

Upvotes: 0

LombaX
LombaX

Reputation: 17364

First of all, "<null>" is not a valid JSON null value.
Written it that way, it is simply a string containing the word <null>

In JSON, null is written in this way.

{ "value": null }

So, if you can't update your web service to return valid json, I suggest you to do a replace on the JSON string in the first instance. Then when you have valid JSON null values, simply handle it with NSJSONSerialization

NSString *json = @"{ \"value\": null }";
NSError *error = nil;
id jsonObject = [NSJSONSerialization JSONObjectWithData:[json dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:&error];

NSLog(@"%@", jsonObject);

This prints

2014-07-16 10:31:36.737 MacUtilities[30760:303] {
    value = "<null>";
}

And debugging the class of value

po [[jsonObject objectForKey:@"value"] class];
NSNull

This because NSJSONSerialization handles null correctly, turning it into an NSNull instance

Upvotes: 1

Related Questions