How to tweet with Line Break (Twitter Rest API via Fabric) - ios

I'm developing a application for iOS(Swift).
I'm afraid my expressions may be rude or hard to read, because I'm not so good at English.
Sorry for any inconvinience I may cause you.
I asked same question on Twitter Developer Forums.
I'm trying to make tweet with "Line Break".
For example
Hello!
World!
So I tried to use Rest API via Fabric. But it doesn't work.
My code is...
let endPoint = "https://api.twitter.com/1.1/statuses/update.json"
var clientError : NSError?
var tweetText = self.contentTextView.text
tweetText = tweetText.stringByReplacingOccurrencesOfString("\n", withString: "\n\r")
let params = ["status" : tweetText]
let request = Twitter.sharedInstance().APIClient.URLRequestWithMethod("POST", URL: endPoint, parameters: params, error: &clientError)
Twitter.sharedInstance().APIClient.sendTwitterRequest(request) { (response, data, connectionError) -> Void in
if (connectionError == nil) {
print(“success")
}else {
print(“failure: \(connectionError)")
}
}
In this code, “contentTextView.text" is text which I want to tweet.
I tried to change line break code “\n”,”\r”,”\n\r” and “%0D%0A”, but it didn’t work too.
Error message is...
failure: Optional(Error Domain=TwitterAPIErrorDomain Code=32 "Request failed: unauthorized (401)" UserInfo={NSErrorFailingURLKey=https://api.twitter.com/1.1/statuses/update.json, NSLocalizedDescription=Request failed: unauthorized (401), NSLocalizedFailureReason=Twitter API error : Could not authenticate you. (code 32)})
If contentTextView.text doesn’t contain “\n” (in other words single line), I can tweet correctly.
For example
Hello!World!
How can I do?
Thanks.
UPDATE:
If I remove the line below, I get same error.
tweetText = tweetText.stringByReplacingOccurrencesOfString("\n", withString: "\n\r")

What if you don't replace "\n"?
By this, I mean remove the line
tweetText = tweetText.stringByReplacingOccurrencesOfString("\n", withString: "\n\r")

Related

Error code 403 when using guest authentication with TwitterKit iOS for getting user timeline

I am using Fabric's twitter kit for getting a username's tweets in my iOS application by making a request to the REST API endpoint "https://api.twitter.com/1.1/statuses/user_timeline.json"
I am have correctly set up my "consumer key" and "consumer secret key" as provided by the Fabric app in my AppDelegate and info.plist , but I repeatedly get the following error message -
Error: Optional(Error Domain=TwitterAPIErrorDomain Code=200 "Request
failed: forbidden (403)"
UserInfo={NSErrorFailingURLKey=https://api.twitter.com/1.1/guest/activate.json,
NSLocalizedDescription=Request failed: forbidden (403),
NSLocalizedFailureReason=Twitter API error : Forbidden. (code 200)})
My code is as under follows -
Twitter.sharedInstance().startWithConsumerKey(TWITTER_CONSUMER_KEY, consumerSecret: TWITTER_CONSUMER_KEY_SECRET)
Fabric.with([Twitter.sharedInstance()])
let userId = Twitter.sharedInstance().sessionStore.session()?.userID
let client = TWTRAPIClient.init(userID: userId)
let params = ["screen_name": twitterUsername, "count" : "10"]
var clientError : NSError?
let request = client.URLRequestWithMethod("GET", URL: TWITTER_TIMELINE_ENDPOINT, parameters: params, error: &clientError)
client.sendTwitterRequest(request) { (response, data, connectionError) -> Void in
if(connectionError == nil) {
self.twitterJson = self.nsdataToJSON(data!)!
self.constructTweetView(self.twitterJson)
}
else {
print("Error: \(connectionError)")
}
I am on the most recent version of TwitterKit(>2.0)
How can I go about resolving this ?
Thanks!
Add key in exception domains as shown in info.plist. Following fixed bug for me.

Authenticated http request swift Alamofire

I'm struggling with getting this to work to make request to my API. Without a token works, but when I try to add additional headers, things turn to be complicated, for me.
First, the structure.
one class called: APIAsyncTask that makes the requests
one class called APIParams, just a data holder to send parameters to the APIAsyncTask class.
one class called DatabaseAPI that makes that builds the parameters, and send that to the APIAsyncTask class.
DatabaseAPI
func someMethod()
{
let task = APIAsyncTasks()
task.registerCallback { (error, result) -> Void in
print("Finished task, back at DatabaseAPI")
}
let params2 = APIParams(request: .GET, apiPath: "Posts/1", apiToken: "4iTX-56w")
task.APIrequest(params2)
}
APIAsyncTask
This part is for fixing another error, because manager was not global, the task got cancelled quickly.
var manager : Manager!
init(authenticatedRequest : Bool, token: String?)
{
manager = Alamofire.Manager()
print("Pre \(manager.session.configuration.HTTPAdditionalHeaders?.count)")
if(authenticatedRequest && token != nil)
{
var defaultHeaders = Alamofire.Manager.sharedInstance.session.configuration.HTTPAdditionalHeaders!
defaultHeaders["Authorization"] = "bearer \(token)"
let configuration = Manager.sharedInstance.session.configuration
configuration.HTTPAdditionalHeaders = defaultHeaders
manager = Alamofire.Manager(configuration: configuration)
}
print("Post \(manager.session.configuration.HTTPAdditionalHeaders?.count)")
}
After some decision making, it comes down to this part.
private func GetRequest(url: String!,token : String?, completionHandler: (JSON?, NSURLRequest?, NSHTTPURLResponse?, NSError?) -> () ) -> ()
{
print("Begin Get Request")
if(token != nil)//if token is not nil, make authenticated request
{
print("just before request: \(manager.session.configuration.HTTPAdditionalHeaders?.count)")
manager.request(.GET, url, parameters: nil, encoding: .JSON).responseJSON { (request, response, json, error) in
print("Get Request (authenticated), inside alamofire request")
var resultJson : JSON?
if(json != nil)
{
resultJson = JSON(json!)
}
completionHandler(resultJson, request, response, error)
}
}
else
{
//working part without token
So as the code is now, I get an error on completing:
Mattt himself gives the answer of using Alamofire.Manager.sharedInstance.session.configuration.HTTPAdditionalHeaders
, so that should be fine...
I suspect it has something to do with the multiple threads, according to this blog. Or, since it is something about CFNetwork, it could be because my API does not use SSL? I disabled NSAppTransportSecurity
I'm kind of new to swift, so examples would be really appreciated! Thankyou!
So the majority of your code looks solid.
The error leads me to believe that CFNetwork is having difficulty figuring out how to compute the protection space for the challenge. I would also assume you are getting a basic auth challenge since you are attaching an Authorization header.
Digging through your logic a bit more with this in mind led me to see that your not attaching your token to the string properly inside the Authorization header. You need to do the following instead.
defaultHeaders["Authorization"] = "bearer \(token!)"
Otherwise your Authorization header value is going to include Optional(value) instead of just value.
That's the only issue I can see at the moment. If you could give that a try and comment back that would be great. I'll update my answer accordingly if that doesn't actually solve your problem.
Best of luck!
You can add your headers in your request with Alamofire 2 and Swift 2.
For an example: go to example

AFNetworking 2 empty POST response but no errors

It's a very tricky problem:
I do a POST request (login) to a server.
The server will answer:
ok Status Code: 200 + JSON Data
error Status Code: 401 + plain/text
Code:
func login (id: String, password: String){
self.responseSerializer = AFJSONResponseSerializer()
self.responseSerializer.acceptableContentTypes = nil
self.responseSerializer.acceptableStatusCodes = NSIndexSet(index: 400)
//self.responseSerializer.acceptableStatusCodes = nil
var param = ["id": lbid, "password": password]
POST(APIURL.URL_LOGIN, parameters: param,
{ (operation : NSURLSessionDataTask!, response : AnyObject!) -> Void in
//var finalResponse : Dictionary = Dictionary<String, String>()
var tmp = response as String
self.defaults.setObject(tmp, forKey: "USERSSID")
self.defaults.setBool(true, forKey: "USERLOGGEDIN")
println("Success login")
}) { (operation : NSURLSessionDataTask!, error : NSError!) -> Void in
println(error)
}
}
It executes the failure blog and I get this error:
Code=-1011 "Request failed: no error (200)" UserInfo=0x7f9fa1534760 {com.alamofire.serialization.response.error.response=<NSHTTPURLResponse: 0x7f9fa15791e0> { URL: https://************ } { status code: 200, headers {
Connection = "Keep-Alive";
"Content-Length" = 107;
"Content-Type" = "application/json";
Date = "Wed, 04 Mar 2015 21:47:51 GMT";
"Keep-Alive" = "timeout=7, max=150";
Server = Apache;
"Set-Cookie" = "SID=************; expires=Mon, 02-Mar-2020 21:47:51 GMT; path=/;domain=.*********";}},NSErrorFailingURLKey=https://***********,com.alamofire.serialization.response.error.data=< CORRECT POST BODY>, NSLocalizedDescription=Request failed: no error (200)}
If I delete this code:
self.responseSerializer.acceptableStatusCodes = NSIndexSet(index: 400)
Then the app crashes. However the server responses with status code 200...
I don't know how to solve this issue.
Could you help me?
Here I get the correct body. But why not in the normal success blog?
EDIT:
self.responseSerializer.acceptableStatusCodes = NSIndexSet(index: 200)
=> App crashs
self.responseSerializer.acceptableStatusCodes = nil
=> App crashs
self.responseSerializer.acceptableStatusCodes = NSIndexSet(index: 401)
=> App doesn't crash, but executes failure block. Status code in error message is 200 and error data contains the correct POST response body.
=> I could extract the message from the error data... but it's such a simple task. It has to work correctly.
Can't use Alamofire because I want to use ssl certificats!
Final edit:
Don't no why, but the error disappeared by its own.
If you haven't already done so, check out Postman (a Google Chrome app). That's the best way to debug AFNetworking issues, by simulating the same request and making sure the data is coming through properly. A number of times, I've been fighting an issue to then use Postman and discover that it's something the server is doing.
I found something that said:
acceptableStatusCodes
The acceptable HTTP status codes for responses. When non-nil,
responses with status codes not contained by the set will result in an
error during validation.
In Objective C:
self.responseSerializer.acceptableStatusCodes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 100)];
The previous post was very useful to fix it. I was searching more and more but nothing was helped out. I tried of adding different codes and got tired ton's of times. Finally seen the above post, which was really solved the issue. I spent 2 days to find the solution.
Initially got the error with -1011 with 400 error. I solved by using the below:
manager.responseSerializer.acceptableStatusCodes = [NSIndexSet indexSetWithIndex:400];
Again got different error like this: "200 no error". I solved by using below code:
manager.responseSerializer.acceptableStatusCodes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 100)];
It works!! cool!!
Hence, I advice you you guys to add the set of below code:
manager.responseSerializer.acceptableStatusCodes = [NSIndexSet indexSetWithIndex:400];
manager.responseSerializer.acceptableStatusCodes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 100)];
Thanks Stackoverflow!!!!

Facebook Pages API Swift

I'm new in programming in swift. I'm trying to read Facebook pages posts(wall) from a public page and show the content(images and messages) in my app without users login. I've already set up the app with Facebook SDK (plist, bridging-Header.h etc...). I know I must open a session and pass a valid access token to the Facebook server. But I can't understand how....
below my viewDidLoad
let request = "/(pageID)?fields=id,posts"
FBRequestConnection.startWithGraphPath(request, completionHandler: {(connection: FBRequestConnection!, result: AnyObject!, error: NSError!) -> Void in
if (error? != nil){
NSLog("error = \(error)")
}else{
println(result)
}
} as FBRequestHandler)
I get this error:
An open FBSession must be specified for calls to this endpoint.
com.facebook.sdk:ParsedJSONResponseKey={
body = {
error = {
code = 104;
message = "An access token is required to request this resource.";
type = OAuthException;
};
};
code = 400;
}}
i think i need to open a session in AppDelegate and so I can make the request I've also read the Facebook documentation but I haven't found the answer.
Please help me. Thank you!!!

