Error in passing data to the web service. 'NSInvalidArgumentException', reason: 'Invalid (non-string) key in JSON dictionary'

1.4k Views Asked by At

I'm trying to pass the twitter feeds that i save on the UserDefaults to the WebService. the WebService works because i'm using it on the passing the feeds from Facebook.

- (void) fetchedTwitterFeeds: (NSString *)screenname{
STTwitterAPI * twit = [STTwitterAPI twitterAPIAppOnlyWithConsumerKey:twitter_id consumerSecret:twitter_secret];

if ([[NSUserDefaults standardUserDefaults] valueForKey:TWITTER_SCREEN_NAME] !=nil) {
    screenname = [NSString stringWithFormat:@"%@", [[NSUserDefaults standardUserDefaults] valueForKey:TWITTER_SCREEN_NAME]];
}

[twit verifyCredentialsWithSuccessBlock:^(NSString * username){
    [twit getUserTimelineWithScreenName:screenname successBlock:^(NSArray * statuses){
        self.feeds = [NSMutableArray arrayWithArray:statuses];
        NSLog(@"Twitter Feeds Login: %@", feeds);

        NSLog(@"Session Token: %@", [[NSUserDefaults standardUserDefaults] valueForKey:SESSION_TOKEN]);
        NSLog(@"Track ID: %d", track_id);
        NSLog(@"Tweets: %@", [feeds valueForKey:@"text"]);
        NSLog(@"Created at: %@", [feeds valueForKey:@"created_at"]);
        NSLog(@"Country: %@", [[feeds valueForKey:@"place"] valueForKey:@"country"]);
        NSLog(@"Place Name: %@", [[feeds valueForKey:@"place"] valueForKey:@"full_name"]);
        NSLog(@"Sample Lat: -75.14310264");
        NSLog(@"Sample Long: 40.05701649");
        NSLog(@"Media URL: %@", [[[feeds valueForKey:@"entities"] valueForKey:@"media"] valueForKey:@"media_url"]);
        NSLog(@"Provider Name: %@", TWITTER_PROVIDER);

        //Saving Feeds
        if ([feeds valueForKey:@"text"] !=nil)[[NSUserDefaults standardUserDefaults] setObject:[feeds valueForKey:@"text"] forKey:TWITTER_FEED_TWEETS_KEY];
        else[[NSUserDefaults standardUserDefaults] setObject:@"No Tweets" forKey:TWITTER_FEED_TWEETS_KEY];

        if ([feeds valueForKey:@"created_at"] !=nil)[[NSUserDefaults standardUserDefaults] setObject:[feeds valueForKey:@"created_at"] forKey:TWITTER_FEED_DATE_CREATED_KEY];
        else[[NSUserDefaults standardUserDefaults] setObject:@"No Date Created" forKey:TWITTER_FEED_DATE_CREATED_KEY];

        if ([feeds valueForKey:@"created_at"] !=nil)[[NSUserDefaults standardUserDefaults] setObject:[[feeds valueForKey:@"place"] valueForKey:@"country"] forKey:TWITTER_FEED_COUNTRY_KEY];
        else[[NSUserDefaults standardUserDefaults] setObject:@"No Country" forKey:TWITTER_FEED_COUNTRY_KEY];

        if ([feeds valueForKey:@"created_at"] !=nil)[[NSUserDefaults standardUserDefaults] setObject:[[feeds valueForKey:@"place"] valueForKey:@"full_name"] forKey:TWITTER_FEED_PLACE_NAME_KEY];
        else[[NSUserDefaults standardUserDefaults] setObject:@"No Place Name" forKey:TWITTER_FEED_PLACE_NAME_KEY];

        if ([feeds valueForKey:@"created_at"] !=nil)[[NSUserDefaults standardUserDefaults] setObject:@"-75.14310264" forKey:TWITTER_FEED_LATITUDE_KEY];

        if ([feeds valueForKey:@"created_at"] !=nil)[[NSUserDefaults standardUserDefaults] setObject:@"40.05701649" forKey:TWITTER_FEED_LONGITUDE_KEY];

        if ([feeds valueForKey:@"created_at"] !=nil)[[NSUserDefaults standardUserDefaults] setObject:[[[feeds valueForKey:@"entities"] valueForKey:@"media"] valueForKey:@"media_url"] forKey:TWITTER_FEED_MEDIA_URL_KEY];
        else[[NSUserDefaults standardUserDefaults] setObject:@"No Media " forKey:TWITTER_FEED_MEDIA_URL_KEY];

    }errorBlock:^(NSError * error){
        NSLog(@"%@", error.debugDescription);
    }];
}errorBlock:^(NSError * error){
    NSLog(@"%@", error.debugDescription);
}];
}

