Search code examples
iosswiftcastingnsnull

Variable is null when cast


I have a variable content from a NSArray : let content = application["content"]!

When I print content, I have a String : print(content) -> My content

But when I want to cast my variable to String : let content = application["content"]! as! String

I can't print my variable because it's null : print(content) -> Could not cast value of type 'NSNull' (0x1a0507768) to 'NSString' (0x1a0511798).

Why ?

UPDATE :

My array when value is not casted :

{
    "application_title" = "Marina Kaye";
    "application_type" = discussions;
    "application_type_name" = Discussions;
    content =     (
                {
            content = "Le nouvel album de Marina Kaye";
            link = "?message_id=118";
        },
                {
            content = "Son album est num\U00e9ro 1 des";
            link = "?message_id=131";
        },
                {
            content = "Le nouvel album s'appel";
            link = "?message_id=126";
        }
    );
    "content_title" = "Messages utiles";
    "content_type" = "useful_messages";
}

My array when value is casted :

{
    "application_title" = "Marina Kaye";
    "application_type" = discussions;
    "application_type_name" = Discussions;
    content = "<null>";
    "content_title" = "<null>";
    "content_type" = "usefull_messages";
}

I can't cast content to NSArray and content_title to String.

MY CODE :

    let applicationsArray = result["applications"]! as! NSArray

    for application in applicationsArray {

        let applicationTitle = application["application_title"]! as! String
        let applicationType = application["application_type"]! as! String
        let applicationTypeName = application["application_type_name"]! as! String
        let content = application["content"]! as! NSArray
        let contentTitle = application["content_title"]! as! String
        let contentType = application["content_type"]! as! String
        self.listApplications.append(Application(applicationTitle: applicationTitle, applicationType: applicationType, applicationTypeName: applicationTypeName, content: content, contentTitle: contentTitle, contentType: contentType))
    }

Solution

  • As you are coding in Swift, you do not need the legacy NSArray and NSDictionary types. Instead, these are now Array and Dictionary, but you do not even have to care about that.

    To declare an array, you usually specify the type in square brackets, such as [String]. For a dictionary, you need this for both key and value, separated by a colon, e.g. [String: AnyObject].

    From your log output, you have a Dictionary of type [String: AnyObject] with 6 keys; all of them point to String objects, except the "content" one.

    The "content" key apparently points to an array of dictionaries. This is written like this: [[String: AnyObject]]. Thus it is not surprising that casting this to String is not successful.

    Here is how you can parse the application dictionary's "content":

    if let content = application["content"] as? [[String: AnyObject]] {
       for item in content {
           let text = content["content"] as? String
           let link = content["link"] as? String
           // do something with this data
       }
    }
    

    I would recommend defining a class or struct to capture the application object. Your code will be much clearer and easier to maintain.