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

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.

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.

VoiceOver accessibility label for Touch ID

I am trying to ensure that the iOS app that I am working on is accessible and am trying to implement VoiceOver to ensure this.
One strange thing that I cannot find any help for is when the Touch ID view is displayed (in my case for signing into the app). VoiceOver pronounces ID as a word and not I.D.
I have tried implementing the accessibility attributes to both NSString and the LAContext object but neither seem to change what is read out by VoiceOver. Code snippets below:
LAContext *context = [[LAContext alloc] init];
[context setIsAccessibilityElement:YES];
[context setAccessibilityLabel:#"TEST 2"];
NSError *error = nil;
NSString *label = #"Please authenticate your ID using the Touch ID";
[label setIsAccessibilityElement:YES];
[label setAccessibilityTraits:UIAccessibilityTraitStaticText];
[label setAccessibilityLabel:#"TEST"];
showingTouchID = TRUE;
if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]) {
[context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
localizedReason:label
reply:^(BOOL success, NSError *error) {
......
The output from VoiceOver with or without context having the accessibility attributes is always the label text.
All help greatly appreciated :)
You should definitely not change the accessibility label just to make VoiceOver pronounce things correctly (i.e. do not try "hack" the label pronounciation). The reason is that VoiceOver does not have speech output only; it has also braille output where blind users expect to read things exactly letter-by-letter as they are written (i.e. see exactly all the spaces, capital/small letters, etc.) If you did e.g. write "I D" instead of "ID", then while VoiceOver would pronounce it perhaps correctly (in the specific version of iOS), blind users, after also reading "I D" on a braille display might think that that is how it is actually written and appear let's say non-professionally when they would then use this wrong spelling in written exchanges with other people.
The correct way to deal with this, albeit without giving you an immediate solution, is:
File a bug with Apple about pronounciation of the specific word with the specific voice in the specific language (e.g. "Expected pronounciation: [aj'di:]" vs. "Actual pronounciation: [id]")
File a bug with Apple to request the ability to customize pronunciation only (i.e. where you would leave the accessibility label intact and correct, but specify to the voice how it should pronounce certain part of the text), and where this customization could be done for each language individually by the translator translating the strings (because wrong pronunciation is language-specific) - also see the next point.
If you can reword, try different word than the problematic one (which seems not applicable in case of "Touch ID" which is a set term). But this is a hack too, as that solves only the English original and does not care about translations where the rewording might on the contrary potentially complicate the pronunciation.
Sorry for the bad news.
Finally, here, both on iOS 8.4.1 and iOS 9.0.2, VoiceOver with default US English iOS voice, at least on this webpage, pronounces "ID" in "Touch ID" as [ajdi:], not [id].
You can try this for a quick work around: Just give space between I and D
NSString *label = #"Please authenticate your ID using the Touch ID";
label.accessibilityLabel=#"Please authenticate your I D using the Touch I D";
Also please note that you can only set accessibility to UIElements and you cannot set it to general variables. It doesn't make sense to set accessibility label for LAContext and to NSString.
YOu need to set the accessibility label to UILabel or the element which you give the NSString to.
Starting with iOS 11, you can set the element's accessibilityAttributedLabel and use the UIAccessibilitySpeechAttributeIPANotation key (Swift: NSAttributedString.Key.accessibilitySpeechIPANotation) to specify the pronunciation for a range of the attributed string.
See "Speech Attributes for Attributed Strings" for other tools you can use to tweak how VoiceOver reads your text.

Titanium ios contact phone custom labels?

I found a bug in Titanium Appcelerator Studio , the phone object return undefined when the contact object has custom labels for phone number .
Unfortunately they may take more time to fix this issue , but the good news I can modify the build classes of Objective-C , here is the method to provide person information .
inside /build/iphone/classes/TiContactsPerson.m
+(NSDictionary*)multiValueLabels
{
if (multiValueLabels == nil) {
multiValueLabels =
[[NSDictionary alloc] initWithObjectsAndKeys:(NSString*)kABHomeLabel,#"home", // Generic labels
kABWorkLabel,#"work",
kABOtherLabel,#"other",
kABPersonPhoneMobileLabel,#"mobile", // Phone labels
kABPersonPhonePagerLabel,#"pager",
kABPersonPhoneWorkFAXLabel,#"workFax",
kABPersonPhoneMainLabel,#"main",
kABPersonPhoneIPhoneLabel,#"iPhone",
kABPersonPhoneHomeFAXLabel,#"homeFax",
kABPersonSocialProfileServiceFacebook,#"facebookProfile",// Social Profile Labels
kABPersonSocialProfileServiceFlickr,#"flickrProfile",
kABPersonSocialProfileServiceGameCenter,#"gameCenterProfile",
kABPersonSocialProfileServiceLinkedIn,#"linkedInProfile",
kABPersonSocialProfileServiceMyspace,#"myspaceProfile",
kABPersonSocialProfileServiceSinaWeibo,#"sinaWeiboProfile",
kABPersonSocialProfileServiceTwitter,#"twitterProfile",
kABPersonInstantMessageServiceAIM,#"aim", // IM labels
kABPersonInstantMessageServiceICQ,#"icq",
kABPersonInstantMessageServiceJabber,#"jabber",
kABPersonInstantMessageServiceMSN,#"msn",
kABPersonInstantMessageServiceYahoo,#"yahoo",
kABPersonInstantMessageServiceQQ,#"qq",
kABPersonInstantMessageServiceSkype,#"skype",
kABPersonInstantMessageServiceGoogleTalk,#"googletalk",
kABPersonInstantMessageServiceGaduGadu,#"gadugadu",
kABPersonInstantMessageServiceFacebook,#"facebook",
kABPersonMotherLabel,#"mother", // Relation labels
kABPersonFatherLabel,#"father",
kABPersonParentLabel,#"parent",
kABPersonSisterLabel,#"sister",
kABPersonBrotherLabel,#"brother",
kABPersonChildLabel,#"child",
kABPersonFriendLabel,#"friend",
kABPersonSpouseLabel,#"spouse",
kABPersonPartnerLabel,#"partner",
kABPersonManagerLabel,#"manager",
kABPersonAssistantLabel,#"assistant",
kABPersonAnniversaryLabel,#"anniversary", // Date label
kABPersonHomePageLabel,#"homepage", // URL label
nil];
}
return multiValueLabels;
}
It does not include custom label's set by user for phone number , and that's why the phone array return undefined when contact has custom label set.
my question how to get all custom label's created by user and push
them inside above array ?
note : I've reported this bug to appcelerator Jira.
any advice is very much appreciated
The ticket https://jira.appcelerator.org/browse/TIMOB-19739 is closed and released since SDK 5.1.0

Google+ API in iOS, GPPShare recipient setting

I am trying to integrate GooglePlus inside an iOS app of mine.
The app sends a simple message. I have a few questions about the setting of the recipient(s).
Here is the kind of code I am using:
[GPPShare sharedInstance].delegate = self;
id<GPPNativeShareBuilder> shareBuilder = [[GPPShare sharedInstance] nativeShareDialog];
[shareBuilder setPrefillText:#"Hello world! How is everything?"];
[shareBuilder setPreselectedPeopleIDs:#"112233445566778899000"]; // Question point!!
if (![shareBuilder open]) {
NSLog(#"Status: Error (shareBuilder cannot open).");
}
When the line with the comment "Question point!!" is present, I can set one(or a few) individual(s) as recipient(s) of the message.
When it is not present the set of recipients defaults to "Friends".
Here are my two questions:
Is it possible to set one of my circles (or a community) as recipient? Not only "Friends".
When using the "setPreselectedPeopleIDs:" method, one needs the ID of the recipient. How do we find this ID? There are documents and videos on the net showing how to find one's own ID, but since people usually send messages to other peole rather than to themselves, it would also be useful to know how to get other's IDs.
Doesn't seem like you can share with a specific circle.
You can use this method to get all of the visible people in the user's circles using this method
queryForPeopleListWithUserId:collection:
which is outlined here:
https://developers.google.com/+/mobile/ios/people
Explanation of the parameters from the header:
// List all of the people in the specified collection.
// Required:
// userId: Get the collection of people for the person identified. Use "me" to
// indicate the authenticated user.
// collection: The collection of people to list.
// kGTLPlusCollectionVisible: The list of people who this user has added to
// one or more circles, limited to the circles visible to the requesting
// application.
And another question that goes into this a little bit:
How to Fetch Google Plus circles in IOS Sdk
It does not seem to me like you can discern who is in what circle, unfortunately.

Why am I unable to post to Twitter using SLComposeViewController?

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).

Resources