And heres the twitter Feeds i get when i NSLog(@"Twitter Feeds Login: %@", feeds) :

    2014-08-19 15:42:10.497 backtrack[11009:60b] Twitter Feeds Login: (
    {
    contributors = "<null>";
    coordinates = "<null>";
    "created_at" = "Tue Aug 19 04:50:45 +0000 2014";
    entities =         {
        hashtags =             (
        );
        media =             (
                            {
                "display_url" = "pic.twitter.com/kKBrsjf4GO";
                "expanded_url" = "http://twitter.com/calsofer/status/501592079156273152/photo/1";
                id = 501592077608562689;
                "id_str" = 501592077608562689;
                indices =                     (
                    5,
                    27
                );
                "media_url" = "http://pbs.twimg.com/media/BvYDVkgCMAEBucu.png";
                "media_url_https" = "https://pbs.twimg.com/media/BvYDVkgCMAEBucu.png";
                sizes =                     {
                    large =                         {
                        h = 120;
                        resize = fit;
                        w = 120;
                    };
                    medium =                         {
                        h = 120;
                        resize = fit;
                        w = 120;
                    };
                    small =                         {
                        h = 120;
                        resize = fit;
                        w = 120;
                    };
                    thumb =                         {
                        h = 120;
                        resize = crop;
                        w = 120;
                    };
                };
                type = photo;
                url = "http://t.co/kKBrsjf4GO";
            }
        );
        symbols =             (
        );
        urls =             (
        );
        "user_mentions" =             (
        );
    };
    "extended_entities" =         {
        media =             (
                            {
                "display_url" = "pic.twitter.com/kKBrsjf4GO";
                "expanded_url" = "http://twitter.com/calsofer/status/501592079156273152/photo/1";
                id = 501592077608562689;
                "id_str" = 501592077608562689;
                indices =                     (
                    5,
                    27
                );
                "media_url" = "http://pbs.twimg.com/media/BvYDVkgCMAEBucu.png";
                "media_url_https" = "https://pbs.twimg.com/media/BvYDVkgCMAEBucu.png";
                sizes =                     {
                    large =                         {
                        h = 120;
                        resize = fit;
                        w = 120;
                    };
                    medium =                         {
                        h = 120;
                        resize = fit;
                        w = 120;
                    };
                    small =                         {
                        h = 120;
                        resize = fit;
                        w = 120;
                    };
                    thumb =                         {
                        h = 120;
                        resize = crop;
                        w = 120;
                    };
                };
                type = photo;
                url = "http://t.co/kKBrsjf4GO";
            }
        );
    };
    "favorite_count" = 0;
    favorited = 0;
    geo = "<null>";
    id = 501592079156273152;
    "id_str" = 501592079156273152;
    "in_reply_to_screen_name" = "<null>";
    "in_reply_to_status_id" = "<null>";
    "in_reply_to_status_id_str" = "<null>";
    "in_reply_to_user_id" = "<null>";
    "in_reply_to_user_id_str" = "<null>";
    lang = en;
    place =         {
        attributes =             {
        };
        "bounding_box" =             {
            coordinates =                 (
                                    (
                                            (
                        "-8.662663",
                        "49.1626564"
                    ),
                                            (
                        "1.768926",
                        "49.1626564"
                    ),
                                            (
                        "1.768926",
                        "60.86165"
                    ),
                                            (
                        "-8.662663",
                        "60.86165"
                    )
                )
            );
            type = Polygon;
        };
        "contained_within" =             (
        );
        country = "United Kingdom";
        "country_code" = GB;
        "full_name" = "United Kingdom";
        id = 6416b8512febefc9;
        name = "United Kingdom";
        "place_type" = country;
        url = "https://api.twitter.com/1.1/geo/id/6416b8512febefc9.json";
    };
    "possibly_sensitive" = 0;
    "retweet_count" = 0;
    retweeted = 0;
    source = "<a href=\"http://twitter.com\" rel=\"nofollow\">Twitter Web Client</a>";
    text = "Test http://t.co/kKBrsjf4GO";
    truncated = 0;
    user =         {
        "contributors_enabled" = 0;
        "created_at" = "Sat Jan 29 11:30:22 +0000 2011";
        "default_profile" = 0;
        "default_profile_image" = 0;
        description = "You can't just grow a sexy beard. You either have one, or you don't..:";
        entities =             {
            description =                 {
                urls =                     (
                );
            };
        };
        "favourites_count" = 0;
        "follow_request_sent" = "<null>";
        "followers_count" = 17;
        following = "<null>";
        "friends_count" = 47;
        "geo_enabled" = 1;
        id = 244472426;
        "id_str" = 244472426;
        "is_translation_enabled" = 0;
        "is_translator" = 0;
        lang = en;
        "listed_count" = 0;
        location = "";
        name = "Christopher Fuertes";
        notifications = "<null>";
        "profile_background_color" = 1A1B1F;
        "profile_background_image_url" = "http://pbs.twimg.com/profile_background_images/558638885/559647_3164538518462_1415356240_32122022_1669491008_n.jpg";
        "profile_background_image_url_https" = "https://pbs.twimg.com/profile_background_images/558638885/559647_3164538518462_1415356240_32122022_1669491008_n.jpg";
        "profile_background_tile" = 1;
        "profile_banner_url" = "https://pbs.twimg.com/profile_banners/244472426/1352679509";
        "profile_image_url" = "http://pbs.twimg.com/profile_images/2838158026/56ed90e6ccc6c35cc41a1a8a41db312e_normal.jpeg";
        "profile_image_url_https" = "https://pbs.twimg.com/profile_images/2838158026/56ed90e6ccc6c35cc41a1a8a41db312e_normal.jpeg";
        "profile_link_color" = 960E20;
        "profile_sidebar_border_color" = FFFFFF;
        "profile_sidebar_fill_color" = 252429;
        "profile_text_color" = 666666;
        "profile_use_background_image" = 1;
        protected = 0;
        "screen_name" = calsofer;
        "statuses_count" = 1;
        "time_zone" = "Kuala Lumpur";
        url = "<null>";
        "utc_offset" = 28800;
        verified = 0;
    };
}
)

