How to upload a file using Reskit in iOS - objective-c

How would I go about uploading an audio file using Restkit? I've looked around the documentation and can't seem to find anything about uploading files. Thanks for your help.

This article explains how: http://mobile.tutsplus.com/tutorials/iphone/advanced-restkit-development_iphone-sdk/
Excerpt:
NSString* myFilePath = #"/some/path/to/picture.gif";
RKParams* params = [RKParams params];
// Set some simple values -- just like we would with NSDictionary
[params setValue:#"Blake" forParam:#"name"];
[params setValue:#"blake#restkit.org" forParam:#"email"];
// Create an Attachment
RKParamsAttachment* attachment = [params setFile:myFilePath forParam:#"image1"];
attachment.MIMEType = #"image/gif";
attachment.fileName = #"picture.gif";
// Attach an Image from the App Bundle
UIImage* image = [UIImage imageNamed:#"another_image.png"];
NSData* imageData = UIImagePNGRepresentation(image);
[params setData:imageData MIMEType:#"image/png" forParam:#"image2"];
// Let's examine the RKRequestSerializable info...
NSLog(#"RKParams HTTPHeaderValueForContentType = %#", [params HTTPHeaderValueForContentType]);
NSLog(#"RKParams HTTPHeaderValueForContentLength = %d", [params HTTPHeaderValueForContentLength]);
// Send a Request!
[[RKClient sharedClient] post:#"/uploadImages" params:params delegate:self];
Enjoy!

For Restkit 0.20, the MIME types are automatically detected when creating the attachement. So you do not need to call
attachment.MIMEType
And when building the params:
[params setData:imageData MIMEType:attachment.MIMEType forParam:#"image2"];
see this link

Related

Everytime same video gets uploaded + Assets Library

ImgVidData =[[NSData alloc]init];
ALAssetRepresentation *representation = alAsset.defaultRepresentation;
NSURL *movieURL = representation.url;
NSURL *uploadURL = [NSURL fileURLWithPath:[[NSTemporaryDirectory() stringByAppendingPathComponent:#"test"] stringByAppendingString:#".mov"]];
// ImgVidData = [NSData dataWithContentsOfFile: [[NSTemporaryDirectory() stringByAppendingPathComponent:#"test"] stringByAppendingString:#".mp4"]];
AVAsset *asset = [AVURLAsset URLAssetWithURL:movieURL options:nil];
AVAssetExportSession *session =
[AVAssetExportSession exportSessionWithAsset:asset presetName:AVAssetExportPresetMediumQuality];
session.outputFileType = AVFileTypeQuickTimeMovie;
session.outputURL = uploadURL;
videoURL=uploadURL;
[session exportAsynchronouslyWithCompletionHandler:^{
if (session.status == AVAssetExportSessionStatusCompleted)
{
NSLog(#"output Video URL %#",uploadURL);
}
}];
ImgVidData = [NSData dataWithContentsOfURL:session.outputURL];
Above is the code , i have implemented inside didFinishPickingAssets:(NSArray *)assets
I'm picking up the video and uploading the video to server. I'm fetching uploaded video URL and converting it into NSdata and uploading it to server.
STRANGE : everytime I'm getting same video uploaded to server which i choose first time. i choose different video everytime but same videos get uplaoded.
Any help !!

Cocoa: AVAsset loaded from file has 0 tracks

I'm attempting to concatenate some audio files using the technique shown here. My audio files are .m4a and I can verify that they play fine in Quicktime. Here's the code I'm trying to use to concatenate them:
[currFile.audioContent writeToFile:tempOldFilePath atomically:NO];
AVURLAsset *oldAudioAsset = [AVURLAsset URLAssetWithURL:[NSURL URLWithString:tempOldFilePath] options:nil];
AVURLAsset *newAudioAsset = [AVURLAsset URLAssetWithURL:[NSURL URLWithString:tempInputFilePath] options:nil];
NSLog(#"oldAsset num tracks = %lu",(unsigned long)oldAudioAsset.tracks.count);
NSLog(#"newAsset num tracks = %lu",(unsigned long)newAudioAsset.tracks.count);
AVAssetTrack *oldTrack = [[oldAudioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
AVAssetTrack *newTrack = [[newAudioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
AVMutableComposition *mutableComposition = [AVMutableComposition composition];
AVMutableCompositionTrack *compTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
NSError *error=nil;
[compTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, oldTrack.timeRange.duration) ofTrack:oldTrack atTime:kCMTimeZero error:&error];
if (error) {
NSLog(#"%#",error.localizedDescription);
error=nil;
}
[compTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, newTrack.timeRange.duration) ofTrack:newTrack
atTime:oldTrack.timeRange.duration error:&error];
if (error) {
NSLog(#"%#",error.localizedDescription);
error=nil;
}
exporter = [[AVAssetExportSession alloc] initWithAsset:mutableComposition presetName:AVAssetExportPresetAppleM4A];
exporter.outputURL = [NSURL URLWithString:tempCompFilePath];
exporter.outputFileType = AVFileTypeAppleM4A;
[exporter exportAsynchronouslyWithCompletionHandler:^{
NSLog(#"handller");
NSError *error=nil;
NSData *newData = [NSData dataWithContentsOfFile:tempCompFilePath options:0 error:&error];
NSLog(#"%lu",(unsigned long)newData.length);
if (error) {
NSLog(#"%#",error.localizedDescription);
}
currFile.audioContent = newData;
[[AppDelegate sharedDelegate] saveAction:nil];
}];
The first problem I noticed is that the exporter's handler method is never called. I'm guessing the reason for this is the other problem I noticed: After created my AVAssets from URL, log statements show that they contain 0 tracks. Apple's example doesn't exactly show how the AVAssets are loaded.
Any advice on how to get this working?
As you've already found, you need to use fileURLWithPath:, not URLWithString:, to create your URLs.
URLWithString: expects a string that describes a URL, such as #"file:///path/to/file" or #"http://example.com/". When your string describes a path alone, such as #"/path/to/file", you must use fileURLWithPath:, which will fill in the missing pieces correctly.
More technically, URLWithString: will interpret a path as simply a URL with only a path but no particular scheme, which you could go on to use relative to a base URL in any file-oriented scheme, such as HTTP (GET /path/to/file). fileURLWithPath: will interpret a path as a local file path, and return a file: URL accordingly.
I found the reason why this error was occurred and eventually solve it.
Originally I had set the source file path as ".mp4".
But the type of recorded video file was MOV so I changed as ".mov".
NSString *source_file_path = #"temp_video.mov"
instead of
NSString *source_file_path = #"temp_video.mp4"
The problem was fixed and it is working well now.
Hope to be helpful for all.
Apparently I was using the wrong NSURL method. I changed it to this:
AVURLAsset *oldAudioAsset = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:tempOldFilePath] options:nil];
Now my AVAssets each have 1 track in them. If anyone can provide a good explanation as to why this is necessary, I will accept that answer.

SoundCloud API iOS, no sharing - only listening

I got a website where I make playlists with SoundCloud. Now I want to make an app for iPhone so the users can listen to the songs there as well.
http://developers.soundcloud.com/docs/api/ios-quickstart
In the example in the link the users have to sign in to listen and share, but I want my users only to listen. Is there a way around so they don't have to sign in?
Create a page that outputs the playlist in JSON, then in xcode create a class that downloads the JSON for the track dictionaries and play the downloaded content using AVPlayer (or AVQueuePlayer if you're playing the whole list).
Here's some abstract code:
playlistDownloader.m
- (void)downloadPlaylist{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_sync(concurrentQueue, ^{
NSURL *url = [NSURL URLWithString:#"http://www.yourwebsite.com/playlist.json?id=1"];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *error;
id trackData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
if (!error) {
tempTrackArray = trackData;
} else {
NSLog(#"Playlist wasn't able to download");
}
});
}
tempTrackArray would be a property declared in the class.
Then in your player, you'd do something like this:
audioPlayer.m
- (void)instanciateAudioPlayer
{
NSDictionary *trackDictionary = [playListDownloader.tempTrackArray objectAtIndex:0];
NSString *urlString = [trackDictionary objectForKey:#"stream_url"];
AVAsset *asset = [AVAsset assetWithURL:streamURL];
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:asset];
[avPlayer initWithPlayerItem:playerItem];
}
This is some really rough code but its the general gist of what you're trying to do. Should get you going in the right direction.
Trying the soundcloud quickstart I realised that your stream url needs to begin with https rather than http. Also you need to add your client id from your sound cloud app to the stream url:
NSDictionary *trackDictionary = [playListDownloader.tempTrackArray objectAtIndex:0];
NSString *streamURL = [trackDictionary objectForKey:#"stream_url"];
streamURL = [streamURL stringByReplacingOccurrencesOfString:#"http" withString:#"https"];
NSString *urlString = [NSString stringWithFormat:#"%#?client_id=%#", streamURL, #"a8e117d3fa2121067e0b29105b0543ef"];
From there you just setup the AVPlayer:
self._avPlayer = [AVPlayer playerWithURL:[NSURL URLWithString:urlString]];
[self setupLayer:clayer];
[self._avPlayer play];
Everything should work fine. Hope it helps

Facebook graph API : audio share

Can I share audio using facebook graphic API
Can I directly upload audio on facebook server like video?
Can I share audio link on facebook and it will show embedded player on facebook?
I have tried this solution ios Facebook Graph API - post Audio file , but it doesn't work as expected
What I tried is to share audio link http://bit.ly/Ok4ZX6 but show it on facebook like a normal link not with embedded player http://i.stack.imgur.com/Ld67c.png
Edit
Code I have use :
NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:4];
[params setObject:text forKey:#"message"];
[params setObject:title forKey:#"name"];
[params setObject:fileUrl forKey:#"source"];
[facebook requestWithGraphPath:#"me/feed" andParams:params andHttpMethod:#"POST" andDelegate:self];
Also used this code too :
NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:4];
NSString *attachment = [NSString stringWithFormat:#"{'media': [{'type': 'mp3', 'src': '%#', 'title': '%#'}], 'messgae': 'Messgae Messgae Messgae', 'name': 'Name Name Name', 'href': '%#'}",amazon_link, title, link];
[params setObject:attachment forKey:#"attachment"];
[params setObject:text forKey:#"message"];
[params setObject:#"stream.publish" forKey:#"method"];
[facebook requestWithParams:params andDelegate:self];
What solution from that link did you try? Post your own code. I also noticed that your audio link doesn't work, atleast not for me.
I think the correct way is to use the "source" field in the graph api, not "link".
This is a good page on the developer reference:
http://developers.facebook.com/docs/reference/api/post/
To upload a video using the graph API you can do this. You also need to be authorized to the publish_stream permission.
NSString * file = [[NSBundle mainBundle] pathForResource:#"video" ofType:#"mov"];
NSData * video = [NSData dataWithContentsOfFile:file];
NSMutableDictionary * dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
#"title", #"title",
#"description", #"description",
video, #"video.mov",
#"video/quicktime", #"contentType",
nil];
[facebook requestWithGraphPath:#"me/videos"
andParams:dict
andHttpMethod:#"POST"
andDelegate:self];
Soundcloud use og:video tags to show the embedded player. The video tags accept SWF files, so it's possible to load up an interactive audio player widget. Try using the OG Debugger to see the tags.
Currently, this seems like the only strategy to show a player when content is shared.
Try like this.. Its working for me..
NSMutableDictionary *variables=[[NSMutableDictionary alloc]init];
//Posting audio file
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"Dookudu" ofType:#"mp3"];
FbGraphFile *file=[[FbGraphFile alloc]initWithData:[NSData dataWithContentsOfFile:filePath]];
[variables setObject:file forKey:#"file"];
FbGraphResponse *response=[fbgraph doGraphPost:#"me/videos" withPostVars:variables];
NSLog(#"response %#",response.htmlResponse);

Multithreading to download data from a website

I'm doing an app which downloads info via a request to a website, giving me back and HTML and parsing this data I obtain my app info. For downloading this data I'm using, using a url with all the parameters the request needs at the end.
NSData *data = [NSData dataWithContentsOfURL:url];
NSString* htmlString;
htmlString = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
[self parserHTML:htmlString]; // here I fill a NSArray with the info parsed
[self searchSomething:htmlString]; // continue filling the NSArray
...
The task for download the data and parser the HTML takes long time.
What can I do to make this faster? Grand Central Dispatch? If so, how can I use it, because I'm using this and it doesn't works, because the NSSArray is empty:
dispatch_queue_t downloadQueue = dispatch_queue_create("pharmacy downloader", NULL);
dispatch_async(downloadQueue, ^{
NSData *data = [NSData dataWithContentsOfURL:urlReal];
NSString* htmlString;
htmlString = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
[self parserHTML:htmlString]; // here I fill a NSArray with the info parsed
[self searchSomething:htmlString]; // continue filling the NSArray
});
dispatch_release(downloadQueue);
If I don't use GCD it works. What can be the problem??
Thanks for your help. I'm totally lost!!! :S
Use NSURLDownload or NSURLConnection instead.
For some sample code you may take a look at QuickLookDownloader