SLRequest and Facebook error 2500

This request will fetch the URL http://example.com/foo?a=1:

    [SLRequest requestForServiceType:SLServiceTypeFacebook       
                       requestMethod:SLRequestMethodGET
                                 URL:[NSURL URLWithString:@"http://example.com/foo"]
                          parameters:@{@"a": @"1"}];

So will this one:

    [SLRequest requestForServiceType:SLServiceTypeFacebook       
                       requestMethod:SLRequestMethodGET
                                 URL:[NSURL URLWithString:@"http://example.com/foo?a=1"]
                          parameters:nil];

This request will attempt to fetch the (malformed) URL http://example.com/foo?a=1?b=2:

    [SLRequest requestForServiceType:SLServiceTypeFacebook       
                       requestMethod:SLRequestMethodGET
                                 URL:[NSURL URLWithString:@"http://example.com/foo?a=1"]
                          parameters:@{@"b": @"2"}];

It might seem harmless to include a query string in the URL if the parameters argument is empty, but extra parameters can get appended in less obvious ways:

NSURL *url =
    [NSURL URLWithString:@"https://graph.facebook.com/me/friends?limit=5000"];
SLRequest *request =
    [SLRequest requestForServiceType:SLServiceTypeFacebook
                         requestMethod:SLRequestMethodGET
                                    URL:url
                            parameters:nil];
request.account = myAccount;

Because the account property is set, an access token will be appended to the URL. If there's already a query string on the URL as above, the result will be malformed:

https://graph.facebook.com/me/friends?limit=5000?access_token=<...>

And the response from Facebook will complain that there is no access token.

Moral of the story: Always use the parameters argument for query string items, never the URL argument.

in practice

NSData Class Reference (emphasis added)

Overview

NSData and its mutable subclass NSMutableData provide data objects, object-oriented wrappers for byte buffers. Data objects let simple allocated buffers (that is, data with no embedded pointers) take on the behavior of Foundation objects.

The size of the data is subject to a theoretical limit of about 8 ExaBytes (in practice, the limit should not be a factor).

[ exa = 1018 ]

let's try this again

New year, new blog, hope springs eternal.