Tuesday, May 17, 2016

How To: Fix XCode 7 Lag

Hello darlings. This is not a coding tutorial but related to XCode so I post here.

XCode lag when switching between files?

I am using XCode 7.2.1 and Yosemite, and suddenly XCode lags when trying to switch between ViewControllers. I have tried many solutions suggested in internet:

1. Clear Derived Data
2. Clear Archives
3. Disable Spotlight Indexing

These somewhat make XCode works faster when building apps, but lags is still there when Im switching btw viewcontroller and/or xib files.

The lag also happens intermittently. Which makes it hard to figure out what's causing the problem. Then I searched further and found some people talking about TOOLTIPS in Apple Forum.

It seems to be the root cause. If you have files with long filenames (such as below):

Everytime your mouse hovers those truncated filenames, XCode tries to show tooltip for it, and that's when the lag happens.

What you do? Just WIDEN THE LEFT PANE. This seems to work for me. Do note though- after you widen it, and then you narrow it back, it becomes totally ok only after a while, it lags again. Just leave the pane widened till there is no "..." in the file names and you'd be okay all the way.

This is really funny problem I hope XCode devs team fix it soon. 

Tuesday, January 12, 2016

How To: Using SLRequest to Upload Image or Video To Twitter

Hi guys what's up. This is a simple tutorial so it doesn't have any downloadable project.

Today I'd like to share with you how to upload an image (like JPEG or GIF animation) to Twitter from the iOS app.

For a normal JPEG and status upload, you can use SLComposeViewController but you will face problem if you want to upload GIF animation or video file. That is because SLComposeViewController only has "addImage" method that takes up a UIImage object.

So you have to use SLRequest - a low level API communicator.

There was a simple API request called "upload_with_media" but Twitter has DEPRECATED it. It works now, but it may not work anymore in the near future and thus may break your app if you use that. So now you need to use 2 APIs to tweet text and image in one tweet. The processes involved is basically 2 - tiered jobs:

1. Upload image first - you will get the media id after upload completes
2. Update status with text and the media ID

As usual you have to request access to Twitter account before you can do anything with it. Once access is granted by user, you can then proceed to instantiate requests to twitter API host. Here's how to upload a media to Twitter's Media server:


NSData *imageData = [NSData dataWithContentsOfURL:fileURL];
NSURL *requestURL = [NSURL URLWithString:@"https://upload.twitter.com/1.1/media/upload.json"];
                    
SLRequest *postRequest = [SLRequest 
                                              requestForServiceType:SLServiceTypeTwitter
                                              requestMethod:SLRequestMethodPOST
                                              URL:requestURL parameters:nil;
                    
postRequest.account = twitterAccount;
[postRequest addMultipartData:imageData
                                         withName:@"media"
                                             type:@"image/gif"
                                         filename:@"test.gif"];
                    
[postRequest performRequestWithHandler:^(NSData *responseData,
                                                 NSHTTPURLResponse *urlResponse, NSError *error)
                     {

First, convert your image/video into NSData. Then create an SLRequest with NIL PARAMETERS with POST method as in code above. Set the request's account. Then add multipart data to the request.

The data type must be matching to what you're uploading. If it's a JPG then use "image/jpeg" if it's a GIF then use "image/gif" etc. Finally perform the request to start uploading the image to twitter's media server. This may take a while so you should have a UIActivityViewController pop up when doing this.

When the request is completed, the method will return responseData in JSON format. Convert this data into JSON.

Example of JSON data returned from twitter:
 
{
    "expires_after_secs" = 86400;
    image =     {
        h = 400;
        "image_type" = "image/gif";
        w = 400;
    };
    "media_id" = 687171095254859776;
    "media_id_string" = 687171095254859776; ---- THIS IS WHAT YOU NEED
    size = 705439;
}

Retrieve the media ID string as follows:
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:nil];
NSString *mediaID = [json objectForKey:@"media_id_string"];

Once you get the mediaID, you can then tweet a text with this ID using /statuses/update.json API.

 
NSURL *requestURL2 = [NSURL URLWithString:@"https://api.twitter.com/1.1/statuses/update.json"];
NSDictionary *message2 = @{@"status": @"Here is image",
                                                    @"media_ids": mediaID };
                         
SLRequest *postRequest2 = [SLRequest
                                                   requestForServiceType:SLServiceTypeTwitter
                                                   requestMethod:SLRequestMethodPOST
                                                   URL:requestURL2 parameters:message2];
postRequest2.account = twitterAccount;
                         
[postRequest2 performRequestWithHandler:^(NSData *responseData,
                                                      NSHTTPURLResponse *urlResponse, NSError *error)
                          {

The second request is just the same method performRequestWithHandler but with different requestURL. And that's how it's done.

Here is the complete code (including requesting access to twitter account):

 

-(void)uploadImageToTwitter {


        
        ACAccountStore *account = [[ACAccountStore alloc] init];
        ACAccountType *accountType = [account accountTypeWithAccountTypeIdentifier:
                                      ACAccountTypeIdentifierTwitter];
        
        [account requestAccessToAccountsWithType:accountType options:nil
                                      completion:^(BOOL granted, NSError *error)
        {
            if (granted == YES)
            {
                NSArray *arrayOfAccounts = [account
                                            accountsWithAccountType:accountType];
                
                if ([arrayOfAccounts count] > 0)
                {
                    ACAccount *twitterAccount =
                    [arrayOfAccounts lastObject];
                    
                    
                    NSURL *furl = [NSURL fileURLWithPath:NSTemporaryDirectory()];
                    NSURL *fileURL = [furl URLByAppendingPathComponent:@"animation.gif"];
                    NSData *imageData = [NSData dataWithContentsOfURL:fileURL];
                   
                    NSURL *requestURL = [NSURL URLWithString:@"https://upload.twitter.com/1.1/media/upload.json"];
                    
                    SLRequest *postRequest = [SLRequest 
                                              requestForServiceType:SLServiceTypeTwitter
                                              requestMethod:SLRequestMethodPOST
                                              URL:requestURL parameters:nil];
                    
                    postRequest.account = twitterAccount;
                    
                    [postRequest addMultipartData:imageData
                                         withName:@"media"
                                             type:@"image/gif"
                                         filename:@"test.gif"];
                    
                    [postRequest
                     performRequestWithHandler:^(NSData *responseData,
                                                 NSHTTPURLResponse *urlResponse, NSError *error)
                     {
                         
                         
                          NSDictionary *json = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:nil];
                         
                         NSString *mediaID = [json objectForKey:@"media_id_string"];
                         
                         
                         if (mediaID!=nil) {
                             
                         
                             NSURL *requestURL2 = [NSURL URLWithString:@"https://api.twitter.com/1.1/statuses/update.json"];
                         NSDictionary *message2 = @{@"status": @"Here is the image",
                                                    @"media_ids": mediaID };
                         
                         SLRequest *postRequest2 = [SLRequest
                                                   requestForServiceType:SLServiceTypeTwitter
                                                   requestMethod:SLRequestMethodPOST
                                                   URL:requestURL2 parameters:message2];
                         postRequest2.account = twitterAccount;
                         
                         [postRequest2
                          performRequestWithHandler:^(NSData *responseData,
                                                      NSHTTPURLResponse *urlResponse, NSError *error)
                          {
                             // DONE!!!

                          }];
                             
                         }
                         
                     }];
                }
            }
         }];


That's all FOLKS!
Related Posts Plugin for WordPress, Blogger...