I am trying to export a photo from my application to Instagram, using this code:
// Capture Screenshot
UIGraphicsBeginImageContextWithOptions(self.view.frame.size,self.view.opaque,0.0);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData *imageData = UIImageJPEGRepresentation(image, 1.0);
NSString *jpgPath = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents/test.igo"];
NSURL *igImageHookFile = [[NSURL alloc] initWithString:[[NSString alloc] initWithFormat:#"file://%#", jpgPath]];
dic = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:igImageHookFile]];
dic.UTI = #"com.instagram.photo";
dic.annotation = [NSDictionary dictionaryWithObject:#"my caption" forKey:#"InstagramCaption"];
NSURL *instagramURL = [NSURL URLWithString:#"instagram://app"];
if ([[UIApplication sharedApplication] canOpenURL:instagramURL]) {
[[UIApplication sharedApplication] openURL:instagramURL];
} else {
NSLog(#"No Instagram Found");
}
But it is not working. It crashes with the following error:
2013-01-19 20:40:41.948 Ayat[12648:c07] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[NSURL initFileURLWithPath:]: nil string parameter'
I am not sure I'm properly:
1- Saving jpgpath as the screenshot I took .
2- Passing the "dic" document to Instagram.
In my app, I have also export photo to Instagram. (Image must be larger than 612x612 size)
Try this code:
-(void)shareImageOnInstagram:(UIImage*)shareImage
{
//Remember Image must be larger than 612x612 size if not resize it.
NSURL *instagramURL = [NSURL URLWithString:#"instagram://app"];
if([[UIApplication sharedApplication] canOpenURL:instagramURL])
{
NSString *documentDirectory=[NSHomeDirectory() stringByAppendingPathComponent:#"Documents"];
NSString *saveImagePath=[documentDirectory stringByAppendingPathComponent:#"Image.ig"];
NSData *imageData=UIImagePNGRepresentation(shareImage);
[imageData writeToFile:saveImagePath atomically:YES];
NSURL *imageURL=[NSURL fileURLWithPath:saveImagePath];
UIDocumentInteractionController *docController=[[UIDocumentInteractionController alloc]init];
docController.delegate=self;
[docController retain];
docController.UTI=#"com.instagram.photo";
docController.annotation=[NSDictionary dictionaryWithObjectsAndKeys:#"Image Taken via #App",#"InstagramCaption", nil];
[docController setURL:imageURL];
[docController presentOpenInMenuFromBarButtonItem:self.navigationItem.rightBarButtonItem animated:YES]; //Here try which one is suitable for u to present the doc Controller. if crash occurs
}
else
{
NSLog (#"Instagram not found");
}
}
I hope this will helps you.
On this line
dic = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:igImageHookFile]];
you are calling fileURLWithPath:. For a start this expects an NSString, not an NSURL, but from your error message it looks like igImageHookFile is nil.
It took a bunch of research but I finally found this at this site that helped. I just trimmed it up a bit to not include the caption as that was his original problem... but if you're only putting in the picture, here it is:
-(void)shareImageOnInstagram
{
//Remember Image must be larger than 612x612 size if not resize it.
NSURL *instagramURL = [NSURL URLWithString:#"instagram://app"];
if ([[UIApplication sharedApplication] canOpenURL:instagramURL]){
NSString *urlString = [[NSString alloc] initWithFormat:#"file://%#", blendedImageURL];
NSURL *imageUrl = [[NSURL alloc] initWithString: urlString];
self.docController = [self setupControllerWithURL:imageUrl usingDelegate:self];
self.docController.UTI = #"com.instagram.exclusivegram";
// self.docController.annotation = [NSDictionary dictionaryWithObject:#"I want to share this text" forKey:#"InstagramCaption"];
[self.docController presentOpenInMenuFromRect: self.view.frame inView: self.view animated: YES ];}
}
I tried the following code and it worked:
- (void) shareImageWithInstagram
{
NSURL *instagramURL = [NSURL URLWithString:#"instagram://"];
if ([[UIApplication sharedApplication] canOpenURL:instagramURL])
{
UICachedFileMgr* mgr = _gCachedManger;
UIImage* photoImage = [mgr imageWithUrl:_imageView.image];
NSData* imageData = UIImagePNGRepresentation(photoImage);
NSString* captionString = [NSString stringWithFormat:#"%#%#",self.approvedData.approvedCaption,self.approvedData.tag];
NSString* imagePath = [UIUtils documentDirectoryWithSubpath:#"image.igo"];
[imageData writeToFile:imagePath atomically:NO];
NSURL* fileURL = [NSURL fileURLWithPath:[NSString stringWithFormat:#"file://%#",imagePath]];
self.docFile = [[self setupControllerWithURL:fileURL usingDelegate:self]retain];
self.docFile.annotation = [NSDictionary dictionaryWithObject: captionString
forKey:#"InstagramCaption"];
self.docFile.UTI = #"com.instagram.photo";
// OPEN THE HOOK
[self.docFile presentOpenInMenuFromRect:self.view.frame inView:self.view animated:YES];
}
else
{
[UIUtils messageAlert:#"Instagram not installed in this device!\nTo share image please install instagram." title:nil delegate:nil];
}
}
Related
I am currently trying to make an app stream raw data from mic over mulipeer connectivity.
I have been using this tutorial as a base https://robots.thoughtbot.com/streaming-audio-to-multiple-listeners-via-ios-multipeer-connectivity
Now however I am struggling with changing the URL from itunes library to my local file.
I am no advanced programmer and this is some kind of summer project.
When the program is getting music from itunes library it uses this code:
- (void)mediaPicker:(MPMediaPickerController *)mediaPicker didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection
{
[self dismissViewControllerAnimated:YES completion:nil];
if (self.outputStreamer) return;
self.song = mediaItemCollection.items[0];
NSMutableDictionary *info = [NSMutableDictionary dictionary];
info[#"title"] = [self.song valueForProperty:MPMediaItemPropertyTitle] ? [self.song valueForProperty:MPMediaItemPropertyTitle] : #"";
info[#"artist"] = [self.song valueForProperty:MPMediaItemPropertyArtist] ? [self.song valueForProperty:MPMediaItemPropertyArtist] : #"";
MPMediaItemArtwork *artwork = [self.song valueForProperty:MPMediaItemPropertyArtwork];
UIImage *image = [artwork imageWithSize:self.albumImage.frame.size];
if (image)
info[#"artwork"] = image;
if (info[#"artwork"])
self.albumImage.image = info[#"artwork"];
else
self.albumImage.image = nil;
self.songTitle.text = info[#"title"];
self.songArtist.text = info[#"artist"];
[self.session sendData:[NSKeyedArchiver archivedDataWithRootObject:[info copy]]];
NSArray *peers = [self.session connectedPeers];
if (peers.count) {
self.outputStreamer = [[TDAudioOutputStreamer alloc] initWithOutputStream:[self.session outputStreamForPeer:peers[0]]];
[self.outputStreamer streamAudioFromURL:[self.song valueForProperty:MPMediaItemPropertyAssetURL]];
[self.outputStreamer start];
But I want it to get music from the recorder:
NSArray *pathComponents = [NSArray arrayWithObjects:
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject],
#"MyAudioMemo.m4a",
nil];
NSURL *outputFileURL = [NSURL fileURLWithPathComponents:pathComponents];
recorder = [[AVAudioRecorder alloc] initWithURL:outputFileURL settings:recordSetting error:nil];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:recorder.url error:nil];
I have been struggling with this for a while now and would appreciate any kind of help!
On my xib I have a UITextField and UIImageView and a button,
what actually I want is when user can enter image name e.g. Default.png OR a full web URL of image and when press that button should check
if text is simple e.g. Default.png then use the local image and
if text is web URL with image then load data from image URL and create a image and then put on UIImageView.
I have checked many question here but did not get exact solution for what I want to achieve.
What I have done: (Which is not working)
// imageViewViewController.h
#import <UIKit/UIKit.h>
#interface imageViewViewController : UIViewController<UITextFieldDelegate>
{
IBOutlet UITextField * urlInput;
IBOutlet UIImageView * myImgView;
}
- (IBAction)submit:(id)sender;
#end
Code from .m file
- (IBAction)submit:(id)sender
{
NSString *url = urlInput.text;
UIImage *tempImg;
if([self validateUrl:url]) {
NSURL *imageurl = [NSURL URLWithString:url];
NSData *imagedata = [[NSData alloc]initWithContentsOfURL:imageurl];
tempImg = [UIImage imageWithData: imagedata];
} else {
tempImg = [UIImage imageNamed:url];
}
if(tempImg == nil){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Image not present!!!" message:#"Image not present!!!" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
} else {
myImgView.image = tempImg;
}
}
- (BOOL) validateUrl: (NSString *) candidate {
NSString *urlRegEx =
#"(http|https)://((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+";
NSPredicate *urlTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", urlRegEx];
return [urlTest evaluateWithObject:candidate];
}
Even after entering correct image URL it is showing me alert "Image not present!!!"
I think there is problem with my URL validation function.
You could use the
+(id)URLWithString:(NSString *)URLString
method of NSURL, which returns nil if the string is not URL
"The string with which to initialize the NSURL object. Must be a URL that conforms to RFC 2396. This method parses URLString according to RFCs 1738 and 1808." (c)
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSURL_Class/Reference/Reference.html
The code support the string is URL or Not,
NSString *incoming_string=#"http://www.gmail.com";
NSString *substring=#"http";
NSRange textRange = [incoming_string rangeOfString:substring];
if(textRange.location != NSNotFound){
NSLog(#"This is url image");
}else{
NSLog(#"This is SYSTEM Image");
}
UIImage *img = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:txtField.text]]];
if(img)
{
// Do something
}
Try this.
Use this method to check for a valid url
- (BOOL)isValidUrl:(NSString *)urlString{
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
return [NSURLConnection canHandleRequest:request];
}
There are two alternative to check valid URL :
Method 1:
- (BOOL)CheckUrl:(NSString *)urlString {
NSURLRequest *req = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
return [NSURLConnection canHandleRequest:request];
}
Method 2 :
NSString *urlRegEx = #"http(s)?://([\\w-]+\\.)+[\\w-]+(/[\\w- ./?%&=]*)?";
Hope this might solve the problem
Use this code for check that its valid URL or not...
NSURLRequest *req = [NSURLRequest requestWithURL:[NSURL URLWithString: url]];
bool valid = [NSURLConnection canHandleRequest:req];
I use the following code to get an image from a video at given path.
- (UIImage*) thumbnailImageForVideo:(NSURL *)videoURL atTime:(NSTimeInterval)time {
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoURL options:nil];
NSParameterAssert(asset);
AVAssetImageGenerator *assetImageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
assetImageGenerator.appliesPreferredTrackTransform = YES;
assetImageGenerator.apertureMode = AVAssetImageGeneratorApertureModeEncodedPixels;
CGImageRef thumbnailImageRef = NULL;
CFTimeInterval thumbnailImageTime = time;
NSError *thumbnailImageGenerationError = nil;
thumbnailImageRef = [assetImageGenerator copyCGImageAtTime:CMTimeMake(thumbnailImageTime, 60) actualTime:NULL error:&thumbnailImageGenerationError];
if (!thumbnailImageRef)
NSLog(#"thumbnailImageGenerationError %#", thumbnailImageGenerationError);
UIImage *thumbnailImage = thumbnailImageRef ? [[UIImage alloc] initWithCGImage:thumbnailImageRef] : nil;
previewImage = thumbnailImage;
return thumbnailImage;
}
However this is not working for a video saved in a NSDocumentDirectory. Cant we access the NSDocumentDIrectory using NSURL? If not any alternative. The main idea is to show the thumbnail of an image saved in document directory and later allow it to upload to sever. This can be a temp directory as well.
Worked when you use NSURL *outputURL = [[NSURL alloc] initFileURLWithPath: path];
Can the Above be Done using only AVFoundation.framework?
i Tried doing a few experiment but i can't really get it to work
(sorry newbie here please do tell me where to put the codes at Example: ViewController or the MainView)
These are my code,(UI Components are inside as i'm do not want use interface builder)
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
NSError *error;
buttonPlay = [[UILabel alloc] initWithFrame:CGRectMake(0, 350, 100, 50)];
buttonPlay.text = #"Play";
// Get the file path to the song to play.
NSString* path;
NSURL* url;
path = [[NSBundle mainBundle] pathForResource:#"Bring_Me_To_Life.mp3" ofType:nil];
url = [NSURL fileURLWithPath:path];
NSData *_objectData = [NSData dataWithContentsOfURL:url];
//Initialize the AVAudioPlayer.
audioPlayer = [[AVAudioPlayer alloc] initWithData:_objectData error:&error];
// Preloads the buffer and prepares the audio for playing.
audioPlayer.numberOfLoops = 0;
audioPlayer.volume = 1.0f;
[audioPlayer prepareToPlay];
if (audioPlayer == nil)
NSLog(#"%#", [error description]);
else
[audioPlayer play];
[self addSubview:buttonPlay];
}
return self;
}
-(void)touchesBegan:(CGPoint)location{
if(CGRectContainsPoint(buttonPlay.frame, location)){
NSLog(#"Dec from Chl %f",[audioPlayer peakPowerForChannel:0]);
NSLog(#"Length of Clip %f",[audioPlayer duration]);
}
}
try this
audioPlayer=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:nil];
I have problem with MPMoviePlayerController (self.mp). When I want to access duration property, I get 0, when I want to access thumbnail…, I get nil. On iOS 4 it is OK, iOS 5 it is not.
After all app says to me: The Operation Could Not Be Completed.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
if([[info objectForKey:UIImagePickerControllerMediaType] isEqualToString:(NSString *)kUTTypeMovie]){
NSString *tempFilePath = [[info objectForKey:UIImagePickerControllerMediaURL] path];
NSString *rootPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
double hashToNameOfFile = [NSDate timeIntervalSinceReferenceDate] * 1000.0;
NSString *finalPath = [rootPath stringByAppendingPathComponent:[NSString stringWithFormat: #"%.0f.%#", hashToNameOfFile, #"MOV"]];
NSString *finalPathToThumbRetina = [rootPath stringByAppendingPathComponent:[NSString stringWithFormat: #"thumb_%.0f#2x.%#", hashToNameOfFile, #"jpg"]];
NSString *finalPathToThumb = [rootPath stringByAppendingPathComponent:[NSString stringWithFormat: #"thumb_%.0f.%#", hashToNameOfFile, #"jpg"]];
// we do need retina now, we use real name for CoreData
NSString *finalImage = [finalPath lastPathComponent];
NSString *finalImageThumb = [finalPathToThumb lastPathComponent];
if ( UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(tempFilePath)){
// Copy it to the camera roll.
UISaveVideoAtPathToSavedPhotosAlbum(tempFilePath, self, #selector(video:didFinishSavingWithError:contextInfo:), tempFilePath);
}
// save video to application directory
NSData *videoData = [NSData dataWithContentsOfFile:tempFilePath];
if ( [videoData writeToFile:finalPath atomically:YES] ) {
NSLog(#"SAVED");
}
else{
NSLog(#"NOT SAVED");
}
// create thumbnail of video
MPMoviePlayerController *moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:finalPath]];
self.mp = moviePlayer;
[moviePlayer release];
NSData *videoData2 = [NSData dataWithContentsOfFile:finalPath];
NSLog(#"LENGTH %i", [videoData2 length]);
NSLog(#"FINAL PATH %#", finalPath);
UIImage *image = [[[UIImage alloc] init] autorelease];
image = [self.mp thumbnailImageAtTime:(NSTimeInterval)1.0 timeOption:MPMovieTimeOptionNearestKeyFrame];
NSLog(#"%#", [image size]);
UIImage *thumbImageRetina = [image thumbnailImage:400 transparentBorder:0 cornerRadius:0 interpolationQuality:kCGInterpolationDefault];
UIImage *thumbImage = [image thumbnailImage:200 transparentBorder:0 cornerRadius:0 interpolationQuality:kCGInterpolationDefault];
NSData *thumbImageRetinaData = [NSData dataWithData:UIImageJPEGRepresentation(thumbImageRetina, 1.0)];
NSData *thumbImageData = [NSData dataWithData:UIImageJPEGRepresentation(thumbImage, 1.0)];
if ( [thumbImageRetinaData writeToFile:finalPathToThumbRetina atomically:YES] ) {
NSLog(#"RETINA THUMB SAVED");
}
else{
NSLog(#"RETINA THUMB NOT SAVED");
}
if ( [thumbImageData writeToFile:finalPathToThumb atomically:YES] ) {
NSLog(#"THUMB SAVED");
}
else{
NSLog(#"THUMB NOT SAVED");
}
// duration of video
double dur = [self.mp duration];
NSLog(#"DUR %f", dur);
TaleRecords *newTaleRecord = (TaleRecords *)[NSEntityDescription insertNewObjectForEntityForName:#"TaleRecords" inManagedObjectContext:_context];
newTaleRecord.content = finalImage;
newTaleRecord.date = [NSDate date];
NSDecimalNumber *latNum = [[NSDecimalNumber alloc] initWithDouble:[self.latitude doubleValue]];
NSDecimalNumber *longNum = [[NSDecimalNumber alloc] initWithDouble:[self.longitude doubleValue]];
newTaleRecord.latitude = latNum; // vertical
newTaleRecord.longitude = longNum; // horizontal
[latNum release];
[longNum release];
newTaleRecord.contentType = [[NSString alloc] initWithFormat:#"cTypeVideo"];
newTaleRecord.thumb = finalImageThumb;
newTaleRecord.duration = [NSNumber numberWithDouble:dur];
newTaleRecord.tale = tales;
tales.record = [newTaleRecord tale].record;
NSError *error = nil;
if (![_context save:&error]) {
/*
Replace this implementation with code to handle the error appropriately.
abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
*/
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
}
[CLController.locationManager stopUpdatingLocation];
[self dismissModalViewControllerAnimated:YES];
}
More simple example
I am doing this:
// save video to application directory
NSData *videoData = [NSData dataWithContentsOfFile:tempFilePath];
if ( [videoData writeToFile:finalPath atomically:YES] ) {
NSLog(#"SAVED");
}
else{
NSLog(#"NOT SAVED");
}
At tempFilePath is real video content and I write it to finalPath. After that I create MPMoviePlayerController instance:
MPMoviePlayerController *moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:finalPath]];
self.mp = moviePlayer;
[moviePlayer release];
But self.mp give me no content. When I want to do [self.mp duration], it returns zero/nil. Path to resource works, but it seems no content is there.
Thank you for your help.
I figured out my problem.
It is like iOS5 is not comfortable with:
NSString *tempFilePath = [[info objectForKey:UIImagePickerControllerMediaURL] path];
so instead, if you just use
NSURL *someUrl =[info objectForKey:UIImagePickerControllerMediaURL] ;
and then initial mpmovieplayercontroller with this url, it works fine for me,
which is exactly the opposite of iOS4.
here is my code:
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
mediaURL = [info objectForKey:UIImagePickerControllerMediaURL];
NSLog(#"%#",mediaURL);
if (!mymoviePlayer) {
mymoviePlayer=[[MPMoviePlayerController alloc]initWithContentURL:mediaURL];
[mymoviePlayer setControlStyle:MPMovieControlStyleNone];
[mymoviePlayer.view setFrame: videoView.bounds];
[videoView addSubview:mymoviePlayer.view];
}
else
{
[mymoviePlayer setContentURL:mediaURL];
[mymoviePlayer stop];
[mymoviePlayer setInitialPlaybackTime:-1];
}
[self dismissModalViewControllerAnimated:YES];
}