jose920405
jose920405

Reputation: 8049

Instagram hooks pre-select media issue

This is my code. The file is correctly added to photos library, but in instagram app this url -> instagram://library?AssetPath=assets-library%3A%2F%2Fasset%2Fasset.mp4%3Fid=5EDBD113-FF57-476B-AABB-6A59F31170B5&ext=mp4&InstagramCaption=my%caption don't open the last video.

- (void)loadCameraRollAssetToInstagram:(NSURL*)assetsLibraryURL andMessage:(NSString*)message
{
    NSString *escapedString   = [self urlencodedString:assetsLibraryURL.absoluteString];
    NSString *escapedCaption  = [self urlencodedString:message];
    NSURL *instagramURL       = [NSURL URLWithString:[NSString stringWithFormat:@"instagram://library?AssetPath=%@&InstagramCaption=%@", escapedString, escapedCaption]];

    NSLog(@"instagramURL ==> %@",instagramURL);

    if ([[UIApplication sharedApplication] canOpenURL:instagramURL]) {
        NSLog(@"Open Instagram!!");
        [[UIApplication sharedApplication] openURL:instagramURL];
    } else {
        NSLog(@"Cant open Instagram!!");
        [[[UIAlertView alloc] initWithTitle:@"Instagram" message:@"App not installed" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil] show];
    }
}

- (NSString*)urlencodedString:(NSString *)message
{
    return [message stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]];
}

- (void)saveToCameraRoll:(NSURL *)srcURL withCurrentAction:(NSString *)action
{
    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
    ALAssetsLibraryWriteVideoCompletionBlock videoWriteCompletionBlock = ^(NSURL *newURL, NSError *error) {

        if (error) {
            NSLog( @"Error writing image with metadata to Photo Library: %@", error );
            [[[UIAlertView alloc] initWithTitle:@"Facebook" message:@"Pal - Currently we can't process your video. Please try again in few moments" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Sign In", nil] show];

        } else {
            NSLog( @"Wrote image with metadata to Photo Library: %@", newURL.absoluteString);
            if ([action isEqualToString:@"instagram"])
                [self loadCameraRollAssetToInstagram:newURL andMessage:@"My caption"]; //Can be any text?
        }
    };

    if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:srcURL])
    {
        [library writeVideoAtPathToSavedPhotosAlbum:srcURL completionBlock:videoWriteCompletionBlock];
    }
}

enter image description here

something very strange is that worked perfect, until I turned uninstall and then install instagram. Do not know if this has something to do

Upvotes: 12

Views: 8061

Answers (8)

Jaydeep Patel
Jaydeep Patel

Reputation: 1739

Here is code for sharing video on instagram : May be you need to add condition for substringFromIndex but its working.

 - (void)ShareAssetURLvideoToInstagram:(NSURL*)assetsLibraryURL
        {
            NSMutableDictionary *queryStringDictionary = [[NSMutableDictionary alloc] init];

            NSString *strParamater = [assetsLibraryURL.absoluteString substringFromIndex:[assetsLibraryURL.absoluteString rangeOfString:@"?"].location+1];
            NSArray *urlComponents = [strParamater componentsSeparatedByString:@"&"];
            for (NSString *keyValuePair in urlComponents)
            {
                NSArray *pairComponents = [keyValuePair componentsSeparatedByString:@"="];
                NSString *key = [[pairComponents firstObject] stringByRemovingPercentEncoding];
                NSString *value = [[pairComponents lastObject] stringByRemovingPercentEncoding];

                [queryStringDictionary setObject:value forKey:key];
            }

            NSString *mediaId = [queryStringDictionary valueForKey:@"id"];

            if (mediaId.length > 0) {
                NSURL *instagramURL = [NSURL URLWithString:[NSString stringWithFormat:@"instagram://library?LocalIdentifier=%@",mediaId]];

                if ([[UIApplication sharedApplication] canOpenURL:instagramURL]) {
                    [[UIApplication sharedApplication] openURL:instagramURL];
                }
            }

        }

Upvotes: 0

jose920405
jose920405

Reputation: 8049

Resuming this task after a long time and considering the borisgolovnev's answer and ALAssetsLibrary is deprecated, the final solution is:

- (void)saveToCameraRollOpt2:(NSURL *)srcURL
{
    __block PHAssetChangeRequest *_mChangeRequest = nil;
    __block PHObjectPlaceholder *placeholder;

    [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{

        NSData *pngData = [NSData dataWithContentsOfURL:srcURL];
        UIImage *image = [UIImage imageWithData:pngData];

        _mChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];

        placeholder = _mChangeRequest.placeholderForCreatedAsset;

    } completionHandler:^(BOOL success, NSError *error) {

        if (success) {
            [self loadCameraRollAssetToInstagram:[placeholder localIdentifier]];
        }
        else {
            NSLog(@"write error : %@",error);
            [self showAlert:@"Error" msg:@"Error saving in camera roll" action:nil];
        }
    }];
}

