Reputation: 101
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
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
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
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
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
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
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