AVAssetReader/Writer only working on certain devices? - objective-c

I was using this tutorial to get a song from the music library to my specified directory. It works fine for me, but other people are reporting that the song never gets there. At first I thought there were device limitations, but it seems like people with the same device as me are having the problem. It is sort of annoying because I can't recreate their problem.
Here is my code:
{
NSURL *assetURL = [song valueForProperty:MPMediaItemPropertyAssetURL];
AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:assetURL options:nil];
NSError *assetError = nil;
AVAssetReader *assetReader = [[AVAssetReader assetReaderWithAsset:songAsset
error:&assetError]
retain];
if (assetError) {
NSLog (#"error: %#", assetError);
return;
}
AVAssetReaderOutput *assetReaderOutput = [[AVAssetReaderAudioMixOutput
assetReaderAudioMixOutputWithAudioTracks:songAsset.tracks
audioSettings: nil]
retain];
if (! [assetReader canAddOutput: assetReaderOutput]) {
NSLog (#"can't add reader output... die!");
return;
}
[assetReader addOutput: assetReaderOutput];
NSString *exportPath = #"Library/PreferenceBundles/MyAlarmSettings.bundle/export.m4a";
if ([[NSFileManager defaultManager] fileExistsAtPath:exportPath]) {
[[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil];
}
NSURL *exportURL = [NSURL fileURLWithPath:exportPath];
AVAssetWriter *assetWriter = [[AVAssetWriter assetWriterWithURL:exportURL
fileType:AVFileTypeAppleM4A
error:&assetError]
retain];
if (assetError) {
NSLog (#"error: %#", assetError);
return;
}
AudioChannelLayout channelLayout;
memset(&channelLayout, 0, sizeof(AudioChannelLayout));
channelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
NSDictionary *outputSettings = [NSDictionary dictionaryWithObjectsAndKeys:
[ NSNumber numberWithInt: kAudioFormatMPEG4AAC], AVFormatIDKey,
[ NSNumber numberWithInt: 2 ], AVNumberOfChannelsKey,
[ NSNumber numberWithFloat: 44100.0 ], AVSampleRateKey,
[ NSData dataWithBytes:&channelLayout length: sizeof( AudioChannelLayout ) ], AVChannelLayoutKey,
[ NSNumber numberWithInt: 320000 ], AVEncoderBitRateKey,
nil];
AVAssetWriterInput *assetWriterInput = [[AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio
outputSettings:outputSettings]
retain];
if ([assetWriter canAddInput:assetWriterInput]) {
[assetWriter addInput:assetWriterInput];
} else {
NSLog (#"can't add asset writer input... die!");
return;
}
assetWriterInput.expectsMediaDataInRealTime = NO;
[assetWriter startWriting];
[assetReader startReading];
AVAssetTrack *soundTrack = [songAsset.tracks objectAtIndex:0];
CMTime startTime = CMTimeMake (0, soundTrack.naturalTimeScale);
[assetWriter startSessionAtSourceTime: startTime];
__block UInt64 convertedByteCount = 0;
dispatch_queue_t mediaInputQueue = dispatch_queue_create("mediaInputQueue", NULL);
[assetWriterInput requestMediaDataWhenReadyOnQueue:mediaInputQueue
usingBlock: ^
{
// NSLog (#"top of block");
while (assetWriterInput.readyForMoreMediaData) {
CMSampleBufferRef nextBuffer = [assetReaderOutput copyNextSampleBuffer];
if (nextBuffer) {
// append buffer
[assetWriterInput appendSampleBuffer: nextBuffer];
// NSLog (#"appended a buffer (%d bytes)",
// CMSampleBufferGetTotalSampleSize (nextBuffer));
convertedByteCount += CMSampleBufferGetTotalSampleSize (nextBuffer);
// oops, no
// sizeLabel.text = [NSString stringWithFormat: #"%ld bytes converted", convertedByteCount];
NSNumber *convertedByteCountNumber = [NSNumber numberWithLong:convertedByteCount];
[self performSelectorOnMainThread:#selector(updateSizeLabel:)
withObject:convertedByteCountNumber
waitUntilDone:NO];
} else {
// done!
NSString *songtitle = [[NSString alloc]initWithFormat:#"Alarm sound set to '%#' \n \n Press OK to respring. ",[song valueForProperty:MPMediaItemPropertyTitle]];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Done!" message:songtitle delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
[assetWriterInput markAsFinished];
[assetWriter finishWriting];
[assetReader cancelReading];
NSDictionary *outputFileAttributes = [[NSFileManager defaultManager]
attributesOfItemAtPath:exportPath
error:nil];
NSLog (#"done. file size is %llu",
[outputFileAttributes fileSize]);
NSNumber *doneFileSize = [NSNumber numberWithLong:[outputFileAttributes fileSize]];
[self performSelectorOnMainThread:#selector(updateCompletedSizeLabel:)
withObject:doneFileSize
waitUntilDone:NO];
// release a lot of stuff
[assetReader release];
[assetReaderOutput release];
[assetWriter release];
[assetWriterInput release];
[exportPath release];
break;
}
}
}];
NSLog (#"bottom of convertTapped:");
}

If you are accessing mediaItems from the users iPod library they maybe in the cloud. Use
[self.mediaItem valueForProperty:MPMediaItemPropertyIsCloudItem]
as far as I know you can not access these assets or force them to stream

Related

How to parse ShopStyle JSON in Objective-C

I have a snippet of some JSON which contains ShopStyle products here: https://docs.google.com/document/d/1konfjof33sgNngxIgq_sCyKmCcDda-ziXnOfUUxeKas/edit?usp=sharing
How do I go about getting the products' names and ids from the JSON? So far, I have the following code:
NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:#"http://api.shopstyle.com/api/v2/products?pid=%#&fts=%#&offset=0&limit=50", apiKey, searchkeywords]];
NSLog(#"%#", URL);
[NSURLConnection sendAsynchronousRequest:[[NSURLRequest alloc] initWithURL:URL] queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (error) {
//[self.delegate fetchingGroupsFailedWithError:error];
} else {
//[self.delegate receivedGroupsJSON:data];
NSDictionary *rest_data = [NSJSONSerialization JSONObjectWithData:data
options:0
error:NULL];
NSLog(#"rest_data = %#", rest_data);
for (NSDictionary *topComment in[rest_data objectForKey:#"products"]) {
[self processCommentThread:topComment andLevel:0];
}
NSLog(#"GET COMMENTS RETURN:%#", commentsContainer);
[self performSelectorOnMainThread:#selector(doneFormatting) withObject:nil waitUntilDone:YES];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:[NSString stringWithFormat:#"%#", rest_data] delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:nil, nil];
[alert show];
}
}];
/*
PSSProductQuery *productQuery = [[PSSProductQuery alloc] init];
productQuery.searchTerm = searchBar.text;
__weak typeof(self) weakSelf = self;
[[PSSClient sharedClient] searchProductsWithQuery:productQuery offset:nil limit:nil success:^(NSUInteger totalCount, NSArray *availableHistogramTypes, NSArray *products) {
weakSelf.products = products;
[resultsTableView reloadData];
NSLog(#"_products = %#", _products);
resultsTableView.hidden = NO;
} failure:^(int *operation, NSError *error) {
}];
*/
}
- (void)processCommentThread:(NSDictionary *)comments andLevel:(int)level {
#autoreleasepool {
NSMutableDictionary *comment = [[NSMutableDictionary alloc] init];
if (!([comments objectForKey:#"name"] == nil)) {
[comment setObject:[comments objectForKey:#"name"] forKey:#"name"];
}
if (!([comments objectForKey:#"id"] == nil)) {
[comment setObject:[comments objectForKey:#"id"] forKey:#"id"];
}
}
}
-(void)doneFormatting{
[myTableView reloadData];
}

video of image array in xcode

I have taken screen shoot of images and stored its document directory path to an array..
i want to create a video by passing this array.. here is my code for creating the video
-(void)writeImagesAsMovie:(NSArray *)array toPath:(NSString *)path
{
NSError *error1 = nil;
NSFileManager *fileMgr = [NSFileManager defaultManager];
if ([fileMgr removeItemAtURL:[NSURL fileURLWithPath:path] error:&error1]!=YES)
{
NSLog(#"Unable to delete file: %#", [error1 localizedDescription]);
}
UIImage *first = [UIImage imageWithContentsOfFile:[array objectAtIndex:0]];
CGSize frameSize = first.size;
NSError *error = nil;
AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:
[NSURL fileURLWithPath:path] fileType:AVFileTypeMPEG4
error:&error];
if(error)
{
NSLog(#"error creating AssetWriter: %#",[error description]);
}
NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
AVVideoCodecH264, AVVideoCodecKey,
[NSNumber numberWithInt:frameSize.width], AVVideoWidthKey,
[NSNumber numberWithInt:frameSize.height], AVVideoHeightKey,
nil];
AVAssetWriterInput* writerInput = [AVAssetWriterInput
assetWriterInputWithMediaType:AVMediaTypeVideo
outputSettings:videoSettings];
NSMutableDictionary *attributes = [[NSMutableDictionary alloc] init];
[attributes setObject:[NSNumber numberWithUnsignedInt:kCVPixelFormatType_32RGBA] forKey:(NSString*)kCVPixelBufferPixelFormatTypeKey];
[attributes setObject:[NSNumber numberWithUnsignedInt:frameSize.width] forKey:(NSString*)kCVPixelBufferWidthKey];
[attributes setObject:[NSNumber numberWithUnsignedInt:frameSize.height] forKey:(NSString*)kCVPixelBufferHeightKey];
AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor
assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput
sourcePixelBufferAttributes:attributes];
[videoWriter addInput:writerInput];
// fixes all errors
writerInput.expectsMediaDataInRealTime = YES;
//Start a session:
[videoWriter startWriting];
[videoWriter startSessionAtSourceTime:kCMTimeZero];
CVPixelBufferRef buffer = NULL;
int fps = 25;
int cnt = 0;
for (NSString *filename in array)
{
if (adaptor.assetWriterInput.readyForMoreMediaData)
{
cnt++;
CMTime frameTime = CMTimeMake(1, fps);
CMTime lastTime = CMTimeMake(cnt, fps);
CMTime presentTime = CMTimeAdd(lastTime, frameTime);
UIImage *imgFrame=[UIImage imageWithContentsOfFile:filename];
buffer = [self pixelBufferFromCGImage:[imgFrame CGImage]];
BOOL result = [adaptor appendPixelBuffer:buffer withPresentationTime:presentTime];
if (result == NO) {
NSLog(#"failed to append buffer");
NSLog(#"The error is %#", [videoWriter error]);
}
if(buffer) {
CVBufferRelease(buffer);
}
}
else {
NSLog(#"error");
cnt--;
}
}
// finish the session
[writerInput markAsFinished];
[videoWriter finishWritingWithCompletionHandler:^{
}];
CVPixelBufferPoolRelease(adaptor.pixelBufferPool);
UIAlertView *saveAlert = [[UIAlertView alloc] initWithTitle:#"Complete" message:#"Finished making movie" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[saveAlert show];
}
- (CVPixelBufferRef) pixelBufferFromCGImage: (CGImageRef) cgiImage {
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
[NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
nil];
CVPixelBufferRef pxbuffer = NULL;
CVPixelBufferCreate(kCFAllocatorDefault, CGImageGetWidth(cgiImage),
CGImageGetHeight(cgiImage), kCVPixelFormatType_32ARGB, (__bridge CFDictionaryRef) options,
&pxbuffer);
CVPixelBufferLockBaseAddress(pxbuffer, 0);
void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);
CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(pxdata, CGImageGetWidth(cgiImage),
CGImageGetHeight(cgiImage), 8, 4*CGImageGetWidth(cgiImage), rgbColorSpace,
kCGImageAlphaNoneSkipFirst);
CGContextConcatCTM(context, CGAffineTransformMakeRotation(0));
CGAffineTransform flipVertical = CGAffineTransformMake(
1, 0, 0, -1, 0, CGImageGetHeight(cgiImage)
);
CGContextConcatCTM(context, flipVertical);
CGAffineTransform flipHorizontal = CGAffineTransformMake(
-1.0, 0.0, 0.0, 1.0, CGImageGetWidth(cgiImage), 0.0
);
CGContextConcatCTM(context, flipHorizontal);
CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(cgiImage),
CGImageGetHeight(cgiImage)), cgiImage);
CGColorSpaceRelease(rgbColorSpace);
CGContextRelease(context);
CVPixelBufferUnlockBaseAddress(pxbuffer, 0);
return pxbuffer;
}
This code helps me to create the video but the video is not proper and all the pixels are blurred....
in .m file.
import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
-(void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(IBAction)createVideo:(id)sender
{
NSError *error = nil;
NSFileManager *fileMgr = [NSFileManager defaultManager];
NSString *documentsDirectory = [NSHomeDirectory()
stringByAppendingPathComponent:#"Documents"];
NSString *videoOutputPath = [documentsDirectory stringByAppendingPathComponent:#"test_output.mp4"];
if ([fileMgr removeItemAtPath:videoOutputPath error:&error] != YES)
NSLog(#"Unable to delete file: %#", [error localizedDescription]);
CGSize imageSize = CGSizeMake(400, 200);
NSUInteger fps = 30;
NSMutableArray *imageArray;
imageArray = [[NSMutableArray alloc] initWithObjects:#"photo1.png",#"photo2.png",#"photo3.png",#"photo4.png",#"photo5.png", nil];
NSArray* imagePaths = [[NSBundle mainBundle] pathsForResourcesOfType:#"png" inDirectory:nil];
imageArray = [[NSMutableArray alloc] initWithCapacity:imagePaths.count];
NSLog(#"-->imageArray.count= %lu", (unsigned long)imageArray.count);
for (NSString* path in imagePaths)
{
[imageArray addObject:[UIImage imageWithContentsOfFile:path]];
}
NSLog(#"Start building video from defined frames.");
AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:
[NSURL fileURLWithPath:videoOutputPath] fileType:AVFileTypeQuickTimeMovie
error:&error];
NSParameterAssert(videoWriter);
NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
AVVideoCodecH264, AVVideoCodecKey,
[NSNumber numberWithInt:imageSize.width], AVVideoWidthKey,
[NSNumber numberWithInt:imageSize.height], AVVideoHeightKey,
nil];
AVAssetWriterInput* videoWriterInput = [AVAssetWriterInput
assetWriterInputWithMediaType:AVMediaTypeVideo
outputSettings:videoSettings];
AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor
assetWriterInputPixelBufferAdaptorWithAssetWriterInput:videoWriterInput
sourcePixelBufferAttributes:nil];
NSParameterAssert(videoWriterInput);
NSParameterAssert([videoWriter canAddInput:videoWriterInput]);
videoWriterInput.expectsMediaDataInRealTime = YES;
[videoWriter addInput:videoWriterInput];
[videoWriter startWriting];
[videoWriter startSessionAtSourceTime:kCMTimeZero];
CVPixelBufferRef buffer = NULL;
int frameCount = 0;
double numberOfSecondsPerFrame = 6;
double frameDuration = fps * numberOfSecondsPerFrame;
NSLog(#"**************************************************");
for(UIImage * img in imageArray)
{
buffer = [self pixelBufferFromCGImage:[img CGImage]];
BOOL append_ok = NO;
int j = 0;
while (!append_ok && j < 30) {
if (adaptor.assetWriterInput.readyForMoreMediaData) {
NSLog(#"Processing video frame (%d,%d)",frameCount,[imageArray count]);
CMTime frameTime = CMTimeMake(frameCount*frameDuration,(int32_t) fps);
append_ok = [adaptor appendPixelBuffer:buffer withPresentationTime:frameTime];
if(!append_ok){
NSError *error = videoWriter.error;
if(error!=nil) {
NSLog(#"Unresolved error %#,%#.", error, [error userInfo]);
}
}
}
else {
printf("adaptor not ready %d, %d\n", frameCount, j);
[NSThread sleepForTimeInterval:0.1];
}
j++;
}
if (!append_ok) {
printf("error appending image %d times %d\n, with error.", frameCount, j);
}
frameCount++;
}
NSLog(#"**************************************************");
[videoWriterInput markAsFinished];
[videoWriter finishWriting];
AVMutableComposition* mixComposition = [AVMutableComposition composition];
NSString *bundleDirectory = [[NSBundle mainBundle] bundlePath];
NSString *audio_inputFilePath = [bundleDirectory stringByAppendingPathComponent:#"30secs.mp3"];
NSURL *audio_inputFileUrl = [NSURL fileURLWithPath:audio_inputFilePath];
NSURL *video_inputFileUrl = [NSURL fileURLWithPath:videoOutputPath];
NSString *outputFilePath = [documentsDirectory stringByAppendingPathComponent:#"final_video.mp4"];
NSURL *outputFileUrl = [NSURL fileURLWithPath:outputFilePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:outputFilePath])
[[NSFileManager defaultManager] removeItemAtPath:outputFilePath error:nil];
CMTime nextClipStartTime = kCMTimeZero;
AVURLAsset* videoAsset = [[AVURLAsset alloc]initWithURL:video_inputFileUrl options:nil];
CMTimeRange video_timeRange = CMTimeRangeMake(kCMTimeZero,videoAsset.duration);
AVMutableCompositionTrack *a_compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
[a_compositionVideoTrack insertTimeRange:video_timeRange ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:nextClipStartTime error:nil];
AVURLAsset* audioAsset = [[AVURLAsset alloc]initWithURL:audio_inputFileUrl options:nil];
CMTimeRange audio_timeRange = CMTimeRangeMake(kCMTimeZero, audioAsset.duration);
AVMutableCompositionTrack *b_compositionAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
[b_compositionAudioTrack insertTimeRange:audio_timeRange ofTrack:[[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:nextClipStartTime error:nil];
AVAssetExportSession* _assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetHighestQuality];
_assetExport.outputFileType = #"public.mpeg-4";
_assetExport.outputURL = outputFileUrl;
[_assetExport exportAsynchronouslyWithCompletionHandler:
^(void ) {
//[self saveVideoToAlbum:outputFilePath];
}
];
NSLog(#"DONE.....outputFilePath--->%#", outputFilePath);
}
-(CVPixelBufferRef) pixelBufferFromCGImage: (CGImageRef) image
{
CGSize size = CGSizeMake(400, 200);
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
[NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
nil];
CVPixelBufferRef pxbuffer = NULL;
CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault,
size.width,
size.height,
kCVPixelFormatType_32ARGB,
(__bridge CFDictionaryRef) options,
&pxbuffer);
if (status != kCVReturnSuccess){
NSLog(#"Failed to create pixel buffer");
}
CVPixelBufferLockBaseAddress(pxbuffer, 0);
void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);
CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(pxdata, size.width,
size.height, 8, 4*size.width, rgbColorSpace,(CGBitmapInfo)
kCGImageAlphaNoneSkipLast);
CGContextConcatCTM(context, CGAffineTransformMakeRotation(0));
CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image),
CGImageGetHeight(image)), image);
CGColorSpaceRelease(rgbColorSpace);
CGContextRelease(context);
CVPixelBufferUnlockBaseAddress(pxbuffer, 0);
return pxbuffer;
}
#end
in .h file...
import
import Foundation/Foundation.h
import CoreMedia/CoreMedia.h
import CoreVideo/CoreVideo.h
import CoreGraphics/CoreGraphics.h
import AVFoundation/AVFoundation.h
import QuartzCore/QuartzCore.h
#interface ViewController : UIViewController
-(IBAction)createVideo:(id)sender;
#end
and also add following framework..
CoreMedia.framework
CoreVideo.framework
CoreGraphics.framework
AVFoundation.framework
QuartzCore.framework

Memory don't release

Here is my code:
-(void) encodeStationsBack
{
if (context == nil)
{
context = [(radioAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
NSLog(#"After managedObjectContext: %#", context);
}
// here is JSON parsing
int i=0;
int count = stations.count;
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Station" inManagedObjectContext:context];
NSMutableArray* parsedData = [[NSMutableArray alloc] init];
while(stations.count > 0) {
NSString*string = [[NSString alloc] initWithString:[stations objectAtIndex:0]];
if (![string isEqual:#""]) {
NSMutableDictionary*dic = [[NSMutableDictionary alloc]init];
// NSLog(#"%#", string);
NSData*data = [[NSData alloc] initWithData:[string dataUsingEncoding:NSUTF8StringEncoding]];
NSMutableDictionary* pars;
#try {
pars = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
}
#catch (NSException *exception) {
NSLog(#"%# , %#", exception.description, exception.reason);
}
#finally {
}
// NSMutableDictionary* pars =[[NSMutableDictionary alloc]initWithDictionary:[NSJSONSerialization JSONObjectWithData:data
// options:kNilOptions/*NSJSONReadingMutableContainers*/ error:nil]];
[pars retain];
[dic setObject:[[pars objectForKey:#"nm"]mutableCopy] forKey:#"nm"];
[dic setObject:[[pars objectForKey:#"btr"]mutableCopy] forKey:#"btr"];
[dic setObject:[[pars objectForKey:#"id"]mutableCopy] forKey:#"id"];
[dic setObject:[[pars objectForKey:#"cntr"]mutableCopy] forKey:#"cntr"];
[dic setObject:[[pars objectForKey:#"gnr"]mutableCopy] forKey:#"gnr"];
[pars release];
#try {
[parsedData addObject:[NSDictionary dictionaryWithDictionary:dic]];
}
#catch (NSException* exc) {
NSLog(#"%#, %#", exc.description, exc.reason);
}
[dic release];
[data release];
[string release];
[stations removeObjectAtIndex:0];
// if (i%1000==0) {
// NSLog(#"nnnn %i %i", parsedData.count, stations.count);
// }
i++;
float k = count;
k = (i + 1)/k;
[self performSelectorOnMainThread:#selector(increaseProgress:) withObject:[NSNumber numberWithFloat:k] waitUntilDone:YES];
}
else {
[stations removeObjectAtIndex:0];
}
}
[stations release];
i = 0;
while (parsedData.count > 0) {
Station*station = [[Station alloc] initWithEntity:entity insertIntoManagedObjectContext:nil];
[station setName:[[[parsedData objectAtIndex:0] objectForKey:#"nm"]mutableCopy]];
[station setBit:[[[parsedData objectAtIndex:0] objectForKey:#"btr"]mutableCopy]];
[station setEnabled:[NSNumber numberWithInt:1]];
//encoding id of the station
unsigned int tempInt;
NSScanner *scanner= [[NSScanner alloc] init];
scanner = [NSScanner scannerWithString:[[parsedData objectAtIndex:0] objectForKey:#"id"]];
[scanner scanHexInt:&tempInt];
NSNumber *numb = [[NSNumber alloc] init];
numb = [NSNumber numberWithInt:tempInt];
numb = [NSNumber numberWithInt: ([numb integerValue] ^ sec )];
[station setNumber: [NSNumber numberWithInt:[numb intValue]]];
//encoding country ID
tempInt = 0;
scanner = [NSScanner scannerWithString:[[parsedData objectAtIndex:0] objectForKey:#"cntr"]];
[scanner scanHexInt:&tempInt];
numb = [NSNumber numberWithInt:tempInt];
numb = [NSNumber numberWithInt:(([numb integerValue] ^ sec ))];
if (![numb isEqualToNumber:[NSNumber numberWithInt:n]])
{
[station setCountryID:[NSNumber numberWithInt:[numb intValue]]];
}
else
{
[station setCountryID:[NSNumber numberWithInt:-1]];
}
//encoding genre ID
tempInt = 0;
scanner = [NSScanner scannerWithString:[[parsedData objectAtIndex:0] objectForKey:#"gnr"]];
[scanner scanHexInt:&tempInt];
numb = [NSNumber numberWithInt:tempInt];
numb = [NSNumber numberWithInt:(([numb integerValue] ^ sec ))];
if (![numb isEqualToNumber:[NSNumber numberWithInt:N]])
{
[station setGenerID:[NSNumber numberWithInt:[numb intValue]]];
}
else
{
[station setGenerID: [NSNumber numberWithInt:-1]];
}
[station setOrder:[NSNumber numberWithInt:i]];
[context insertObject:station];
float k = count;
k = (i + 1)/k;
[self performSelectorOnMainThread:#selector(increaseProgress:) withObject:[NSNumber numberWithFloat:k] waitUntilDone:YES];
// NSLog(#"%i", i);
[parsedData removeObjectAtIndex:0];
[station release];
// [station release];
i++;
}
[parsedData release];
[self performSelectorOnMainThread:#selector(deleteAllFromDB) withObject:nil waitUntilDone:YES];
[context save:nil];
}
I can't understand why my app uses so mutch memory (~150 mb). I tryed to look on my code with analyze. Nothing interestig xCode thinks that all is ok.
Here is what I see with Instruments
Instruments
you have alloced in the loop and de alloced outside the loop in scanner there are other mistakes like this. have a look and make a code review.
id obj1 =[[pars objectForKey:#"nm"]mutableCopy];
[dic setObject:obj1 forKey:#"nm"];
[obj1 release]; // No memory leak
[dic setObject:[[pars objectForKey:#"btr"]mutableCopy] forKey:#"btr"];//memory leak
[dic setObject:[[pars objectForKey:#"id"]mutableCopy] forKey:#"id"];//memory leak
[dic setObject:[[pars objectForKey:#"cntr"]mutableCopy] forKey:#"cntr"];//memory leak
[dic setObject:[[pars objectForKey:#"gnr"]mutableCopy] forKey:#"gnr"];//memory leak
Change all setObject:forKey:

Fix unicode characters in NSString

I am getting a string response from the Google Directions API that contains characters that are supposed to represent a different-language character. Similiar to Ƨ³, similiar to these type of characters. I think the characters are portugese, but anyways my string contains like this:
\U00e3o
(I am not sure if those are zeroes or 'O's)
I am not sure what the technical term for these characters are, but how can I fix them in my string so they print properly.
Thank you
UPDATE:
I have updated my question title with the correct term 'unicode'.
I have checked a few questions:
NSString Unicode display
Detect Unicode characters in NSString on iPhone
iOS HTML Unicode to NSString?
And a few others. I have followed the answer, but the unicode characters are not fixed.
UPDATE:
Here is my code to get the response from GDirection.
Forming the request and getting a response:
AFHTTPClient *_httpClient = [AFHTTPClient clientWithBaseURL:[NSURL URLWithString:#"http://maps.googleapis.com/"]];
[_httpClient registerHTTPOperationClass: [AFJSONRequestOperation class]];
[_httpClient setDefaultHeader:#"Accept" value:#"application/json"];
NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
[parameters setObject:[NSString stringWithFormat:#"%f,%f", location.coordinate.latitude, location.coordinate.longitude] forKey:#"origin"];
[parameters setObject:[NSString stringWithFormat:#"%f,%f", location2.coordinate.latitude, location2.coordinate.longitude] forKey:#"destination"];
[parameters setObject:#"false" forKey:#"sensor"];
[parameters setObject:#"driving" forKey:#"mode"];
[parameters setObject:#"metric" forKey: #"units"];
NSMutableURLRequest *request = [_httpClient requestWithMethod:#"GET" path: #"maps/api/directions/json" parameters:parameters];
request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
AFHTTPRequestOperation *operation = [_httpClient HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSInteger statusCode = operation.response.statusCode;
if (statusCode == 200) {
[self parseResponse:responseObject];
} else {
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) { }];
[_httpClient enqueueHTTPRequestOperation:operation];
}
Retrieving information from response object:
- (void)parseResponse:(NSDictionary *)response {
NSString *status = [response objectForKey: #"status"];
if (![status isEqualToString: #"OK"]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:[NSString stringWithFormat: #"Google Directions Response Status: %#", status] delegate:self cancelButtonTitle:#"Dismiss" otherButtonTitles:nil, nil];
[alert show];
}
else {
NSArray *routes = [response objectForKey:#"routes"];
NSDictionary *routePath = [routes lastObject];
if (routePath) {
NSString *overviewPolyline = [[routePath objectForKey: #"overview_polyline"] objectForKey:#"points"];
legs = [routePath valueForKey: #"legs"];
if (legs) {
/* DIRECTION SET ================================================================================================================================
*/
directionOverview = [[NSMutableDictionary alloc] init];
NSString *legsDis = [NSString stringWithFormat: #"%#", [[legs valueForKey: #"distance"] valueForKey: #"text"]];
NSString *kmDistance = [self cutStringToPreference: legsDis];
if (kmDistance) {
[directionOverview setObject:kmDistance forKey: #"distance"];
milesLabel.text = kmDistance;
milesLabel.font = [UIFont fontWithName:#"interstate" size: 20.0];
}
NSString *durationText = [NSString stringWithFormat: #"%#", [[legs valueForKey: #"duration"] valueForKey: #"text"]];
durationText = [self cutStringToPreference: durationText];
if (durationText) {
[directionOverview setObject:durationText forKey: #"duration"];
}
NSString *startAddress = [NSString stringWithFormat: #"%#", [legs valueForKey: #"start_address"]];
startAddress = [self cutStringToPreference: startAddress];
NSString *endAddress = [NSString stringWithFormat: #"%#", [legs valueForKey: #"end_address"]];
endAddress = [self cutStringToPreference: endAddress];
[directionOverview setObject:startAddress forKey: #"origin"];
[directionOverview setObject:endAddress forKey: #"destination"];
NSArray *steps = [legs valueForKey: #"steps"];
if (steps) {
instructionArray = [[NSMutableArray alloc] init];
durationArray = [[NSMutableArray alloc] init];
distanceArray = [[NSMutableArray alloc] init];
int number = [[[steps lastObject] valueForKey: #"html_instructions"] count];
for (int i = 1; i <= number; ++i) {
NSString *instruction = [[[steps lastObject] valueForKey: #"html_instructions"] objectAtIndex: i-1];
instruction = [self cutStringToPreference: instruction];
instruction = [self flattenHTML: instruction];
instruction = [self stringByDecodingHTMLEntitiesInString: instruction];
[instructionArray addObject: instruction];
NSString *distance = [[[[steps lastObject] valueForKey: #"distance"] objectAtIndex: i-1] valueForKey: #"text"];
[distanceArray addObject: distance];
NSString *duration = [[[[steps lastObject] valueForKey: #"duration"] objectAtIndex: i-1] valueForKey: #"text"];
[durationArray addObject: duration];
}
}
}
_path = [self decodePolyLine:overviewPolyline];
NSInteger numberOfSteps = _path.count;
CLLocationCoordinate2D coordinates[numberOfSteps];
for (NSInteger index = 0; index < numberOfSteps; index++) {
CLLocation *location = [_path objectAtIndex:index];
CLLocationCoordinate2D coordinate = location.coordinate;
coordinates[index] = coordinate;
}
polyLine = [MKPolyline polylineWithCoordinates:coordinates count:numberOfSteps];
[self.mapView addOverlay:polyLine];
}
}
}
Displaying the text in a label:
NSString *overviewAddressText = [NSString stringWithFormat: #"%# to %#", [directionOverview objectForKey: #"origin"], [directionOverview objectForKey: #"destination"]];
overviewAddress.text = overviewAddressText;
UPDATE:
Image of label
So as you can see, in the label, the text contains this kind of substring: S/U00e3o, which is a word that has an unsupported character. How can I fix that so that unicode turns into this: São

Objective C: OpenAL changing Pitch issue

im having a hard time on OpenAL framework... i just want to change the pitch in playback action... what code is missing in my project.. im new in objective c,iOS development. hoping for your kind consideration, thanks in advance.. here is my code for the three button (RECORD,STOP,Play)..
-(void)startRecording:(UIButton *)sender
{ //for recording
recStopBtn.hidden = NO;
recStopBtn.enabled =YES;
playRecBtn.enabled = NO;
loading.hidden = NO;
[loading startAnimating];
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *err = nil;
[audioSession setCategory :AVAudioSessionCategoryPlayAndRecord error:&err];
if(err)
{
NSLog(#"audioSession: %# %d %#", [err domain], [err code], [[err userInfo] description]);
return;
}
[audioSession setActive:YES error:&err];
err = nil;
if(err)
{
NSLog(#"audioSession: %# %d %#", [err domain], [err code], [[err userInfo] description]);
return;
}
recordSetting = [[NSMutableDictionary alloc] init];
// We can use kAudioFormatAppleIMA4 (4:1 compression) or kAudioFormatLinearPCM for nocompression
[recordSetting setValue :[NSNumber numberWithInt:kAudioFormatAppleIMA4] forKey:AVFormatIDKey];
// We can use 44100, 32000, 24000, 16000 or 12000 depending on sound quality
[recordSetting setValue:[NSNumber numberWithFloat:16000.0] forKey:AVSampleRateKey];
// We can use 2(if using additional h/w) or 1 (iPhone only has one microphone)
[recordSetting setValue:[NSNumber numberWithInt: 1] forKey:AVNumberOfChannelsKey];
// These settings are used if we are using kAudioFormatLinearPCM format
//[recordSetting setValue :[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
//[recordSetting setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
//[recordSetting setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];
recorderFilePath = [NSString stringWithFormat:#"%#/MySound.caf", DOCUMENTS_FOLDER];
NSLog(#"recorderFilePath: %#",recorderFilePath);
NSURL *url = [NSURL fileURLWithPath:recorderFilePath];
err = nil;
NSData *audioData = [NSData dataWithContentsOfFile:[url path] options: 0 error:&err];
if(audioData)
{
NSFileManager *fm = [NSFileManager defaultManager];
[fm removeItemAtPath:[url path] error:&err];
}
err = nil;
recorder = [[ AVAudioRecorder alloc] initWithURL:url settings:recordSetting error:&err];
if(!recorder){
NSLog(#"recorder: %# %d %#", [err domain], [err code], [[err userInfo] description]);
UIAlertView *alert =
[[UIAlertView alloc] initWithTitle: #"Warning"
message: [err localizedDescription]
delegate: nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
return;
}
//prepare to record
[recorder setDelegate:self];
[recorder prepareToRecord];
recorder.meteringEnabled = YES;
BOOL audioHWAvailable = audioSession.inputIsAvailable;
if (! audioHWAvailable) {
UIAlertView *cantRecordAlert =
[[UIAlertView alloc] initWithTitle: #"Warning"
message: #"Audio input hardware not available"
delegate: nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[cantRecordAlert show];
return;
}
// start recording
[recorder record];
lblStatusMsg.text = #"Recording...";
//recIcon.image = [UIImage imageNamed:#"rec_icon.png"];
//progressView.progress = 0.0;
//timer = [NSTimer scheduledTimerWithTimeInterval:6.0 target:self selector:#selector(handleTimer) userInfo:nil repeats:YES];
}
-(void)stopRecord:(UIButton *)sender
{
loading.hidden = YES;
[loading stopAnimating];
recStartBtn.enabled = YES;
recStartBtn.hidden = NO;
playRecBtn.hidden = NO;
playRecBtn.enabled = YES;
recStopBtn.enabled = NO;
recStopBtn.hidden = YES;
[recorder stop];
[timer invalidate];
lblStatusMsg.text = #"Stopped";
// recIcon.image = [UIImage imageNamed:#"rec_icon2.png"];
}
-(void)playRecord:(UIButton *)sender
{
recorderFilePath = [NSString stringWithFormat:#"%#/MySound.caf", DOCUMENTS_FOLDER];
NSURL *urlRecord = [NSURL fileURLWithPath:recorderFilePath isDirectory:NO];
NSError *errorRecord;
soundRecord = [[AVAudioPlayer alloc] initWithContentsOfURL:urlRecord error:&errorRecord];
[soundRecord play];
}
-(void)changePitch:(UIButton *)sender
{
alSourcef(recorderFilePath, AL_PITCH, 1.2f);//this kinda troubles me,the source. =(
[soundRecord play];//this one also...
}
The first argument of the alSourcef method isn't an NSString file path, it's an ALuint representing an audio source.
See the example oalTouch (specifically the oalPlayback class) for how to set up an OpenAL source from a URL.