Parse JSON in SWIFT

Hi i try to find a way to parse JSON in SWIFT, this works great for me but i run into a problem.
I let the user enter a username that is used for the JSON URL -> if the user type in a valid username all works fine.
But if he enter a wrong username my parsing fails, this is correct too, but for now my app only crashes and i looking for a way to make a work around.
This is my Code where it crashes,
let url0 = NSURL(string: newUrlPath!)
let session0 = NSURLSession.sharedSession()
let task0 = session0.dataTaskWithURL(url0!, completionHandler: {data, response, error -> Void in
if (error != nil) {
println(error)
} else {
let summonorID_JSON = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
The Xcode Error
Error Domain=NSURLErrorDomain Code=-1002 "The operation couldn’t be
completed. (NSURLErrorDomain error -1002.)" UserInfo=0x7c12d610
{NSErrorFailingURLKey=XX, NSErrorFailingURLStringKey=XX,
NSUnderlyingError=0x7c12c8d0 "The operation couldn’t be completed.
(kCFErrorDomainCFNetwork error -1002.)"} fatal error: unexpectedly
found nil while unwrapping an Optional value
All is fine cause this is the return page i get from my Request
https://br.api.pvp.net/api/lol/br/v1.4/summoner/by-name/smirknaitiax?api_key=5c7d4d4f-f320-43d5-8647-643c9f6ee5de
And yes he can't parse this into a NSDirectory as its no JSON that returns (as its normally is) is there a way to take care that if this page comes up (so the user entered a wrong username) that i can exit my loop/take a other way ;)?
You are using many operations which could all fail, and Swift is quite unforgiving about failure. Your code will crash if newURLPath is nil, if url0 is nil because newURLPath wasn't a valid URL.
So your URL request might return an error (the request itself failed), but you have the case that the URL request succeeded but gives unexpected results (not a JSON dictionary). Your code ending in "as NSDictionary" tells Swift: "I know I might not get a dictionary, but convert what you get to a dictionary and crash if this doesn't work". Just change this to
if let parsedJSON = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil)
{
// Will still crash if the server sends a valid JSON array
let summonorID_JSON = parsedJSON as NSDictionary
}
else
{
// data wasn't valid JSON, handle it.
}
The difference is that the optional value returned by the JSON parser will be accepted without crashing, and you check whether you received valid JSON or not.
Since you are getting 404 on this request, I assume that this will happen every time something is bad with username, you should handle server response to fit that. First thing will be to check what server returned:
let httpResp: NSHTTPURLResponse = response as NSHTTPURLRespons
At this point you can access statusCode property, that will tell you if request was good or not (404). Having that information you can decide what to do, and for example, you can modify your code something like this:
let url0 = NSURL(string: newUrlPath!)
let session0 = NSURLSession.sharedSession()
let task0 = session0.dataTaskWithURL(url0!, completionHandler: {data, response, error -> Void in
if (error != nil) {
println(error)
} else {
let httpResp: NSHTTPURLResponse = response as NSHTTPURLRespons
httpResp.statusCode != 404 {
let summonorID_JSON = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
} else {
// Handle error at this point, tell user to retype username etc.
}
})
NSURL is a failable initializer and exactly this happens when you give an invalid url: It fails to initialize.
So wrap your code in an conditional unwrap:
if let url0 = NSURL(string: newUrlPath!) {
...
}
The url0 becomes nil if user enter wrong data. If you use the nil value as url0! app will crash.
When you add a ! after a variable you tell the compiler the value will not be nil.
so to avoid the crash, you have to check for nil condition before calling
let task0 = session0.dataTaskWithURL(url0!, completionHandler: {data, response, error -> Void in

Resources