Why am I unable to post to Twitter using SLComposeViewController? - ios

I'm trying to post an article title and an article URL to twitter and then append the app's name to the end of the tweet. So something like
"How to grow a cactus (via #appname)" attached URL
I was having trouble figuring out how to balance the length of the title and URL to make sure that the tweet doesn't exceed 140 characters. So if the URL is really long, cut some of the article title off so it can be under 140 characters.
Looking at Twitter's guidelines for SLComposeViewController they state this part:
Note that the methods for setting initial content respond with Boolean values; this allows you, the developer, to not have to worry about the current count of characters in the body of the Tweet that you are initializing. If the method returns YES, there was enough room to add the content. If the method returns NO, the content you attempted to add would result in a Tweet longer than 140 characters. The logic for character counting also takes into effect the current number of characters required for t.co URL wrapping.
(From the "Code Example" section.)
Given that, I wrote the following code to build a tweet and balance the URL length and article length:
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter]) {
SLComposeViewController *twitterViewController = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
[twitterViewController addURL:[NSURL URLWithString:self.article.url]];
NSString *titleToShare = self.article.title;
while ([twitterViewController setInitialText:[NSString stringWithFormat:#"%# (via #SyllableApp)", titleToShare]]) {
titleToShare = [titleToShare substringToIndex:titleToShare.length - 1];
}
[self presentViewController:twitterViewController animated:YES completion:nil];
}
Which basically adds the URL then constructs the rest of the tweet by looping through the setInitialText: method until it returns YES, decreasing the length of the title by 1 each time it returns NO in order to get closer to the required length.
But it never returns YES! Even when I know it should. I was using one article where it could potentially exceed 140 characters as the title is 105 characters long and the URL is 55, plus the app credit. So it should theoretically be able to shorten the title down and then add it fine, but it never happens.
So what's going on? How do I accomplish link attachment with SLComposeViewController?

while ([twitterViewController setInitialText:[NSString stringWithFormat:#"%# (via #SyllableApp)", titleToShare]])
=>
while (![twitterViewController setInitialText:[NSString stringWithFormat:#"%# (via #SyllableApp)", titleToShare]])
There is a ! missing in condition, so you shorten the post when it fits, not when it is too long ;)

The problem with this approach is that it works only on iOS6.
SLComposeViewController *social = [[SLComposeViewController alloc] init];
NSString *stringToShare = #"";
for (int i = 0; i < 150; i++)
{
stringToShare = [stringToShare stringByAppendingString:#"x"];
}
NSLog(#"%#",[social setInitialText:stringToShare]?#"YES":#"NO");
yields different results on iOS6 (NO) and iOS7 (YES). The answer to this behaviour comes from the documentation of SLComposeViewController
// Sets the initial text to be posted. Returns NO if the sheet has already been
// presented to the user. On iOS 6.x, this returns NO if the specified text
// will not fit within the character space currently available; on iOS 7.0 and
// later, you may supply text with a length greater than the service supports,
// and the sheet will allow the user to edit it accordingly.
- (BOOL)setInitialText:(NSString *)text;
Probably is worth either having different approaches on iOS6 and 7, or check the length without using SLComposeViewController method.

As imihaly said, you did miss a "!".
And 140 characters count is the limit of title only, not including URL.So your title is 105 characters long which is less than 140,this method should return YES.

There is an open bug with link lengths not getting calculated correctly (radar://10469407). This might be related. You might try sending a Tweet with a link in it to check which URL shortener is being used (I imagine it's using t.co, but I could be wrong).

Related

TwitterKit iOS SDK counting image and URL against character count

I am using the latest version of TwitterKit (2.5), and when I attempt to share a Tweet with an image and URL, the TWTRComposer is counting them against the character count. Twitter is supposed to no longer count media against the character count, and in fact I am able to post the exact same tweet from the web that I cannot post in-app (app says it is too long).
In my current use case, my actual tweet text is 100 characters. With an image and URL, TWTRComposer is showing that I am 8 characters over the limit. Yet, I can post this exact same Tweet with the exact same content from Chrome with 16 characters to spare.
Is this a known bug?
Code snippet:
func didTapShareToTwitter() {
// Configure composer
let composer = TWTRComposer()
composer.setText(composerText)
composer.setURL(shareURL)
if shareImageURL != nil {
if let imageData = NSData(contentsOfURL: shareImageURL!) {
composer.setImage(UIImage(data: imageData))
}
}
// Present composer
composer.showFromViewController(self) { result in
if (result == TWTRComposerResult.Cancelled) {
log("Tweet composition cancelled.")
}
else {
log("Sending tweet...")
}
}
}
Looks like this an iOS system-level bug, not necessarily the Twitter SDK. The TWTRComposer is actually just a wrapper around the built-in iOS sharing view controller, SLComposeViewController.
The iOS SLComposeViewController still counts attached URLs and images against the total Twitter character limit (140) as of the latest iOS release, 10.1. Most likely, Apple just hasn’t updated their OS code since Twitter made the move to not count images and URLs against the character limit earlier this year.
After doing some testing, I have come to the following conclusion:
On iOS, a URL counts as 23 characters no matter original length of
the URL is.
On iOS, an image counts as 23 characters no matter what
size it is.
Therefore, with an image and URL, we have only 94 characters
available on iOS per Tweet. And there’s nothing that can be done
about it unless Twitter updates their SDK or Apple updates
SLComposeViewController.

iOS - Pinterest Sharing Description Text not working if I send "&" in description text

I had implemented pinterest sharing code in my app as well. Its working fine. But problem arrives at one scenario see follow
Correct working:
[pinterest createPinWithImageURL:[NSURL URLWithString:imageUrl]
sourceURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#",shareUrl]]
description:#"My Description"];
Then it will share Pinterest Description same My Description as per my expectation.
But when I send Description Test like :
[pinterest createPinWithImageURL:[NSURL URLWithString:imageUrl]
sourceURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#",shareUrl]]
description:#"My Details & Description"];
Then it will share Pinterest Description like My Details.
My expected text here is My Details & Description this is trunks my string after & symbol.
What actually wrong happening with me please look at here.
AFAIK, Pinterest's Pin It SDK isn't open source, so it's difficult to find out what's really going on.
I would guess, however, that this method is creating a GET request under-the-hood that's incorrectly URL encoding the description parameter (perhaps they're using stringByAddingPercentEscapesUsingEncoding or some other naive method).
I'd recommend contacting the Pinterest SDK developers/maintainers to look into this.
As a quick fix, you might try URL encoding the & yourself. For example, you might try replacing & with %26, e.g.
NSString *description = // ...whatever it should be set to...
description = [description stringByReplacingOccurrencesOfString:#"&" withString:#"%26"];
However, this might actually lead to other problems as the Pinterest SDK is likely doing some sort of URL encoding and would likely encode the % symbol.
Another naive approach may simply be to replace & with the word and, such as
NSString *description = // ...whatever it should be set to...
description = [description stringByReplacingOccurrencesOfString:#"&" withString:#"and"];
Again, it's hacky, but it's a workaround for a bug that's likely in the underlying SDK.

Reference website live updating status from App

I have a website: http://www.grandforks.af.mil/library/weathercenter/index.asp
There is a logo on the middle of the page for the current road conditions on base.
The file names for each condition is different by 1 number.
Green is 19
Yellow is 20
Red is 21
I do not have control over this website.
My question is how can I have the current road conditions in an app that I am building display as a reflection of the website? I don't want to have any user input I want the app to be able to pull off of the site. I have tried using UIWebView but I cannot get it to focus on that area of the page. If I could do that it would probably be the better solution.
Ugly solution:
you can download the html of the website, parse it searching the string "http://www.grandforks.af.mil/shared/media/document/AFD-121002-" and get the actual URL (which is something like http://www.grandforks.af.mil/shared/media/document/AFD-121002-019.jpg).
After that, you can load that URL in your UIImageView or (better) discriminate and show your image that is included in the app.
The ugliness depends by the fact that if they change the image's URL, your app stops working.
I would suggest that when the user opens the app, it goes to check your page and eventually download the string your are looking for. Doing so, if the website changes the url, you can manually modify the source without update the app.
I don't know if using others information is legal.
EDIT:
here is an example that I built that demonstrate how you can substring a string:
NSString *myString = #"11111www.the-site.com/img42.jpg222222222222222";
NSString *searchString = #"www.the-site.com/img";
NSRange range = [myString rangeOfString:searchString];
NSLog(#"searched string strart at character %lu, and it's long %lu charactrers", (unsigned long)range.location, (unsigned long)range.length);
NSInteger index = range.location + range.length;
NSString *mySubString = [myString substringFromIndex:index];
NSLog(#"string from the index: %#", mySubString);
//I know that the substring I'm looking for is long exactly 2 characters
NSString *the_answer = [mySubString substringToIndex:2];
NSLog(#"this should print 42: %#", the_answer);
I added some prints, so you can see step by step what I'm doing.
Obviously you have to change "searchString" with "http://www.grandforks.af.mil/shared/media/document/AFD-121002-" and myString is the html of the page.
I hope it helps.

Is Twitter sharing broken under iOS 7? (Example project attached.)

Example project: http://cl.ly/261z1P100T25
Under iOS 7, when I try to add a URL to a tweet, the method should return NO if there's no enough space to add it ("This method returns NO if url does not fit in the currently available character space") but this method ALWAYS returns YES in iOS 7. For example, in the following example, "Couldn't add." is never printed and the tweet is presented with -32 characters remaining.
SLComposeViewController *twitterViewController = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
NSString *titleToShare = #"i am a string a super string the most super string that ever existed in the world of the super string universe which as it happens is very super as well";
if (titleToShare.length > 140) {
titleToShare = [titleToShare substringToIndex:140];
}
[twitterViewController setInitialText:titleToShare];
if (![twitterViewController addURL:[NSURL URLWithString:#"http://google.com"]]) {
NSLog(#"Couldn't add.");
}
[self presentViewController:twitterViewController animated:YES completion:nil];
Is it broken? Do I have to code around this?
It's not broken, just it isn't publicly documented well. I found in code following comment for setInitialText: method:
// Sets the initial text to be posted. Returns NO if the sheet has already been
// presented to the user. On iOS 6.x, this returns NO if the specified text
// will not fit within the character space currently available; on iOS 7.0 and
// later, you may supply text with a length greater than the service supports,
// and the sheet will allow the user to edit it accordingly.
So, they allow you to set text greater then 140 characters, just you can't post this text because post button is disabled.

Prevent UIWebView from showing UIPopoverController for tel links

I'm working on an iPad application with UIWebView(Deployment target iOS 5.0+).
My UIWebView should do nothing when user taps emails, addresses and phone numbers.
I have a problem with phone numbers. If html page contains links like this: 555-555-5555 when user taps this link UIPopoverController appears(Add to Contacts, Copy).
I have tried next:
Switch off detection in xib file for UIWebView
webView.dataDetectorTypes = UIDataDetectorTypeNone;
call JS - document.documentElement.style.webkitTouchCallout = "none";
UIWebView delegate method shouldStartLoadWithRequest doesn't work for telephone numbers on iPad but works fine on iPhone.
Do you have any ideas?
The reason that particular phone number link isn't getting disabled is that it's not a detected phone number, it's just a regular old <a href=foo> link that happens to have a telephone link for its href attribute. Setting the dataDetectorTypes like you're doing is the the right way to disable phone number detection. So if you have phone numbers just appearing in the web page text somewhere and you want to prevent those from becoming links, keep using webView.dataDetectorTypes = UIDataDetectorTypeNone;.
If you want to disable all links that look like phone numbers you will need to execute a JavaScript after the page has finished loading. In your UIWebView's delegate's webViewDidFinishLoad method use [webView stringByEvaluatingJavaScriptFromString:] and pass in JavaScript to replace the offending links. Here's an example JavaScript that would replace all your tel style links with text elements showing the phone number instead. You might want something slightly different, or maybe you just want to remove the links from the DOM entirely.
var links = document.getElementsByTagName('a');
for (var j = 0; j < links.length; j++) {
var href=links[j].getAttribute('href');
var prefix = href.substring(0,4);
if (prefix == "tel:") {
var parentNode = links[j].parentNode;
var replacementNode = document.createTextNode(href.substring(prefix.length, href.length));
parentNode.replaceChild(replacementNode, links[j]);
}
}

Resources