And heres my code for passing it to web service:

 NSLog(@"UserDefault Tweets: %@", [[NSUserDefaults standardUserDefaults] objectForKey:TWITTER_FEED_TWEETS_KEY]);
NSLog(@"UserDefault Date Created: %@", [[NSUserDefaults standardUserDefaults] objectForKey:TWITTER_FEED_DATE_CREATED_KEY]);
NSLog(@"UserDefault Country: %@", [[NSUserDefaults standardUserDefaults] objectForKey:TWITTER_FEED_COUNTRY_KEY]);
NSLog(@"UserDefault Place Name: %@", [[NSUserDefaults standardUserDefaults] objectForKey:TWITTER_FEED_PLACE_NAME_KEY]);
NSLog(@"UserDefault Latitude: %@", [[NSUserDefaults standardUserDefaults] objectForKey:TWITTER_FEED_LATITUDE_KEY]);
NSLog(@"UserDefault Longtitude: %@", [[NSUserDefaults standardUserDefaults] objectForKey:TWITTER_FEED_LONGITUDE_KEY]);
NSLog(@"UserDefault Media URL: %@", [[NSUserDefaults standardUserDefaults] objectForKey:TWITTER_FEED_MEDIA_URL_KEY]);

NSDictionary * dict = [NSDictionary dictionaryWithObject:[NSArray arrayWithObjects: [[NSUserDefaults standardUserDefaults] valueForKey:SESSION_TOKEN], [NSString stringWithFormat:@"%d", track_id], [[NSUserDefaults standardUserDefaults] valueForKey:TWITTER_FEED_TWEETS_KEY], [[NSUserDefaults standardUserDefaults] valueForKey:TWITTER_FEED_DATE_CREATED_KEY], [[NSUserDefaults standardUserDefaults] valueForKey:TWITTER_FEED_COUNTRY_KEY], [[NSUserDefaults standardUserDefaults] valueForKey:TWITTER_FEED_PLACE_NAME_KEY], [[NSUserDefaults standardUserDefaults] valueForKey:TWITTER_FEED_LATITUDE_KEY], [[NSUserDefaults standardUserDefaults] valueForKey:TWITTER_FEED_LONGITUDE_KEY], [[NSUserDefaults standardUserDefaults] valueForKey:TWITTER_FEED_MEDIA_URL_KEY],TWITTER_PROVIDER, nil]
                                                  forKey:[NSArray arrayWithObjects:SESSION_TOKEN, @"track_id", @"message",@"date_created",@"country",@"place_name",@"latitude",@"longitude",@"media_url",@"provider_name", nil]];

