Twitter API invalid URLRequestWithMethod using Swift - ios

i'm trying to access the home_timeline request as per this example.
However, I keep getting following error:
'URLRequestWithMethod' with an argument list of type '(String, URL: String, parameters: NSArray, error: inout NSError?)'
func getHomeTimeLine(){
var clientError:NSError?
let params = []
let request = Twitter.sharedInstance().APIClient.URLRequestWithMethod(
"GET",
URL: "https://api.twitter.com/1.1/statuses/home_timeline.json",
parameters: params,
error: &clientError)
if request != nil {
Twitter.sharedInstance().APIClient.sendTwitterRequest(request) {
(response, data, connectionError) -> Void in
if (connectionError == nil) {
var jsonError : NSError?
let json : AnyObject? =
NSJSONSerialization.JSONObjectWithData(data,
options: nil,
error: &jsonError)
}
else {
println("Error: \(connectionError)")
}
}
}
else {
println("Error: \(clientError)")
}
}
Thanks in advance.

Define params as a dictionary and use it.
let params: Dictionary = Dictionary()
func getHomeTimeLine() {
var clientError:NSError?
let params: Dictionary = Dictionary<String, String>()
let request: NSURLRequest! = Twitter.sharedInstance().APIClient.URLRequestWithMethod(
"GET",
URL: "https://api.twitter.com/1.1/statuses/home_timeline.json",
parameters: params,
error: &clientError)
if request != nil {
Twitter.sharedInstance().APIClient.sendTwitterRequest(request!) {
(response, data, connectionError) -> Void in
if (connectionError == nil) {
var jsonError : NSError?
let json : AnyObject? =
NSJSONSerialization.JSONObjectWithData(data!,
options: nil,
error: &jsonError)
// check for json data
if (json != nil) {
println("response = \(json)")
} else {
println("error loading json data = \(jsonError)")
}
}
else {
println("Error: \(connectionError)")
}
}
}
else {
println("Error: \(clientError)")
}
}

Try this:
let request: NSURLRequest? = Twitter.sharedInstance().APIClient.URLRequestWithMethod("GET", URL: "https://api.twitter.com/1.1/statuses/user_timeline.json",
parameters: ["screen_name" : username,
"count" : "20"] ,
error: &clientError)