- (void)loadCameraRollAssetToInstagram:(NSString *)localId
{
    NSURL *instagramURL = [NSURL URLWithString:[NSString stringWithFormat:@"instagram://library?LocalIdentifier=\%@", localId]];

    if ([[UIApplication sharedApplication] canOpenURL:instagramURL]) {
        [[UIApplication sharedApplication] openURL:instagramURL options:@{} completionHandler:nil];
    } else {
        [self showAlert:@"Error" msg:@"Instagram app is not installed" action:nil];
    }
}

- (NSString*)urlencodedString:(NSString *)message
{
    return [message stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]];
}

Don't forget

#import <Photos/Photos.h>

Add `NSPhotoLibraryUsageDescription` and `QueriesSchemes` inside .plist file

<key>NSPhotoLibraryUsageDescription</key>
<string>Need permission to access to manage your photos library</string>
<key>LSApplicationQueriesSchemes</key>
<array>
    <string>instagram</string>
</array>

Upvotes: 4

fatihyildizhan
fatihyildizhan

Reputation: 8832

swift 3 get the latest Identifier simple and fast

  var lastIdentifier = ""
  let fetchOptions = PHFetchOptions()
  fetchOptions.sortDescriptors = [NSSortDescriptor(key:"creationDate", ascending:false)]
  let fetchResult = PHAsset.fetchAssets(with: .video, options: fetchOptions)
  if let lastAsset: PHAsset = fetchResult.lastObject {
    lastIdentifier = lastAsset.localIdentifier
  }

Upvotes: 0

Sarp Solakoglu
Sarp Solakoglu

Reputation: 94

@borisgolovnev's solution actually works. You can get the localIdentifier of your last saved video using the code below. Passing it with instagram://library?LocalIdentifier=(localID) opens Instagram with your video selected.

let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key:"creationDate", ascending:false)]
let fetchResult = PHAsset.fetchAssetsWithMediaType(.Video, options: fetchOptions)
if let lastAsset = fetchResult.firstObject as? PHAsset {
    self.localIdentifier = lastAsset.localIdentifier
}

Upvotes: 1

borisgolovnev
borisgolovnev

Reputation: 1800

instagram://library?AssetPath=\(assetsLibraryUrl) stopped working a while ago. Instagram developers probably moved to Photos framework and no longer use the AssetsLibrary.

Having this assumption I tried several other parameter names and found that instagram://library?LocalIdentifier=\(localID) where localId is the localIdentifier of your PHAsset works for now.

This is still as undocumented as it was so it can break in any future version of the Instagram.

Upvotes: 40

Trung Duc Bui
Trung Duc Bui

Reputation: 11

Replace

- (NSString*)urlencodedString:(NSString *)message{
return [message stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]];
}

With

- (NSString*)urlencodedString:(NSString *)message{
return [message stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet alphanumericCharacterSet]];
}

This worked for me!

Upvotes: 0

Pratik Patel
Pratik Patel

Reputation: 1421

use this code

NSURL *instagramURL = [NSURL URLWithString:@"instagram://app"];
if ([[UIApplication sharedApplication] canOpenURL:instagramURL])
{
    NSURL *videoFilePath = [NSURL URLWithString:[NSString stringWithFormat:@"%@",[request downloadDestinationPath]]]; // Your local path to the video
    NSString *caption = @"Some Preloaded Caption";
    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
    [library writeVideoAtPathToSavedPhotosAlbum:videoFilePath completionBlock:^(NSURL *assetURL, NSError *error) {
        NSString *escapedString   = [self urlencodedString:videoFilePath.absoluteString];
        NSString *escapedCaption  = [self urlencodedString:caption];
        NSURL *instagramURL = [NSURL URLWithString:[NSString stringWithFormat:@"instagram://library?AssetPath=%@&InstagramCaption=%@",escapedString,escapedCaption]];
        if ([[UIApplication sharedApplication] canOpenURL:instagramURL]) {
            [[UIApplication sharedApplication] openURL:instagramURL];
        }
    }];
}

Instagram will only shows those iamges/videos which are saved at path which you set in instagramURL. That path should be absolute.

If it still not shows then add LSApplicationQueriesSchemes in info.plist file of array, add its item0 as instagram.

Upvotes: 0

tk.duy
tk.duy

Reputation: 1

if ([[UIApplication sharedApplication] canOpenURL:instagramURL]) {
NSLog(@"Open Instagram!!"); //enter code here
[[UIApplication sharedApplication/*<enter your code here>*/] openURL:instagramURL];

Upvotes: -4

Related Questions