--- a/Adium.xcodeproj/project.pbxproj Thu Mar 21 00:01:23 2013 -0400
+++ b/Adium.xcodeproj/project.pbxproj Tue Apr 16 17:27:41 2013 +0200
@@ -107,17 +107,12 @@
112E7FA60FC86BB400657119 /* AITwitterActionsHTMLFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 112E7FA50FC86BB400657119 /* AITwitterActionsHTMLFilter.m */; };
1130EA99109B445500FB3454 /* pref-defaultclient.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 1130EA98109B445500FB3454 /* pref-defaultclient.tiff */; };
1130EA9D109B445D00FB3454 /* pref-mention.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 1130EA9B109B445D00FB3454 /* pref-mention.tiff */; };
- 113891830F6B6AFF00A7D7DC /* AILaconicaService.m in Sources */ = {isa = PBXBuildFile; fileRef = 113891820F6B6AFF00A7D7DC /* AILaconicaService.m */; };
- 1138918A0F6B6B2800A7D7DC /* AILaconicaAccount.m in Sources */ = {isa = PBXBuildFile; fileRef = 113891890F6B6B2800A7D7DC /* AILaconicaAccount.m */; };
- 1138918D0F6B6B3F00A7D7DC /* AILaconicaPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 1138918C0F6B6B3F00A7D7DC /* AILaconicaPlugin.m */; };
- 113891950F6B6B9C00A7D7DC /* AILaconicaAccountViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 113891940F6B6B9C00A7D7DC /* AILaconicaAccountViewController.m */; };
113892270F6B70CA00A7D7DC /* laconica-small.png in Resources */ = {isa = PBXBuildFile; fileRef = 113892250F6B70CA00A7D7DC /* laconica-small.png */; };
113892280F6B70CA00A7D7DC /* laconica.png in Resources */ = {isa = PBXBuildFile; fileRef = 113892260F6B70CA00A7D7DC /* laconica.png */; };
113900B10F85BEF60081A418 /* AIURLHandlerPreferences.xib in Resources */ = {isa = PBXBuildFile; fileRef = 113900B00F85BEF60081A418 /* AIURLHandlerPreferences.xib */; };
113900B40F85BF880081A418 /* AIURLHandlerWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 113900B30F85BF880081A418 /* AIURLHandlerWindowController.m */; };
1139011C0F85C9450081A418 /* AIURLHandlerPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 1139011B0F85C9450081A418 /* AIURLHandlerPlugin.m */; };
1139FFAA0F85260E0081A418 /* AIIRCChannelLinker.m in Sources */ = {isa = PBXBuildFile; fileRef = 1139FFA90F85260E0081A418 /* AIIRCChannelLinker.m */; };
- 113F26A00F5CC03F00954772 /* AITwitterURLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 113F269F0F5CC03F00954772 /* AITwitterURLParser.m */; };
114849B90F7841C600EA5264 /* AIAuthorizationRequestsWindowController.h in Headers */ = {isa = PBXBuildFile; fileRef = 114849B70F7841C600EA5264 /* AIAuthorizationRequestsWindowController.h */; settings = {ATTRIBUTES = (Public, ); }; };
114849BA0F7841C600EA5264 /* AIAuthorizationRequestsWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 114849B80F7841C600EA5264 /* AIAuthorizationRequestsWindowController.m */; };
114849BC0F78420300EA5264 /* AIAuthorizationRequestsWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 114849BB0F78420300EA5264 /* AIAuthorizationRequestsWindow.xib */; };
@@ -1033,6 +1028,7 @@
5A3B4D7C16D878AC00903E40 /* STTwitterOAuth.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A3B4D7216D878AB00903E40 /* STTwitterOAuth.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
5A3B4D7E16D878AC00903E40 /* STHTTPRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A3B4D7816D878AC00903E40 /* STHTTPRequest.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
5A44595E169143130078AB0A /* AIPreferenceCVPrototypeView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A445957169118C60078AB0A /* AIPreferenceCVPrototypeView.m */; };
+ 5A4B77E916FBDDC700DF398C /* NSData+Base64.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A4B77E716FBDDC600DF398C /* NSData+Base64.m */; }; 5A4BD41D13F855B000A4D3F7 /* SearchTerms.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5A4BD41B13F855B000A4D3F7 /* SearchTerms.plist */; };
5A4BD41E13F8568100A4D3F7 /* Preferences.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5ACF27331392C585004B6AEF /* Preferences.xib */; };
5A4BD43313F856E300A4D3F7 /* Preferences-AddressBookIntegration.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5AC7F26313B42952002D7265 /* Preferences-AddressBookIntegration.xib */; };
@@ -1847,8 +1843,6 @@
1139FFA90F85260E0081A418 /* AIIRCChannelLinker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIIRCChannelLinker.m; path = Source/AIIRCChannelLinker.m; sourceTree = "<group>"; };
113E06A910D0ABA0005D5B9A /* adiumPurpleMedia.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = adiumPurpleMedia.m; path = "Plugins/Purple Service/adiumPurpleMedia.m"; sourceTree = "<group>"; };
113E06AE10D0ABE3005D5B9A /* adiumPurpleMedia.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = adiumPurpleMedia.h; path = "Plugins/Purple Service/adiumPurpleMedia.h"; sourceTree = "<group>"; };
- 113F269E0F5CC03F00954772 /* AITwitterURLParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AITwitterURLParser.h; path = "Plugins/Twitter Plugin/AITwitterURLParser.h"; sourceTree = "<group>"; };
- 113F269F0F5CC03F00954772 /* AITwitterURLParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AITwitterURLParser.m; path = "Plugins/Twitter Plugin/AITwitterURLParser.m"; sourceTree = "<group>"; };
1147FCC210D1CB4C004E9E8D /* AIMediaWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIMediaWindowController.h; path = Source/AIMediaWindowController.h; sourceTree = "<group>"; };
1147FCC310D1CB4C004E9E8D /* AIMediaWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIMediaWindowController.m; path = Source/AIMediaWindowController.m; sourceTree = "<group>"; };
1147FCC710D1CB83004E9E8D /* AIMediaWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xib; name = AIMediaWindow.xib; path = Resources/AIMediaWindow.xib; sourceTree = "<group>"; };
@@ -3898,6 +3892,9 @@
5A3B4D7816D878AC00903E40 /* STHTTPRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = STHTTPRequest.m; path = "Plugins/Twitter Plugin/STTwitter/Vendor/STHTTPRequest.m"; sourceTree = "<group>"; };
5A445956169118C60078AB0A /* AIPreferenceCVPrototypeView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIPreferenceCVPrototypeView.h; path = Source/AIPreferenceCVPrototypeView.h; sourceTree = "<group>"; };
5A445957169118C60078AB0A /* AIPreferenceCVPrototypeView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIPreferenceCVPrototypeView.m; path = Source/AIPreferenceCVPrototypeView.m; sourceTree = "<group>"; };
+ 5A4B77E716FBDDC600DF398C /* NSData+Base64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSData+Base64.m"; path = "Plugins/Twitter Plugin/STTwitter/NSData+Base64.m"; sourceTree = "<group>"; }; + 5A4B77E816FBDDC700DF398C /* NSData+Base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSData+Base64.h"; path = "Plugins/Twitter Plugin/STTwitter/NSData+Base64.h"; sourceTree = "<group>"; }; + 5A4B77FA16FCABEC00DF398C /* Dock Tile Plugin.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Dock Tile Plugin.xcconfig"; sourceTree = "<group>"; }; 5A4BD41C13F855B000A4D3F7 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = en; path = Resources/en.lproj/SearchTerms.plist; sourceTree = "<group>"; };
5A4BD47213F858EE00A4D3F7 /* Preferences-ContactList.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = "Preferences-ContactList.xib"; path = "Resources/Preferences-ContactList.xib"; sourceTree = "<group>"; };
5A4BD48813F859EF00A4D3F7 /* Preferences-WindowHandling.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = "Preferences-WindowHandling.xib"; path = "Resources/Preferences-WindowHandling.xib"; sourceTree = "<group>"; };
@@ -5055,8 +5052,6 @@
11BD73D20F5A54BB007D438A /* twitter.png */,
EFB1C3120DDBDA3100B3973D /* AITwitterIMPlugin.h */,
EFB1C3130DDBDA3100B3973D /* AITwitterIMPlugin.m */,
- 113F269E0F5CC03F00954772 /* AITwitterURLParser.h */,
- 113F269F0F5CC03F00954772 /* AITwitterURLParser.m */,
112523170F5F7F86003FC58A /* AITwitterURLHandler.h */,
112523180F5F7F86003FC58A /* AITwitterURLHandler.m */,
11F738FA0F58D19B00B3285B /* AITwitterPlugin.h */,
@@ -7319,6 +7314,8 @@
5A3B4D6A16D878AB00903E40 /* STTwitter */ = {
+ 5A4B77E716FBDDC600DF398C /* NSData+Base64.m */, + 5A4B77E816FBDDC700DF398C /* NSData+Base64.h */, 5A0D236816F4C7BC005DF211 /* STTwitterAppOnly.m */,
5A0D236916F4C7BC005DF211 /* STTwitterAppOnly.h */,
5A3B4D6B16D878AB00903E40 /* NSString+STTwitter.h */,
@@ -8090,6 +8087,7 @@
63C7E1160FAFA35E00B310AC /* Plist Macros.xcconfig */,
63C7E1170FAFA35E00B310AC /* Setup Build Directory.xcconfig */,
63C7E11A0FAFA35E00B310AC /* AdiumApplescriptRunner.xcconfig */,
+ 5A4B77FA16FCABEC00DF398C /* Dock Tile Plugin.xcconfig */, @@ -10520,13 +10518,8 @@
11F738F90F58D18700B3285B /* AITwitterService.m in Sources */,
11F738FC0F58D19B00B3285B /* AITwitterPlugin.m in Sources */,
11F739020F58D1C400B3285B /* AITwitterAccountViewController.m in Sources */,
- 113F26A00F5CC03F00954772 /* AITwitterURLParser.m in Sources */,
112523190F5F7F86003FC58A /* AITwitterURLHandler.m in Sources */,
1109661A0F61D3E70064CA0E /* AITwitterReplyWindowController.m in Sources */,
- 113891830F6B6AFF00A7D7DC /* AILaconicaService.m in Sources */,
- 1138918A0F6B6B2800A7D7DC /* AILaconicaAccount.m in Sources */,
- 1138918D0F6B6B3F00A7D7DC /* AILaconicaPlugin.m in Sources */,
- 113891950F6B6B9C00A7D7DC /* AILaconicaAccountViewController.m in Sources */,
1163F0EC0F6C7A8300F12F5D /* AIURLShortenerPlugin.m in Sources */,
11700A350F7E8BE80078D6AB /* AISpecialPasswordPromptController.m in Sources */,
112B490A0F82FB1700690E84 /* AIGroupChatStatusTooltipPlugin.m in Sources */,
@@ -10571,6 +10564,7 @@
5A3B4D7C16D878AC00903E40 /* STTwitterOAuth.m in Sources */,
5A3B4D7E16D878AC00903E40 /* STHTTPRequest.m in Sources */,
5A0D236A16F4C7BC005DF211 /* STTwitterAppOnly.m in Sources */,
+ 5A4B77E916FBDDC700DF398C /* NSData+Base64.m in Sources */, runOnlyForDeploymentPostprocessing = 0;
@@ -12360,7 +12354,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 63C7E2050FAFAA4700B310AC /* Unit tests.xcconfig */;
- COMBINE_HIDPI_IMAGES = YES;
@@ -12368,7 +12361,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 63C7E2050FAFAA4700B310AC /* Unit tests.xcconfig */;
- COMBINE_HIDPI_IMAGES = YES;
@@ -12376,7 +12368,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 63C7E2050FAFAA4700B310AC /* Unit tests.xcconfig */;
- COMBINE_HIDPI_IMAGES = YES;
@@ -12384,11 +12375,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 63C7E2060FAFAA4700B310AC /* AdiumLibpurple.xcconfig */;
- COMBINE_HIDPI_IMAGES = YES;
- FRAMEWORK_SEARCH_PATHS = (
- "\"$(SRCROOT)/Frameworks\"",
@@ -12396,11 +12382,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 63C7E2060FAFAA4700B310AC /* AdiumLibpurple.xcconfig */;
- COMBINE_HIDPI_IMAGES = YES;
- FRAMEWORK_SEARCH_PATHS = (
- "\"$(SRCROOT)/Frameworks\"",
@@ -12408,11 +12389,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 63C7E2060FAFAA4700B310AC /* AdiumLibpurple.xcconfig */;
- COMBINE_HIDPI_IMAGES = YES;
- FRAMEWORK_SEARCH_PATHS = (
- "\"$(SRCROOT)/Frameworks\"",
@@ -12420,7 +12396,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 63C7E1150FAFA35E00B310AC /* Touch Framework Bundles to Executable Date.xcconfig */;
- COMBINE_HIDPI_IMAGES = YES;
@@ -12428,7 +12403,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 63C7E1150FAFA35E00B310AC /* Touch Framework Bundles to Executable Date.xcconfig */;
- COMBINE_HIDPI_IMAGES = YES;
@@ -12436,7 +12410,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 63C7E1150FAFA35E00B310AC /* Touch Framework Bundles to Executable Date.xcconfig */;
- COMBINE_HIDPI_IMAGES = YES;
@@ -12444,7 +12417,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 63C7E2030FAFAA4700B310AC /* AIUtilities.framework.xcconfig */;
- COMBINE_HIDPI_IMAGES = YES;
@@ -12452,7 +12424,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 63C7E2030FAFAA4700B310AC /* AIUtilities.framework.xcconfig */;
- COMBINE_HIDPI_IMAGES = YES;
@@ -12460,7 +12431,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 63C7E2030FAFAA4700B310AC /* AIUtilities.framework.xcconfig */;
- COMBINE_HIDPI_IMAGES = YES;
@@ -12468,7 +12438,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 63C7E2080FAFAA4700B310AC /* Spotlight Importer.xcconfig */;
- COMBINE_HIDPI_IMAGES = YES;
@@ -12476,7 +12445,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 63C7E2080FAFAA4700B310AC /* Spotlight Importer.xcconfig */;
- COMBINE_HIDPI_IMAGES = YES;
@@ -12484,12 +12452,12 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 63C7E2080FAFAA4700B310AC /* Spotlight Importer.xcconfig */;
- COMBINE_HIDPI_IMAGES = YES;
761CE34516F9087D000EE361 /* Debug */ = {
isa = XCBuildConfiguration;
+ baseConfigurationReference = 5A4B77FA16FCABEC00DF398C /* Dock Tile Plugin.xcconfig */; ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
@@ -12522,6 +12490,7 @@
761CE34616F9087D000EE361 /* Release */ = {
isa = XCBuildConfiguration;
+ baseConfigurationReference = 5A4B77FA16FCABEC00DF398C /* Dock Tile Plugin.xcconfig */; ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
@@ -12555,6 +12524,7 @@
761CE34716F9087D000EE361 /* Release-Debug */ = {
isa = XCBuildConfiguration;
+ baseConfigurationReference = 5A4B77FA16FCABEC00DF398C /* Dock Tile Plugin.xcconfig */; ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
@@ -12683,7 +12653,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 63C7E2070FAFAA4700B310AC /* Adium.framework.xcconfig */;
- COMBINE_HIDPI_IMAGES = YES;
@@ -12691,7 +12660,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 63C7E2070FAFAA4700B310AC /* Adium.framework.xcconfig */;
- COMBINE_HIDPI_IMAGES = YES;
@@ -12699,7 +12667,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 63C7E2070FAFAA4700B310AC /* Adium.framework.xcconfig */;
- COMBINE_HIDPI_IMAGES = YES;
@@ -12772,8 +12739,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 63C7E1170FAFA35E00B310AC /* Setup Build Directory.xcconfig */;
- COMBINE_HIDPI_IMAGES = YES;
- PRODUCT_NAME = "Setup Build Directory";
@@ -12781,8 +12746,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 63C7E1170FAFA35E00B310AC /* Setup Build Directory.xcconfig */;
- COMBINE_HIDPI_IMAGES = YES;
- PRODUCT_NAME = "Setup Build Directory";
@@ -12790,8 +12753,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 63C7E1170FAFA35E00B310AC /* Setup Build Directory.xcconfig */;
- COMBINE_HIDPI_IMAGES = YES;
- PRODUCT_NAME = "Setup Build Directory";
@@ -12799,7 +12760,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 63C7E1160FAFA35E00B310AC /* Plist Macros.xcconfig */;
- COMBINE_HIDPI_IMAGES = YES;
@@ -12807,7 +12767,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 63C7E1160FAFA35E00B310AC /* Plist Macros.xcconfig */;
- COMBINE_HIDPI_IMAGES = YES;
@@ -12815,7 +12774,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 63C7E1160FAFA35E00B310AC /* Plist Macros.xcconfig */;
- COMBINE_HIDPI_IMAGES = YES;
--- a/Plugins/Twitter Plugin/AITwitterAccount.m Thu Mar 21 00:01:23 2013 -0400
+++ b/Plugins/Twitter Plugin/AITwitterAccount.m Tue Apr 16 17:27:41 2013 +0200
@@ -15,7 +15,6 @@
#import "AITwitterAccount.h"
-#import "AITwitterURLParser.h"
#import "AITwitterReplyWindowController.h"
#import <AIUtilities/AIAttributedStringAdditions.h>
#import <AIUtilities/AIStringAdditions.h>
@@ -43,12 +42,12 @@
- (void)updateTimelineChat:(AIGroupChat *)timelineChat;
-- (NSAttributedString *)parseMessage:(NSString *)inMessage
- tweetID:(NSString *)tweetID
- userID:(NSString *)userID
- inReplyToUser:(NSString *)replyUserID
- inReplyToTweetID:(NSString *)replyTweetID;
-- (NSAttributedString *)parseDirectMessage:(NSString *)inMessage
+- (NSAttributedString *)parseStatus:(NSDictionary *)inStatus + tweetID:(NSString *)tweetID + userID:(NSString *)userID + inReplyToUser:(NSString *)replyUserID + inReplyToTweetID:(NSString *)replyTweetID; +- (NSAttributedString *)parseDirectMessage:(NSDictionary *)inMessage fromUser:(NSString *)sourceUID;
- (NSAttributedString *)attributedStringWithLinkLabel:(NSString *)label
@@ -613,21 +612,11 @@
AILogWithSignature(@"%@ Updating statuses for profile, user %@", self, inContact);
for (NSDictionary *update in statuses) {
- NSAttributedString *message;
- NSDictionary *retweet = [update valueForKey:TWITTER_STATUS_RETWEET];
- NSString *text = [update objectForKey:TWITTER_STATUS_TEXT];
- if (retweet && [retweet isKindOfClass:[NSDictionary class]]) {
- text = [NSString stringWithFormat:@"RT @%@: %@",
- [[retweet objectForKey:TWITTER_STATUS_USER] objectForKey:TWITTER_STATUS_UID],
- [retweet objectForKey:TWITTER_STATUS_TEXT]];
- message = [self parseMessage:text
- tweetID:[update objectForKey:TWITTER_STATUS_ID]
- inReplyToUser:[update objectForKey:TWITTER_STATUS_REPLY_UID]
- inReplyToTweetID:[update objectForKey:TWITTER_STATUS_REPLY_ID]];
+ NSAttributedString *message = [self parseStatus:update + tweetID:[update objectForKey:TWITTER_STATUS_ID] + inReplyToUser:[update objectForKey:TWITTER_STATUS_REPLY_UID] + inReplyToTweetID:[update objectForKey:TWITTER_STATUS_REPLY_ID]]; [profileArray addObject:[NSDictionary dictionaryWithObjectsAndKeys:message, KEY_VALUE, nil]];
@@ -904,7 +893,7 @@
[twitterEngine getRateLimitsForResources:@[ @"users", @"statuses", @"friendships", @"direct_messages" ]
successBlock:^(NSDictionary *rateLimits) {
NSMutableString *formattedString = [NSMutableString string];
- [rateLimits[@"resources"] enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
+ [[rateLimits objectForKey:@"resources"] enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { if ([obj isKindOfClass:[NSDictionary class]]) {
__block BOOL displayedHeader = NO;
[obj enumerateKeysAndObjectsUsingBlock:^(id subKey, id subObj, BOOL *subStop) {
@@ -929,7 +918,11 @@
- [[NSAlert alertWithMessageText:AILocalizedString(@"Current Twitter rate limits", "Message in the rate limits status window") defaultButton:nil alternateButton:nil otherButton:nil informativeTextWithFormat:@"%@", formattedString] beginSheetModalForWindow:nil modalDelegate:nil didEndSelector:nil contextInfo:nil];
+ [[NSAlert alertWithMessageText:AILocalizedString(@"Current Twitter rate limits", "Message in the rate limits status window") + informativeTextWithFormat:@"%@", formattedString] beginSheetModalForWindow:nil modalDelegate:nil didEndSelector:nil contextInfo:nil]; } errorBlock:^(NSError *error) {
[self requestFailed:AITwitterRateLimitStatus withError:error userInfo:nil];
@@ -1027,23 +1020,25 @@
[listContact setValue:[NSNumber numberWithBool:YES] forProperty:TWITTER_PROPERTY_REQUESTED_USER_ICON notify:NotifyNever];
// Grab the user icon and set it as their serverside icon.
- NSString *imageURL = [url stringByReplacingOccurrencesOfString:@"_normal." withString:@"_bigger."];
- NSURLRequest *imageRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:imageURL]];
- [NSURLConnection sendAsynchronousRequest:imageRequest
- queue:[NSOperationQueue currentQueue]
- completionHandler:^(NSURLResponse *resp, NSData *data, NSError *error) {
- NSImage *image = [[NSImage alloc] initWithData:data];
- AILogWithSignature(@"%@ Updated user icon for %@", self, listContact);
- [listContact setServersideIconData:[image TIFFRepresentation]
- [listContact setValue:nil forProperty:TWITTER_PROPERTY_REQUESTED_USER_ICON notify:NotifyNever];
- [self requestFailed:AITwitterUserIconPull withError:error userInfo:@{ @"ListContact" : listContact }];
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + NSString *imageURL = [url stringByReplacingOccurrencesOfString:@"_normal." withString:@"_bigger."]; + NSURLRequest *imageRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:imageURL]]; + NSData *data = [NSURLConnection sendSynchronousRequest:imageRequest returningResponse:nil error:&error]; + NSImage *image = [[NSImage alloc] initWithData:data]; + dispatch_async(dispatch_get_main_queue(), ^{ + AILogWithSignature(@"%@ Updated user icon for %@", self, listContact); + [listContact setServersideIconData:[image TIFFRepresentation] + [listContact setValue:nil forProperty:TWITTER_PROPERTY_REQUESTED_USER_ICON notify:NotifyNever]; + [self requestFailed:AITwitterUserIconPull withError:error userInfo:@{ @"ListContact" : listContact }]; @@ -1312,7 +1307,7 @@
} else if (linkType == AITwitterLinkUserPage) {
address = [NSString stringWithFormat:@"https://twitter.com/%@", userID];
} else if (linkType == AITwitterLinkSearchHash) {
- address = [NSString stringWithFormat:@"http://search.twitter.com/search?q=%%23%@", context];
+ address = [NSString stringWithFormat:@"http://twitter.com/search?q=%%23%@", context]; } else if (linkType == AITwitterLinkReply) {
address = [NSString stringWithFormat:@"twitterreply://%@@%@?action=reply&status=%@", self.internalObjectID, userID, statusID];
} else if (linkType == AITwitterLinkRetweet) {
@@ -1480,61 +1475,89 @@
* @brief Parse an attributed string into a linkified version.
-- (NSAttributedString *)linkifiedAttributedStringFromString:(NSAttributedString *)inString
- NSAttributedString *attributedString;
- static NSCharacterSet *usernameCharacters = nil;
- static NSCharacterSet *hashCharacters = nil;
- if (!usernameCharacters) {
- usernameCharacters = [NSCharacterSet characterSetWithCharactersInString:@"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"];
- NSMutableCharacterSet *disallowedCharacters = [[NSCharacterSet punctuationCharacterSet] mutableCopy];
- [disallowedCharacters formUnionWithCharacterSet:[NSCharacterSet whitespaceCharacterSet]];
- [disallowedCharacters removeCharactersInString:@"_"];
+- (void)linkifyEntities:(NSArray *)entities inString:(NSMutableAttributedString **)inString forLinkType:(AITwitterLinkType)linkType { + [entities enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + NSString *userID = nil; + NSString *context = nil; + if (linkType == AITwitterLinkUserPage) { + userID = [obj objectForKey:@"screen_name"]; + text = [NSString stringWithFormat:@"@%@", userID]; + } else if (linkType == AITwitterLinkSearchHash) { + context = [obj objectForKey:@"text"]; + text = [NSString stringWithFormat:@"#%@", context]; - hashCharacters = [disallowedCharacters invertedSet];
- attributedString = [AITwitterURLParser linkifiedStringFromAttributedString:inString
- forPrefixCharacter:@"@"
- forLinkType:AITwitterLinkUserPage
- validCharacterSet:usernameCharacters];
- attributedString = [AITwitterURLParser linkifiedStringFromAttributedString:attributedString
- forPrefixCharacter:@"#"
- forLinkType:AITwitterLinkSearchHash
- validCharacterSet:hashCharacters];
- return attributedString;
+ NSString *linkURL = [self addressForLinkType:linkType + [*inString replaceOccurrencesOfString:text + attributes:@{ NSLinkAttributeName : linkURL } + options:NSCaseInsensitiveSearch + range:NSMakeRange(0, [*inString length])]; * @brief Parses a Twitter message into an attributed string
-- (NSAttributedString *)parseMessage:(NSString *)inMessage
- tweetID:(NSString *)tweetID
- userID:(NSString *)userID
- inReplyToUser:(NSString *)replyUserID
- inReplyToTweetID:(NSString *)replyTweetID
+- (NSAttributedString *)parseStatus:(NSDictionary *)inStatus + tweetID:(NSString *)tweetID + userID:(NSString *)userID + inReplyToUser:(NSString *)replyUserID + inReplyToTweetID:(NSString *)replyTweetID - NSAttributedString *message;
+ NSMutableAttributedString *mutableMessage; + NSDictionary *retweet = [inStatus objectForKey:TWITTER_STATUS_RETWEET]; + if (retweet && [retweet isKindOfClass:[NSDictionary class]]) { + NSString *text = [[retweet objectForKey:TWITTER_STATUS_TEXT] stringByUnescapingFromXMLWithEntities:nil]; + mutableMessage = [[NSMutableAttributedString alloc] initWithString:text]; + [mutableMessage replaceCharactersInRange:NSMakeRange(0, 0) + withString:[NSString stringWithFormat:@"RT @%@: ", + [[retweet objectForKey:TWITTER_STATUS_USER] objectForKey:TWITTER_STATUS_UID]]]; + NSString *text = [[inStatus objectForKey:TWITTER_STATUS_TEXT] stringByUnescapingFromXMLWithEntities:nil]; + mutableMessage = [[NSMutableAttributedString alloc] initWithString:text]; - message = [NSAttributedString stringWithString:[inMessage stringByUnescapingFromXMLWithEntities:nil]];
+ //Extract hashtags, users, and URLs + NSDictionary *entities = [inStatus objectForKey:@"entities"]; + NSArray *hashtags = [entities objectForKey:@"hashtags"]; + NSArray *urls = [entities objectForKey:@"urls"]; + NSArray *users = [entities objectForKey:@"user_mentions"]; + NSArray *media = [entities objectForKey:@"media"]; + [self linkifyEntities:users inString:&mutableMessage forLinkType:AITwitterLinkUserPage]; + [self linkifyEntities:hashtags inString:&mutableMessage forLinkType:AITwitterLinkSearchHash]; + [urls enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + NSString *linkURL = [obj objectForKey:@"url"]; + NSString *expandedURL = [obj objectForKey:@"expanded_url"]; + [mutableMessage replaceOccurrencesOfString:linkURL + attributes:@{ NSLinkAttributeName : linkURL } + options:NSLiteralSearch + range:NSMakeRange(0, mutableMessage.length)]; + [media enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + NSString *linkURL = [obj objectForKey:@"url"]; + NSString *displayURL = [obj objectForKey:@"display_url"]; + [mutableMessage replaceOccurrencesOfString:linkURL + attributes:@{ NSLinkAttributeName : linkURL } + options:NSLiteralSearch + range:NSMakeRange(0, mutableMessage.length)]; - message = [self linkifiedAttributedStringFromString:message];
+ NSString *message = [mutableMessage string]; BOOL replyTweet = (replyTweetID.length > 0);
BOOL tweetLink = (tweetID.length && userID.length);
if (replyTweet || tweetLink) {
- NSMutableAttributedString *mutableMessage = [message mutableCopy];
NSUInteger startIndex = message.length;
[mutableMessage appendString:@" (" withAttributes:nil];
@@ -1548,9 +1571,9 @@
- if([inMessage hasPrefix:@"@"] &&
- inMessage.length >= replyUserID.length + 1 &&
- [replyUserID isCaseInsensitivelyEqualToString:[inMessage substringWithRange:NSMakeRange(1, replyUserID.length)]]) {
+ if([message hasPrefix:@"@"] && + message.length >= replyUserID.length + 1 && + [replyUserID isCaseInsensitivelyEqualToString:[message substringWithRange:NSMakeRange(1, replyUserID.length)]]) { // If the message has a "@" prefix, it's a proper in_reply_to_status_id if the usernames match. Set a link appropriately.
[mutableMessage setAttributes:[NSDictionary dictionaryWithObjectsAndKeys:linkAddress, NSLinkAttributeName, nil]
range:NSMakeRange(0, replyUserID.length + 1)];
@@ -1598,7 +1621,7 @@
linkAddress = [self addressForLinkType:AITwitterLinkQuote
- context:[inMessage stringByAddingPercentEscapesForAllCharacters]];
+ context:[message stringByAddingPercentEscapesForAllCharacters]]; #define PILCROW_SIGN @"\u00B6"
@@ -1630,7 +1653,7 @@
linkAddress = [self addressForLinkType:AITwitterLinkDestroyStatus
- context:[inMessage stringByAddingPercentEscapesForAllCharacters]];
+ context:[message stringByAddingPercentEscapesForAllCharacters]]; [mutableMessage appendAttributedString:[self attributedStringWithLinkLabel:@"\u232B"
linkDestination:linkAddress
@@ -1670,24 +1693,25 @@
+ return [[NSAttributedString alloc] initWithString:message]; * @brief Parse a direct message
-- (NSAttributedString *)parseDirectMessage:(NSString *)inMessage
+- (NSAttributedString *)parseDirectMessage:(NSDictionary *)inMessage fromUser:(NSString *)sourceUID
- NSAttributedString *message;
- message = [NSAttributedString stringWithString:[inMessage stringByUnescapingFromXMLWithEntities:nil]];
+ NSString *message = [[inMessage objectForKey:TWITTER_DM_TEXT] stringByUnescapingFromXMLWithEntities:nil]; + NSMutableAttributedString *mutableMessage = [[NSMutableAttributedString alloc] initWithString:message]; - message = [self linkifiedAttributedStringFromString:message];
- NSMutableAttributedString *mutableMessage = [message mutableCopy];
+ NSDictionary *entities = [inMessage objectForKey:@"entities"]; + NSArray *hashtags = [entities objectForKey:@"hashtags"]; + NSArray *users = [entities objectForKey:@"user_mentions"]; + [self linkifyEntities:users inString:&mutableMessage forLinkType:AITwitterLinkUserPage]; + [self linkifyEntities:hashtags inString:&mutableMessage forLinkType:AITwitterLinkSearchHash]; NSUInteger startIndex = message.length;
@@ -1696,7 +1720,7 @@
NSString *linkAddress = [self addressForLinkType:AITwitterLinkDestroyDM
- context:[inMessage stringByAddingPercentEscapesForAllCharacters]];
+ context:[message stringByAddingPercentEscapesForAllCharacters]]; [mutableMessage appendAttributedString:[self attributedStringWithLinkLabel:@"\u232B"
linkDestination:linkAddress
@@ -1783,26 +1807,22 @@
[[AIContactObserverManager sharedManager] delayListObjectNotifications];
for (NSDictionary *status in sortedQueuedUpdates) {
- NSDictionary *retweet = [status objectForKey:TWITTER_STATUS_RETWEET];
- NSString *text = [status objectForKey:TWITTER_STATUS_TEXT];
- if (retweet && [retweet isKindOfClass:[NSDictionary class]]) {
- text = [NSString stringWithFormat:@"RT @%@: %@",
- [[retweet objectForKey:TWITTER_STATUS_USER] objectForKey:TWITTER_STATUS_UID],
- [retweet objectForKey:TWITTER_STATUS_TEXT]];
+ NSString *contactUID = [[status objectForKey:TWITTER_STATUS_USER] objectForKey:TWITTER_STATUS_UID]; + NSAttributedString *message = [self parseStatus:status + tweetID:[status objectForKey:TWITTER_STATUS_ID] + inReplyToUser:[status objectForKey:TWITTER_STATUS_REPLY_UID] + inReplyToTweetID:[status objectForKey:TWITTER_STATUS_REPLY_ID]]; NSDate *date = [status objectForKey:TWITTER_STATUS_CREATED];
- NSString *contactUID = [[status objectForKey:TWITTER_STATUS_USER] objectForKey:TWITTER_STATUS_UID];
if (![self.UID isCaseInsensitivelyEqualToString:contactUID]) {
AIListContact *listContact = [self contactWithUID:contactUID];
// Update the user's status message
- [listContact setStatusMessage:[NSAttributedString stringWithString:[text stringByUnescapingFromXMLWithEntities:nil]]
+ [listContact setStatusMessage:message [self updateUserIcon:[[status objectForKey:TWITTER_STATUS_USER] objectForKey:TWITTER_INFO_ICON] forContact:listContact];
@@ -1814,12 +1834,6 @@
- NSAttributedString *message = [self parseMessage:text
- tweetID:[status objectForKey:TWITTER_STATUS_ID]
- inReplyToUser:[status objectForKey:TWITTER_STATUS_REPLY_UID]
- inReplyToTweetID:[status objectForKey:TWITTER_STATUS_REPLY_ID]];
AIContentMessage *contentMessage = [AIContentMessage messageInChat:timelineChat
@@ -1848,7 +1862,6 @@
for (NSDictionary *message in sortedQueuedDM) {
NSDate *date = [NSDate dateWithNaturalLanguageString:[message objectForKey:TWITTER_DM_CREATED]];
- NSString *text = [message objectForKey:TWITTER_DM_TEXT];
NSString *fromUID = [message objectForKey:TWITTER_DM_SENDER_UID];
NSString *toUID = [message objectForKey:TWITTER_DM_RECIPIENT_UID];
@@ -1871,7 +1884,7 @@
- message:[self parseDirectMessage:text
+ message:[self parseDirectMessage:message withID:[message objectForKey:TWITTER_DM_ID]
fromUser:chat.listObject.UID]
@@ -2225,35 +2238,36 @@
[self setValue:[userInfo objectForKey:@"location"] forProperty:@"Profile Location" notify:NotifyLater];
[self setValue:[userInfo objectForKey:@"description"] forProperty:@"Profile Description" notify:NotifyLater];
- NSString *imageURL = [userInfo objectForKey:TWITTER_INFO_ICON];
- NSURLRequest *imageRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:imageURL]];
- [NSURLConnection sendAsynchronousRequest:imageRequest
- queue:[NSOperationQueue currentQueue]
- completionHandler:^(NSURLResponse *resp, NSData *data, NSError *error) {
- NSImage *image = [[NSImage alloc] initWithData:data];
- AILogWithSignature(@"Updated self icon for %@", self);
- // Set a property so that we don't re-send the image we're just now downloading.
- [self setValue:[NSNumber numberWithBool:YES] forProperty:TWITTER_PROPERTY_REQUESTED_USER_ICON notify:NotifyNever];
- [self setPreference:[NSNumber numberWithBool:YES]
- forKey:KEY_USE_USER_ICON
- group:GROUP_ACCOUNT_STATUS];
- [self setPreference:[image TIFFRepresentation]
- group:GROUP_ACCOUNT_STATUS];
- [self notifyOfChangedPropertiesSilently:NO];
- [self setValue:nil forProperty:TWITTER_PROPERTY_REQUESTED_USER_ICON notify:NotifyNever];
- [self requestFailed:AITwitterSelfUserIconPull withError:error userInfo:nil];
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + NSString *imageURL = [userInfo objectForKey:TWITTER_INFO_ICON]; + NSURLRequest *imageRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:imageURL]]; + NSData *data = [NSURLConnection sendSynchronousRequest:imageRequest returningResponse:nil error:&error]; + NSImage *image = [[NSImage alloc] initWithData:data]; + dispatch_async(dispatch_get_main_queue(), ^{ + AILogWithSignature(@"Updated self icon for %@", self); + // Set a property so that we don't re-send the image we're just now downloading. + [self setValue:[NSNumber numberWithBool:YES] forProperty:TWITTER_PROPERTY_REQUESTED_USER_ICON notify:NotifyNever]; + [self setPreference:[NSNumber numberWithBool:YES] + forKey:KEY_USE_USER_ICON + group:GROUP_ACCOUNT_STATUS]; + [self setPreference:[image TIFFRepresentation] + group:GROUP_ACCOUNT_STATUS]; + [self notifyOfChangedPropertiesSilently:NO]; + [self setValue:nil forProperty:TWITTER_PROPERTY_REQUESTED_USER_ICON notify:NotifyNever]; + [self requestFailed:AITwitterSelfUserIconPull withError:error userInfo:nil]; --- a/Plugins/Twitter Plugin/STTwitter/STTwitterAPIWrapper.m Thu Mar 21 00:01:23 2013 -0400
+++ b/Plugins/Twitter Plugin/STTwitter/STTwitterAPIWrapper.m Tue Apr 16 17:27:41 2013 +0200
@@ -18,6 +18,10 @@
@implementation STTwitterAPIWrapper
+@synthesize oauth = _oauth; +@synthesize consumerName = _consumerName; +@synthesize userName = _userName; @@ -183,8 +187,8 @@
mparams = [NSMutableDictionary new];
- if (optionalSinceID) mparams[@"since_id"] = optionalSinceID;
- if (optionalCount != NSNotFound) mparams[@"count"] = [@(optionalCount) stringValue];
+ if (optionalSinceID) [mparams setObject:optionalSinceID forKey:@"since_id"]; + if (optionalCount != NSNotFound) [mparams setObject:[@(optionalCount) stringValue] forKey:@"count"]; __block NSMutableArray *statuses = [NSMutableArray new];
__block void (^requestHandler)(id response) = nil;
@@ -200,7 +204,7 @@
NSUInteger maxID = [[NSDecimalNumber decimalNumberWithString:lastID] unsignedIntegerValue];
- mparams[@"max_id"] = [@(--maxID) stringValue];
+ [mparams setObject:[@(--maxID) stringValue] forKey:@"max_id"]; [_oauth getResource:timeline parameters:mparams
@@ -293,16 +297,16 @@
NSMutableDictionary *md = [NSMutableDictionary dictionaryWithObject:status forKey:@"status"];
if(optionalExistingStatusID) {
- md[@"in_reply_to_status_id"] = optionalExistingStatusID;
+ [md setObject:optionalExistingStatusID forKey:@"in_reply_to_status_id"]; - md[@"place_id"] = optionalPlaceID;
- md[@"display_coordinates"] = @"true";
+ [md setObject:optionalPlaceID forKey:@"place_id"]; + [md setObject:@"true" forKey:@"display_coordinates"]; } else if(optionalLat && optionalLon) {
- md[@"lat"] = optionalLat;
- md[@"lon"] = optionalLon;
- md[@"display_coordinates"] = @"true";
+ [md setObject:optionalLat forKey:@"lat"]; + [md setObject:optionalLon forKey:@"lon"]; + [md setObject:@"true" forKey:@"display_coordinates"]; [_oauth postResource:@"statuses/update.json" parameters:md successBlock:^(id response) {
@@ -326,16 +330,16 @@
NSMutableDictionary *md = [[ @{ @"status":status, @"media[]":data, @"postDataKey":@"media[]" } mutableCopy] autorelease];
if(optionalExistingStatusID) {
- md[@"in_reply_to_status_id"] = optionalExistingStatusID;
+ [md setObject:optionalExistingStatusID forKey:@"in_reply_to_status_id"]; - md[@"place_id"] = optionalPlaceID;
- md[@"display_coordinates"] = @"true";
+ [md setObject:optionalPlaceID forKey:@"place_id"]; + [md setObject:@"true" forKey:@"display_coordinates"]; } else if(optionalLat && optionalLon) {
- md[@"lat"] = optionalLat;
- md[@"lon"] = optionalLon;
- md[@"display_coordinates"] = @"true";
+ [md setObject:optionalLat forKey:@"lat"]; + [md setObject:optionalLon forKey:@"lon"]; + [md setObject:@"true" forKey:@"display_coordinates"]; [_oauth postResource:@"statuses/update_with_media.json" parameters:md successBlock:^(id response) {
@@ -431,7 +435,7 @@
[ids addObjectsFromArray:[response objectForKey:@"users"]];
cursor = [[response objectForKey:@"next_cursor_str"] copy];
+ [d setObject:cursor forKey:@"cursor"]; if ([cursor isEqualToString:@"0"]) {
@@ -487,7 +491,7 @@
successBlock:(void(^)(NSDictionary *relationship))successBlock
errorBlock:(void(^)(NSError *error))errorBlock {
NSMutableDictionary *d = [NSMutableDictionary dictionaryWithObject:screenName forKey:@"screen_name"];
- d[@"device"] = notify ? @"true" : @"false";
+ [d setObject:notify ? @"true" : @"false" forKey:@"device"]; [_oauth getResource:@"friendships/update.json" parameters:d successBlock:^(id response) {
successBlock(removeNull(response));
--- a/Plugins/Twitter Plugin/STTwitter/STTwitterOAuth.m Thu Mar 21 00:01:23 2013 -0400
+++ b/Plugins/Twitter Plugin/STTwitter/STTwitterOAuth.m Tue Apr 16 17:27:41 2013 +0200
@@ -9,13 +9,11 @@
#import "STTwitterOAuth.h"
#import "STHTTPRequest.h"
#import "NSString+STTwitter.h"
+#import "NSData+Base64.h" #include <CommonCrypto/CommonHMAC.h>
-@interface NSData (Base64)
-- (NSString *)base64Encoding; // private API
@interface STTwitterOAuth ()
@property (nonatomic, retain) NSString *username;
@@ -38,6 +36,18 @@
@implementation STTwitterOAuth
+@synthesize username = _username; +@synthesize password = _password; +@synthesize oauthConsumerName = _oauthConsumerName; +@synthesize oauthConsumerKey = _oauthConsumerKey; +@synthesize oauthConsumerSecret = _oauthConsumerSecret; +@synthesize oauthRequestToken = _oauthRequestToken; +@synthesize oauthRequestTokenSecret = _oauthRequestTokenSecret; +@synthesize oauthAccessToken = _oauthAccessToken; +@synthesize oauthAccessTokenSecret = _oauthAccessTokenSecret; +@synthesize testOauthNonce = _testOauthNonce; +@synthesize testOauthTimestamp = _testOauthTimestamp; @@ -276,8 +286,8 @@
NSURL *url = [NSURL URLWithString:s];
- self.oauthRequestToken = d[@"oauth_token"];
- self.oauthRequestTokenSecret = d[@"oauth_token_secret"]; // unused
+ self.oauthRequestToken = [d objectForKey:@"oauth_token"]; + self.oauthRequestTokenSecret = [d objectForKey:@"oauth_token_secret"]; // unused successBlock(url, _oauthRequestToken);
@@ -303,10 +313,10 @@
// https://api.twitter.com/oauth/authorize?oauth_token=OAUTH_TOKEN&oauth_token_secret=OAUTH_TOKEN_SECRET&user_id=USER_ID&screen_name=SCREEN_NAME
- self.oauthAccessToken = dict[@"oauth_token"];
- self.oauthAccessTokenSecret = dict[@"oauth_token_secret"];
+ self.oauthAccessToken = [dict objectForKey:@"oauth_token"]; + self.oauthAccessTokenSecret = [dict objectForKey:@"oauth_token_secret"]; - successBlock(_oauthAccessToken, _oauthAccessTokenSecret, dict[@"user_id"], dict[@"screen_name"]);
+ successBlock(_oauthAccessToken, _oauthAccessTokenSecret, [dict objectForKey:@"user_id"], [dict objectForKey:@"screen_name"]); } errorBlock:^(NSError *error) {
@@ -333,10 +343,10 @@
// https://api.twitter.com/oauth/authorize?oauth_token=OAUTH_TOKEN&oauth_token_secret=OAUTH_TOKEN_SECRET&user_id=USER_ID&screen_name=SCREEN_NAME
- self.oauthAccessToken = dict[@"oauth_token"];
- self.oauthAccessTokenSecret = dict[@"oauth_token_secret"];
+ self.oauthAccessToken = [dict objectForKey:@"oauth_token"]; + self.oauthAccessTokenSecret = [dict objectForKey:@"oauth_token_secret"]; - successBlock(_oauthAccessToken, _oauthAccessTokenSecret, dict[@"user_id"], dict[@"screen_name"]);
+ successBlock(_oauthAccessToken, _oauthAccessTokenSecret, [dict objectForKey:@"user_id"], [dict objectForKey:@"screen_name"]); } errorBlock:^(NSError *error) {
@@ -426,7 +436,7 @@
r.completionBlock = ^(NSDictionary *headers, NSString *body) {
NSError *jsonError = nil;
- id json = [NSJSONSerialization JSONObjectWithData:r.responseData options:NSJSONReadingMutableLeaves error:&jsonError];
+ id json = [r.responseData objectFromJSONDataWithParseOptions:JKParseOptionNone error:&jsonError]; @@ -478,10 +488,10 @@
r.completionBlock = ^(NSDictionary *headers, NSString *body) {
NSError *jsonError = nil;
- id json = [NSJSONSerialization JSONObjectWithData:r.responseData options:NSJSONReadingMutableLeaves error:&jsonError];
+ id json = [r.responseData objectFromJSONDataWithParseOptions:JKParseOptionNone error:&jsonError];
+ successBlock(body); // response is not necessarily json, eg. https://api.twitter.com/oauth/request_token @@ -554,7 +564,7 @@
NSArray *kv = [s componentsSeparatedByString:@"="];
NSAssert([kv count] == 2, @"-- bad length");
if([kv count] != 2) continue;
- [ma addObject:@{kv[0] : kv[1]}];
+ [ma addObject:@{[kv objectAtIndex:0] : [kv objectAtIndex:1]}]; @@ -588,7 +598,7 @@
unsigned char buf[CC_SHA1_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA1, [key UTF8String], [key length], [self UTF8String], [self length], buf);
NSData *data = [NSData dataWithBytes:buf length:CC_SHA1_DIGEST_LENGTH];
- return [data base64Encoding];
+ return [data base64EncodedString]; - (NSDictionary *)parametersDictionary {
@@ -603,7 +613,7 @@
- [md setObject:keyValue[1] forKey:keyValue[0]];
+ [md setObject:[keyValue objectAtIndex:1] forKey:[keyValue objectAtIndex:0]]; @@ -618,33 +628,3 @@
-@implementation NSData (STTwitterOAuth)
-- (NSString *)base64EncodedString {
- return [self base64Encoding]; // private API
- CFDataRef retval = NULL;
- SecTransformRef encodeTrans = SecEncodeTransformCreate(kSecBase64Encoding, NULL);
- if (encodeTrans == NULL) return nil;
- if (SecTransformSetAttribute(encodeTrans, kSecTransformInputAttributeName, (CFDataRef)self, NULL)) {
- retval = SecTransformExecute(encodeTrans, NULL);
- CFRelease(encodeTrans);
- NSString *s = [[NSString alloc] initWithData:(NSData *)retval encoding:NSUTF8StringEncoding];
- return [s autorelease];