Rest API suddenly failing on iOS9 - Tweets.json / Show.json

ios
rest

#1

This is affecting an app in the wild that was working completely. Suddenly tweets stopped loading.

This is with a live app so obviously no changes to App itself or SDKs on the client side caused this.

Twitter API Status shows Tweets still works but not on IOS9.
https://status.io.watchmouse.com/7617/300002//1.1/search/tweets

Rest API 1.1 Calls that started failing:
-https://api.twitter.com/1.1/search/tweets.json?q=tbt
-https://api.twitter.com/1.1/statuses/show.json?id=%@

Rest API 1.1 calls in the app that still work fine:
-https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=%@&exclude_replies=1&count=100&include_rts=0

So this leaves the obvious question for Twitter Engineers. What changed to the APIs that suddenly stopped working.

Our configuration:
Parse SDK with their integrated Twitter API calls to REST. This obviously worked when we released the app.
Tried changing between 1.9.1, 1.9.0 and 1.8.4 just to be sure. No change. Issue still exist.

I suspect this has something to do with NSAppTransportAuthority. Some change to the server side and suddenly one api is still up to snuff to work fine and two others fail. Help much appreciated.


#2

Without more information what and how exactly it is failing, it’s very hard/nearly impossible to help you.


#3
  1. search results for a search on a hashtag are not showing
  2. any reference to a twitter profile image shows as an egg
  3. any reference to tweet id’s return zero results
  4. a call for profile info followers/following also fails

The iOS app is Hashtag Roundup


#4

Here is the specific error we get:
Error Domain=NSCocoaErrorDomain Code=3840 “No value.”

Here is the API call:
NSURL *verify = [NSURL URLWithString:[NSString stringWithFormat:@“https://api.twitter.com/1.1/search/tweets.json?q=%@%@&count=100”, hashStr, @"%20-RT"]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:verify];
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:NSJSONWritingPrettyPrinted error:&jsonError];
[request setHTTPBody:jsonData];
[[PFTwitterUtils twitter] signRequest:request];

Here is the Parse iOS SDK:

Let me know any other details that would help.


#5

That error is not really helpful as it’s not the HTTP Error but only the error the JSON serializer raises as it’s getting unexpected data.

To actually say anything the HTTP request status code and result is needed.


#6

The data sent is:
<>
Response code is 400:
400 Bad Request The request was invalid or cannot be otherwise served. An accompanying error message will explain further. In API v1.1, requests without authentication are considered invalid and will yield this response.

So interesting… why would this work then suddenly stop? @ePirat thanks your responses actually helped.

Although there is no solution from this besides to know what was a valid request is now suddenly not a valid request and it only affects certain REST apis.


#7

I just quickly looked over the code at first and took a closer look now.
It’s obviously failing as something is broken with your request, this has nothing to do with the Twitter API actually, as when you just send data that makes no sense to it, it’s a bad request as indicated by status code 400.
Your code is incomplete it seems, there is a params variable which is not present at all and I don’t understand why you set a HTTP Body to some JSON string for a simple GET request?
Please share a bit more details. (Please use the code formatting option of this forum, so code actually is displayed correctly. You can do so by using markdown fenced code blocks)


#8

Its not the request. Like I already mentioned this has been working fine for a while. Here is the more complete code snippet. Trying to keep it concise… Really though. Params you can set to nil.

It’s not hard to reproduce. 1. Parse Twitter iOS Authentication. 2. Attempt the same Rest API call.

NSURL *verify = [NSURL URLWithString:[NSString stringWithFormat:@"https://api.twitter.com/1.1/search/tweets.json?q=%@%@&count=100", hashStr, @"%20-RT"]];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:verify];
NSDictionary *params = @{@"count" : @"100"};
NSError *jsonError;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:NSJSONWritingPrettyPrinted error:&jsonError];
[request setHTTPBody:jsonData];

[[PFTwitterUtils twitter] signRequest:request];

NSURLResponse *response = nil;

NSData *data = [NSURLConnection sendSynchronousRequest:request
                                     returningResponse:&response
                                                 error:nil];
NSError *error = nil; 
NSDictionary *res;
if(data != nil){
res = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error];
}else{
    return;
}

if (error != nil) {
    NSLog(@"Error parsing JSON.");
     NSLog(@"Error parsing JSON. %@ json:%@  data:%@ response:%@", error, jsonArray, data, response);
}
else {
    NSLog(@"Array: %@", res); 
    NSArray *results = [res valueForKey:@"statuses"];

}


#9

Update:
Issue fixed.
[request setHTTPBody:jsonData];

Which we had been using to pass params now causes the 400 error. Just commenting that out API calls go through successfully.


#10

Yes, that was what I was trying to say. It makes no sense to use that unless you do a POST request, which is afaik not possible for that endpoint.
Usually you don’t use POST requests to just retrieve data but GET instead where params must be encoded into the URL.


#11

Thank you very much for your assistance with this!