[webService postRequestFromUrl:[NSString stringWithFormat:@"%@%@", ROOT_SERVER_URL, SAVE_DATA_FEEDS] withDictionary:dict];

but I'm getting a error in doing that. the error is:

enter image description here

2

There are 2 best solutions below

0
Paulw11 On BEST ANSWER

When you create dict you should use dictionaryWithObjects:forKeys:, not dictionaryWithObject:forKey: - you are specifying an NSArray as your key, which as the exception tells you, is not a string.

You should have -

NSDictionary * dict = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects: [[NSUserDefaults standardUserDefaults] valueForKey:SESSION_TOKEN], [NSString stringWithFormat:@"%d", track_id], [[NSUserDefaults standardUserDefaults] valueForKey:TWITTER_FEED_TWEETS_KEY], [[NSUserDefaults standardUserDefaults] valueForKey:TWITTER_FEED_DATE_CREATED_KEY], [[NSUserDefaults standardUserDefaults] valueForKey:TWITTER_FEED_COUNTRY_KEY], [[NSUserDefaults standardUserDefaults] valueForKey:TWITTER_FEED_PLACE_NAME_KEY], [[NSUserDefaults standardUserDefaults] valueForKey:TWITTER_FEED_LATITUDE_KEY], [[NSUserDefaults standardUserDefaults] valueForKey:TWITTER_FEED_LONGITUDE_KEY], [[NSUserDefaults standardUserDefaults] valueForKey:TWITTER_FEED_MEDIA_URL_KEY],TWITTER_PROVIDER, nil]
                                                  forKeys:[NSArray arrayWithObjects:SESSION_TOKEN, @"track_id", @"message",@"date_created",@"country",@"place_name",@"latitude",@"longitude",@"media_url",@"provider_name", nil]];

Your code would also be a bit easier to read if you just set a variable to [NSUserDefaults standardUserDefaults] and referred to that rather than invoking the standardUserDefaults method repeatedly

0
lihudi On

The members of [NSUserDefaults standardUserDefaults] valueForKey:WHATEVER_KEY_HERE] are arrays not just strings. That is fine when working with dictionaries, but does not work when serializing to JSON format.

So you have to get the strings out of the arrays for every object in the line:

[NSArray arrayWithObjects: [[NSUserDefaults standardUserDefaults] valueForKey:SESSION_TOKEN], [NSString stringWithFormat:@"%d", track_id], [[NSUserDefaults standardUserDefaults] valueForKey:TWITTER_FEED_TWEETS_KEY], [[NSUserDefaults standardUserDefaults] valueForKey:TWITTER_FEED_DATE_CREATED_KEY], [[NSUserDefaults standardUserDefaults] valueForKey:TWITTER_FEED_COUNTRY_KEY], [[NSUserDefaults standardUserDefaults] valueForKey:TWITTER_FEED_PLACE_NAME_KEY], [[NSUserDefaults standardUserDefaults] valueForKey:TWITTER_FEED_LATITUDE_KEY], [[NSUserDefaults standardUserDefaults] valueForKey:TWITTER_FEED_LONGITUDE_KEY], [[NSUserDefaults standardUserDefaults] valueForKey:TWITTER_FEED_MEDIA_URL_KEY],TWITTER_PROVIDER, nil]

Example:

NSString* sesionToken = [[[NSUserDefaults standardUserDefaults] valueForKey:SESSION_TOKEN] objectAtIndex:0]