Actually, the method signature where it says 'URL' has been changed to 'URLString' the correct / updated method call (in Objective C) looks like this:
NSDictionary *params = #{#"include_email": #"true", #"skip_status": #"true"};
NSError *clientError;
NSURLRequest *request = [client URLRequestWithMethod:#"GET" URLString:#"https://api.twitter.com/1.1/account/verify_credentials.json" parameters:params error:nil];
Hope this helps someone!

Related

Twitter Search Api 1.1 ERROR: Could not cast value of type '__NSCFDictionary' to 'NSArray'

This code is to search a hashtag on twitter but it gives error saying
Could not cast value of type '__NSCFDictionary' to 'NSArray'
and the same code works fine when I access my home timeline with following URL
https://api.twitter.com/1.1/statuses/home_timeline.json
func getTimeLine() {
let accountType = account.accountTypeWithAccountTypeIdentifier(
ACAccountTypeIdentifierTwitter)
self.account.requestAccessToAccountsWithType(accountType, options: nil,
completion: {(success: Bool, error: NSError!) -> Void in
if success {
let arrayOfAccounts =
self.account.accountsWithAccountType(accountType)
if arrayOfAccounts.count > 0 {
let twitterAccount = arrayOfAccounts.last as! ACAccount
let requestURL = NSURL(string:
"https://api.twitter.com/1.1/search/tweets.json?q=%23baseball&result_type=recent%3F")
let parameters = ["count" : "10"]
let postRequest = SLRequest(forServiceType:
SLServiceTypeTwitter,
requestMethod: SLRequestMethod.GET,
URL: requestURL,
parameters: nil)
postRequest.account = twitterAccount
postRequest.performRequestWithHandler(
{(responseData: NSData!, urlResponse: NSHTTPURLResponse!, error: NSError!) -> Void in
var err: NSError?
self.array = NSJSONSerialization.JSONObjectWithData(responseData, options: NSJSONReadingOptions.MutableLeaves, error: &err) as! [AnyObject**strong text**]
if self.array.count != 0 {
dispatch_async(dispatch_get_main_queue()) {
self.mycollectionView.reloadData()
}
}
})
}
}
else {
println("Failed to access account")
}
})
}
Try making a cast to NSDictionary. It should solve your problem.
self.array = NSJSONSerialization.JSONObjectWithData(
responseData,
options: NSJSONReadingOptions.MutableLeaves, error: &err
) as! NSDictionary
Maybe this is the correct return from twitter.

Alamofire Completion Handler returning response + data

I have a function that includes a responseObject in it's completion handler. At the moment this returns the json body when I call it, along with any errors.
Some parts of the API I am using however, don't return any data in the response body, they just return a response (200, 404, etc...)
I was thinking about appending the response inside the empty json object that is getting returned, then realised that would be silly and it would probably be better if I returned the NSHTTPURLResponse as well, but everything I have found just explains how to return the responseObject along with the error...
This is the function that returns the completion handler:
func makePostRequest(url : String, params : AnyObject, completionHandler: (responseObject: NSHTTPURLResponse, JSON?, error: NSError?) -> ()) -> Request? {
println("params = \(params)")
return Alamofire.request(.POST, url, parameters: params as? [String : AnyObject], encoding: .JSON)
.responseJSON { (request, response, data, error) in completionHandler(
//This is wrong
response: response as? NSHTTPURLResponse,
responseObject:
{
println("Request is \(request)")
println("Response is \(response)")
println("Data is \(data)")
println("Error is \(error)")
//Append the response to this JSON object?
//
var json:JSON = [:]
if let anError = error
{
println(error)
}
else if let data: AnyObject = data
{
json = JSON(data)
}
//probably better to return the two...
//
return (response, json)
}(),
error: error
)
}
}
And this is how its used:
networking.makePostRequest(documentUrl, params: docParams) { response, json, error in
println("response is: \(response)")
println("document json: \(json)")
println("document error: \(error)")
}
I've added in the 'response' bits to all the bits of code, i'm sure this is possible? just not sure how to achieve it..
For anyone stuck trying to figure out how to return stuff this way, I solved it like this:
func makePostRequest(url : String, params : AnyObject, completionHandler: (httpResponse: NSHTTPURLResponse, responseObject:JSON?, error: NSError?) -> ()) -> Request? {
println("params = \(params)")
return Alamofire.request(.POST, url, parameters: params as? [String : AnyObject], encoding: .JSON)
.responseJSON { (request, response, data, error) in completionHandler(
//This is wrong
httpResponse: response!,
responseObject:
{
println("Request is \(request)")
println("Response is \(response)")
println("Data is \(data)")
println("Error is \(error)")
//Append the response to this JSON object?
//
var json:JSON = [:]
if let anError = error
{
println(error)
}
else if let data: AnyObject = data
{
json = JSON(data)
}
return json
}(),
error: error
)
}
}
and then calling it like this:
networking.makePostRequest(workDocumentUrl, params: params) { response, json, error in
if response.statusCode == 200{
//do something
}
println("json: \(json)")
println("error: \(error)")
}

Swift - Expected expression in list of expressions

I'm new to Swift been reading but have no clue what this means. On the line of code below, I have "Expected expression in list of expressions" after parameters[String]. AS well at the same point it is looking for "Expected ',' separator. I believe these are related.
AppDelegate.submitLacunaRequest(module: "empire", method: "login", parameters[String]:["myuserid", "mypassword", "mykey"]) {
responseObject, error in
// some network error or programming error
if error != nil {
println("error = \(error)")
println("responseObject = \(responseObject)")
return
}
// network request ok, now see if login was successful
if let responseDictionary = responseObject as? NSDictionary {
if let errorDictionary = responseDictionary["error"] as? NSDictionary {
println("error logging in (bad userid/password?): \(errorDictionary)")
} else if let resultDictionary = responseDictionary["result"] as? NSDictionary {
println("successfully logged in, refer to resultDictionary for details: \(resultDictionary)")
} else {
println("we should never get here")
println("responseObject = \(responseObject)")
}
}
}
Here is the related code from AppDelegate
public func submitLacunaRequest (#module: String, method: String, parameters: AnyObject, completion: (responseObject: AnyObject!, error: NSError!) -> (Void)) -> NSURLSessionTask? {
let session = NSURLSession.sharedSession()
let url = NSURL(string: "https://us1.lacunaexpanse.com")?.URLByAppendingPathComponent(module)
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "POST"
request.setValue("application/json-rpc", forHTTPHeaderField: "Content-Type")
let requestDictionary = [
"jsonrpc" : "2.0",
"id" : 1,
"method" : "login",
"params" : ["myuserid", "mypassword", "mykey"]
]
var error: NSError?
let requestBody = NSJSONSerialization.dataWithJSONObject(requestDictionary, options: nil, error: &error)
if requestBody == nil {
completion(responseObject: nil, error: error)
return nil
}
request.HTTPBody = requestBody
let task = session.dataTaskWithRequest(request) {
data, response, error in
// handle fundamental network errors (e.g. no connectivity)
if error != nil {
completion(responseObject: data, error: error)
return
}
// parse the JSON response
var parseError: NSError?
let responseObject = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &parseError) as? NSDictionary
if responseObject == nil {
// because it's not JSON, let's convert it to a string when we report completion (likely HTML or text)
let responseString = NSString(data: data, encoding: NSUTF8StringEncoding) as String
completion(responseObject: responseString, error: parseError)
return
}
completion(responseObject: responseObject, error: nil)
}
task.resume()
return task
}
You are using external parameter name for a parameter when calling the function, but the external parameter is not defined in your function declaration. Simply use it this way.
submitLacunaRequest(module: "empire", "login", ["myuserid", "mypassword", "mykey"]) {
You're calling the function incorrectly. You don't need the [String] in the parameters param...
AppDelegate.submitLacunaRequest(module: "empire", method: "login", parameters: ["myuserid", "mypassword", "mykey"]) {
...
}
I called my function parameter protocol.
If I was to try using this property as usual, I would notice it to be written in pink being a keyword and I would rename it.
Instead, I used this property in a string like this and I didn't get any clues from the compiler:
func configure(_ protocol: Protocol, host:String, port:String) {
urlString = "\(protocol)://\(host):\(port)"
}
I spend good 5 minutes confused out of my mind by this error, but then I figured it out. The problem was in the name of the parameter.
I didn't want to rename the parameter, so I ended up writing it like this:
urlString = "\(`protocol`)://\(host):\(port)"

Function Return Error in iOS

I have the following function: prepare() which returns NSMUtableArray. When I try, to return a json which is NSMutableArray object, I get the following error:
'NSMutableArray' is not convertible to 'Void'
Function Source Code:
func prepare() -> NSMutableArray {
let statusesShowEndpoint = "https://api.twitter.com/1.1/statuses/user_timeline.json"
let params = ["screen_name": "tikaDotMe"]
var clientError : NSError?
let request = Twitter.sharedInstance().APIClient.URLRequestWithMethod(
"GET", URL: statusesShowEndpoint, parameters: params,
error: &clientError)
if request != nil {
Twitter.sharedInstance().APIClient.sendTwitterRequest(request) {
(response, data, connectionError) -> Void in
if (connectionError == nil) {
var jsonError : NSError?
let json = NSJSONSerialization.JSONObjectWithData(data,
options: nil,
error: &jsonError) as NSMutableArray
//Error: 'NSMutableArray' is not convertible to 'Void'
return json
}
else {
println("Error: \(connectionError)")
}
}
}
else {
println("Error: \(clientError)")
}
return [""]
}
The problem is that you are trying to return json from a closure which is defined as returning a Void:
(response, data, connectionError) -> Void
EDIT: As #Paulw11 mentions, you need to handle the data in your closure, you can't return it from your prepare function.

JSON Parsing error with Swift

I'm new in iOS programming and I'm trying with the new language Swift.
I've a problem / I don't know how in parsing JSON with Swift for iOS use. I already used JSON in Android, so I know that the JSON and the link is right, but when I try the code below (seen in a tutorial) the app seems to crash and highlighted this line:
var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSDictionary
The console gives me back this error:
The operation couldn’t be completed. (NSURLErrorDomain error -1005.) fatal error: unexpectedly found nil while unwrapping an Optional value
Here is the entire code of the button's action:
let urlAsString = "http://xxxxxxxxxx.altervista.org/App/_DD_/downloadutenti.php?email="+campoEmail.text+"&password="+campoPassword.text
let url = NSURL(string: urlAsString)!
let urlSession = NSURLSession.sharedSession()
println(url)
println(urlSession)
let jsonQuery = urlSession.dataTaskWithURL(url, completionHandler: { data, response, error -> Void in
if (error != nil) {
println(error.localizedDescription)
}
var err: NSError?
if(data != nil){
var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSDictionary
if (err != nil) {
println("JSON Error \(err!.localizedDescription)")
}
var jsonEmail = ""
if var jsonEmail: String! = jsonResult["email"] as? NSString{
}
else{
println("PROBLEM 1")
}
var jsonPassword = ""
if var jsonPassword: String! = jsonResult["pass"] as? NSString{
}
else{
println("PROBLEM 2")
}
dispatch_async(dispatch_get_main_queue(), {
self.scritta2.text = "Email: " + jsonEmail + " - Password: " + jsonPassword
})
}
})
jsonQuery.resume()
N.B.
I use xcode6 simulator and I know for sure that the "variables" campoEmail.text and campoPassword.text are taken in a good way.
JSON it should give back:
[{"id":"1","email":"lincoln#gmail.com","password":"pass","permessi":"1","stato":"Italia","citta":"Palermo","via":"Via Lincoln, 29","cap":"90100","telefono":"091xxxxxx"}]
EDIT FOR #Neo HELP:
I edited all the action of the button like this, but the code goes to the data's null check..
let curURL: NSURL = NSURL(string: "http://fantacharleston.altervista.org/App/_DD_/downloadutenti.php?email=lincoln#gmail.com&password=pass")!
let curRequest: NSURLRequest = NSURLRequest(URL: curURL, cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 60)
NSURLConnection.sendAsynchronousRequest(curRequest, queue: NSOperationQueue.mainQueue()) { (response: NSURLResponse!, data: NSData?, error: NSError!) -> Void in
if (data != nil) {
if let jsonArray: NSArray = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSArray? {
let jsonObject: NSDictionary? = jsonArray.objectAtIndex(0) as? NSDictionary
if (jsonObject != nil) {
NSLog("object: %#", jsonObject!)
let email: NSString? = jsonObject?.objectForKey("email") as? NSString
let password: NSString? = jsonObject?.objectForKey("password") as? NSString
if (email != nil && password != nil) {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.scritta2.text = "Email: " + email! + " - Password: " + password!
})
}
}
}
}
else{
println("null")
}
}
Yes I think I know where your Problem is... Your are trying to put a JSONArray into a NSDictionary... That cant go... Its like trying to put it into a JSONObject in Java.
Just exchange the NSDictionary with NSArray and be sure to get properties like array[0]["key"], not like array["key"], because you are working with an array, not with a dictionary... (Its like ArrayList, and HashMap in Java)
Try this please...
if let jsonResult: NSArray = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSArray? {
let jsonEmail: NSString? = jsonResult.objectAtIndex(0).objectForKey("email")
}
Edit with Code you need
Here it is... I wrote it a bit like I would write it in Java for Android... I think you will easily get it... The problem you commented maybe was that there is no "pass" tag in your JSON... its "password"...
let curURL: NSURL = NSURL(string: "http://fantacharleston.altervista.org/App/_DD_/downloadutenti.php?email=lincoln#gmail.com&password=pass")!
let curRequest: NSURLRequest = NSURLRequest(URL: curURL, cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 60)
NSURLConnection.sendAsynchronousRequest(curRequest, queue: NSOperationQueue.mainQueue()) { (response: NSURLResponse!, data: NSData?, error: NSError!) -> Void in
if (data != nil) {
if let jsonArray: NSArray = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSArray? {
let jsonObject: NSDictionary? = jsonArray.objectAtIndex(0) as? NSDictionary
if (jsonObject != nil) {
NSLog("object: %#", jsonObject!)
let email: NSString? = jsonObject?.objectForKey("email") as? NSString
let password: NSString? = jsonObject?.objectForKey("password") as? NSString
if (email != nil && password != nil) {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.scritta2.text = "Email: " + email + " - Password: " + password
})
}
}
}
}
}

Resources