AVAssetExportSession audio missing in iOS9 - audio

I have a code to export a video file. The code works fine on iOS8, but on devices with iOS9 there is no sound on the video file.
I think the problem is on the AVAssetExportSession, but I'm unable to finde the issue and fix it.
What is also weird, is the asset works fine when I export it for playback.
(void)export {
self.videoComposition.renderScale = 1.0;
self.videoComposition.animationTool = [self coreAnimationTool];
FakeAsset * assetFaker = [FakeAsset new];
[assetFaker fakeAssetWithDuration:self.currentTime completitionBlock:^(AVAsset *asset) {
[self addEmptyBackgroundTrackFromAsset:asset];
AVAssetExportSession * exportSession =
[AVAssetExportSession exportSessionWithAsset:[self.composition copy]
presetName:AVAssetExportPresetHighestQuality];
[MovieExport setCurrentExporter:exportSession];
NSUInteger i = 0;
NSString * path;
do {
path =
[NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:#"movieExport%i.mov",i]]; i++;
} while ([[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:NULL]);
NSURL * url = [NSURL fileURLWithPath:path];
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
[[NSFileManager defaultManager] removeItemAtURL:url error:nil];
}
exportSession.outputURL = url;
exportSession.outputFileType = AVFileTypeMPEG4;
exportSession.audioMix = self.audioMix;
exportSession.videoComposition = self.videoComposition;
exportSession.timeRange = CMTimeRangeMake(kCMTimeZero, self.currentTime);
[exportSession exportAsynchronouslyWithCompletionHandler:^{
switch (exportSession.status) {
case AVAssetExportSessionStatusCompleted:
self.callback(#{MovieCreatorVideoURL : exportSession.outputURL}, nil);
break;
case AVAssetExportSessionStatusFailed:
self.callback(nil,exportSession.error);
break;
case AVAssetExportSessionStatusCancelled:
self.callback(nil, exportSession.error);
break;
default:
break;
}
}];
}];
}
- (void)exportForPlayback {
self.videoComposition.renderScale = 2.0;
FakeAsset * assetFaker = [FakeAsset new];
[assetFaker fakeAssetWithDuration:self.currentTime completitionBlock:^(AVAsset *asset){
[self addEmptyBackgroundTrackFromAsset:asset];
AVPlayerItem * playerItem = [AVPlayerItem playerItemWithAsset:self.composition];
playerItem.videoComposition = self.videoComposition;
playerItem.audioMix = self.audioMix;
MovieMetadata * metaData = [MovieMetadata new];
metaData.orderedElements = self.orderedElements;
metaData.orderedMarkers = self.movieMarkers;
metaData.elementBeginTimes = self.elementBeginTimes;
metaData.filmSize = self.filmSize;
metaData.filmFormat = self.filmFormat;
metaData.filmQuality = self.filmQuality;
self.userInfos =
#{MovieCreatorAnimations : self.animationLayer,
MovieCreatorAVPlayerItem : playerItem,
MovieCreatorMetadata : metaData};
self.callback(self.userInfos, nil);
}];
}

I found the issue.
My AVMutableComposition have multiple AVMutableCompositionTrack. If one AVMutableCompositionTrack don't have a track, the video exported will be mute on iOS9 but will work correctly on iOS8
To fix this issue, when I initialize the AVMutableCompositionTrack, I add audio with no sound.
-(void)initEmptyAudio:(AVMutableCompositionTrack *) obj{
NSString* path = [[NSBundle mainBundle] pathForResource:#"emptyAudio" ofType:#"mp3"];
NSURL* audio_inputFileUrl = [NSURL fileURLWithPath:path];
AVURLAsset* audioAsset = [[AVURLAsset alloc]initWithURL:audio_inputFileUrl options:nil];
CMTimeRange audio_timeRange = CMTimeRangeMake(kCMTimeZero, audioAsset.duration);
[obj insertTimeRange:audio_timeRange ofTrack:[[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:CMTimeMake(0,1) error:nil];
}

Related

Implemetation of videos in video with blur effect in objective c

I have to make a video editor with a blur effect on video .
Can someone please guide me some useful links or the way this task should be proceeded .I have tried doing overlapping of videos but it doesn't bring me videos in center exactly.
- (void) overlapVideos{
AVURLAsset* firstAsset = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"BearVideo" ofType:#"mp4"]] options:nil];
AVURLAsset * secondAsset = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"BearVideo" ofType:#"mp4"]] options:nil];
AVMutableComposition* mixComposition = [[AVMutableComposition alloc] init];
AVMutableCompositionTrack *firstTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
[firstTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, firstAsset.duration) ofTrack:[[firstAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:kCMTimeZero error:nil];
AVMutableCompositionTrack *secondTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
[secondTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, secondAsset.duration) ofTrack:[[secondAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:kCMTimeZero error:nil];
AVMutableVideoCompositionInstruction * instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, firstAsset.duration);
AVMutableVideoCompositionLayerInstruction *FirstlayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:firstTrack];
CGAffineTransform Scale = CGAffineTransformMakeScale(0.6f,0.6f);
CGAffineTransform Move = CGAffineTransformMakeTranslation(140,20);
[FirstlayerInstruction setTransform:CGAffineTransformConcat(Scale,Move) atTime:kCMTimeZero];
AVMutableVideoCompositionLayerInstruction *SecondlayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:secondTrack];
CGAffineTransform SecondScale = CGAffineTransformMakeScale(0.9f,0.9f);
CGAffineTransform SecondMove = CGAffineTransformMakeTranslation(0,0);
[SecondlayerInstruction setTransform:CGAffineTransformConcat(SecondScale,SecondMove) atTime:kCMTimeZero];
instruction.layerInstructions = [NSArray arrayWithObjects:FirstlayerInstruction,SecondlayerInstruction,nil];;
AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition];
videoComposition.instructions = [NSArray arrayWithObject:instruction];
videoComposition.frameDuration = CMTimeMake(1, 30);
videoComposition.renderSize = CGSizeMake(1280, 720);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *myPathDocs = [documentsDirectory stringByAppendingPathComponent:#"overlapVideo.mov"];
if([[NSFileManager defaultManager] fileExistsAtPath:myPathDocs])
{
[[NSFileManager defaultManager] removeItemAtPath:myPathDocs error:nil];
}
NSURL *url = [NSURL fileURLWithPath:myPathDocs];
AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetHighestQuality];
exporter.outputURL=url;
[exporter setVideoComposition:videoComposition];
exporter.outputFileType = AVFileTypeQuickTimeMovie;
[exporter exportAsynchronouslyWithCompletionHandler:^
{
dispatch_async(dispatch_get_main_queue(), ^{
[self exportDidFinish:exporter];
});
}];
}
- (void)exportDidFinish:(AVAssetExportSession*)session
{
NSURL *outputURL = session.outputURL;
if(self.videodelegateObj!=nil){
[_videodelegateObj videoOverlappingFinished:outputURL];
}
}
-(void)applyBlurOnAsset:(AVAsset *)asset Completion:(void(^)(BOOL success, NSError* error, NSURL* videoUrl))completion{
CIFilter *filter = [CIFilter filterWithName:#"CIGaussianBlur"];
AVVideoComposition *composition = [AVVideoComposition videoCompositionWithAsset: asset
applyingCIFiltersWithHandler:^(AVAsynchronousCIImageFilteringRequest *request){
// Clamp to avoid blurring transparent pixels at the image edges
CIImage *source = [request.sourceImage imageByClampingToExtent];
[filter setValue:source forKey:kCIInputImageKey];
[filter setValue:[NSNumber numberWithDouble:10.0] forKey:kCIInputRadiusKey];
CIImage *output = [filter.outputImage imageByCroppingToRect:request.sourceImage.extent];
[request finishWithImage:output context:nil];
}];
NSURL *outputUrl = [[NSURL alloc] initWithString:#"Your Output path"];
[[NSFileManager defaultManager] removeItemAtURL:outputUrl error:nil];
AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPreset960x540] ;
exporter.videoComposition = composition;
exporter.outputFileType = AVFileTypeMPEG4;
if (outputUrl){
exporter.outputURL = outputUrl;
[exporter exportAsynchronouslyWithCompletionHandler:^{
switch ([exporter status]) {
case AVAssetExportSessionStatusFailed:
NSLog(#"crop Export failed: %#", [[exporter error] localizedDescription]);
if (completion){
dispatch_async(dispatch_get_main_queue(), ^{
completion(NO,[exporter error],nil);
});
return;
}
break;
case AVAssetExportSessionStatusCancelled:
NSLog(#"crop Export canceled");
if (completion){
dispatch_async(dispatch_get_main_queue(), ^{
completion(NO,nil,nil);
});
return;
}
break;
default:
break;
}
if (completion){
dispatch_async(dispatch_get_main_queue(), ^{
completion(YES,nil,outputUrl);
});
}
}];
}
}
Kindly give some guidance.Any help or guidance in this direction would be highly appreciated.Thanks in advance.

Front Camera recording is MUTE

I am working with some camera recoding app. I want to record video using front and back camera both. For back camera my video is working fine but for front camera my final video is mute (without audio).
CODE:
- (id)initWithPreviewView:(UIView *)previewView {
self = [super init];
if (self) {
NSError *error;
self.captureSession = [[AVCaptureSession alloc] init];
self.captureSession.sessionPreset = AVCaptureSessionPresetHigh;
//AVCaptureSessionPresetHigh AVCaptureSessionPresetPhoto
// AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDevice *videoDevice;
// if (isNeededToSave)
// {
// //for Front cam
// videoDevice = [self frontCamera];
//
// }
// else
// {
// //for back cam
videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
// }
AVCaptureDeviceInput *videoIn = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
if (error) {
NSLog(#"Video input creation failed");
return nil;
}
if (![self.captureSession canAddInput:videoIn]) {
NSLog(#"Video input add-to-session failed");
return nil;
}
[self.captureSession addInput:videoIn];
/*Take PHoto*/
self.isUsingFrontFacingCamera = 0;
// Make a still image output
stillImageOutput = [AVCaptureStillImageOutput new];
[stillImageOutput addObserver:self forKeyPath:#"capturingStillImage" options:NSKeyValueObservingOptionNew context:(__bridge void *)(AVCaptureStillImageIsCapturingStillImageContext)];
if ( [self.captureSession canAddOutput:stillImageOutput] )
[self.captureSession addOutput:stillImageOutput];
// Make a video data output
videoDataOutput = [AVCaptureVideoDataOutput new];
// we want BGRA, both CoreGraphics and OpenGL work well with 'BGRA'
NSDictionary *rgbOutputSettings = [NSDictionary dictionaryWithObject:
[NSNumber numberWithInt:kCMPixelFormat_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey];
[videoDataOutput setVideoSettings:rgbOutputSettings];
[videoDataOutput setAlwaysDiscardsLateVideoFrames:YES]; // discard if the data output queue is blocked (as we process the still image)
// create a serial dispatch queue used for the sample buffer delegate as well as when a still image is captured
// a serial dispatch queue must be used to guarantee that video frames will be delivered in order
// see the header doc for setSampleBufferDelegate:queue: for more information
videoDataOutputQueue = dispatch_queue_create("VideoDataOutputQueue", DISPATCH_QUEUE_SERIAL);
[videoDataOutput setSampleBufferDelegate:self queue:videoDataOutputQueue];
if ( [self.captureSession canAddOutput:videoDataOutput] )
[self.captureSession addOutput:videoDataOutput];
[[videoDataOutput connectionWithMediaType:AVMediaTypeVideo] setEnabled:NO];
/*Take PHoto*/
// save the default format
self.defaultFormat = videoDevice.activeFormat;
defaultVideoMaxFrameDuration = videoDevice.activeVideoMaxFrameDuration;
AVCaptureDevice *audioDevice= [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
AVCaptureDeviceInput *audioIn = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:&error];
[self.captureSession addInput:audioIn];
self.fileOutput = [[AVCaptureMovieFileOutput alloc] init];
[self.captureSession addOutput:self.fileOutput];
self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];
self.previewLayer.frame = previewView.bounds;
self.previewLayer.contentsGravity = kCAGravityResizeAspectFill;
self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[previewView.layer insertSublayer:self.previewLayer atIndex:0];
[self.captureSession startRunning];
}
return self;
}
- (void)switchCameras
{
// [self frontCamera];
// AVCaptureDevicePosition desiredPosition;
// desiredPosition = AVCaptureDevicePositionFront;
AVCaptureDevicePosition desiredPosition;
NSInteger isFront = [[NSUserDefaults standardUserDefaults] integerForKey:#"isUsingFrontFacingCamera"];
if (isFront)
desiredPosition = AVCaptureDevicePositionBack;
else
desiredPosition = AVCaptureDevicePositionFront;
for (AVCaptureDevice *d in [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) {
if ([d position] == desiredPosition) {
[[self.previewLayer session] beginConfiguration];
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:d error:nil];
for (AVCaptureInput *oldInput in [[self.previewLayer session] inputs]) {
[[self.previewLayer session] removeInput:oldInput];
}
[[self.previewLayer session] addInput:input];
[[self.previewLayer session] commitConfiguration];
break;
}
}
if (isFront==0)
{
[[NSUserDefaults standardUserDefaults] setInteger:1 forKey:#"isUsingFrontFacingCamera"];
}
else
{
[[NSUserDefaults standardUserDefaults] setInteger:0 forKey:#"isUsingFrontFacingCamera"];
}
[[NSUserDefaults standardUserDefaults] synchronize];
//NSInteger isFront1= [[NSUserDefaults standardUserDefaults] integerForKey:#"isUsingFrontFacingCamera"];
}

Find assets in library - add to a AVMutableComposition - export = crash

I've been struggling with adding assets from the iPhone Photo Library to a AVMutableComposition and then export them. Here is what I got:
Finding the assets: (here I grab the AVURLAsset)
-(void) findAssets {
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
// Enumerate just the photos and videos group by using ALAssetsGroupSavedPhotos.
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
// Within the group enumeration block, filter to enumerate just videos.
[group setAssetsFilter:[ALAssetsFilter allVideos]];
[group enumerateAssetsUsingBlock:^(ALAsset *alAsset, NSUInteger index, BOOL *innerStop){
// The end of the enumeration is signaled by asset == nil.
if (alAsset) {
ALAssetRepresentation *representation = [alAsset defaultRepresentation];
NSURL *url = [representation url];
AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:url options:nil];
// Do something interesting with the AV asset.
[thumbs addObject:alAsset];
[assets addObject:avAsset];
}else if(alAsset == nil){
[self createScroll];
}
}];
}
failureBlock: ^(NSError *error) {
// Typically you should handle an error more gracefully than this.
NSLog(#"No groups");
}];
[library release];
}
Here I add a asset to my composition (I use the first object in the array for testing only.
-(void) addToCompositionWithAsset:(AVURLAsset*)_asset{
NSError *editError = nil;
composition = [AVMutableComposition composition];
AVURLAsset* sourceAsset = [assets objectAtIndex:0];
Float64 inSeconds = 1.0;
Float64 outSeconds = 2.0;
// calculate time
CMTime inTime = CMTimeMakeWithSeconds(inSeconds, 600);
CMTime outTime = CMTimeMakeWithSeconds(outSeconds, 600);
CMTime duration = CMTimeSubtract(outTime, inTime);
CMTimeRange editRange = CMTimeRangeMake(inTime, duration);
[composition insertTimeRange:editRange ofAsset:sourceAsset atTime:composition.duration error:&editError];
if (!editError) {
CMTimeGetSeconds (composition.duration);
}
}
And finally I export the comp and here it crashes
-(void)exportComposition {
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetPassthrough];
NSLog (#"can export: %#", exportSession.supportedFileTypes);
NSArray *dirs = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [dirs objectAtIndex:0];
NSString *exportPath = [documentsDirectoryPath stringByAppendingPathComponent:EXPORT_NAME];
[[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil];
NSURL *exportURL = [NSURL fileURLWithPath:exportPath];
exportSession.outputURL = exportURL;
exportSession.outputFileType = AVFileTypeQuickTimeMovie;//#"com.apple.quicktime-movie";
[exportSession exportAsynchronouslyWithCompletionHandler:^{
NSLog (#"i is in your block, exportin. status is %d",
exportSession.status);
switch (exportSession.status) {
case AVAssetExportSessionStatusFailed:
case AVAssetExportSessionStatusCompleted: {
[self performSelectorOnMainThread:#selector (exportDone:)
withObject:nil
waitUntilDone:NO];
break;
}
};
}];
}
Does anyone have an idea of what it might be? It crashes on
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetPassthrough];
And I tried different presets and outputFileTypes.
Thanks
* SOLVED *
I have to answer my own question now when I have solved. It's amazing that I've been struggling with this for a whole day and then I fix it right after posting a question :)
I changed and moved:
composition = [AVMutableComposition
composition];
to:
composition = [[AVMutableComposition
alloc] init];
I think I was too tired when I was working on this yesterday. Thanks guys!

create video from array of UIImages and save the video to iPhone library. AVAssetLibrary +AVFoundation

Problem in saving video to iPhone Library.
i have an array of UIImages,and two buttons ,"convertToVideo"&"saveToiPhoneLib"
-(IBAction) convertToVideo
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
NSString *savedVideoPath = [documentsDirectory stringByAppendingPathComponent:#"videoOutput"];
printf(" \n\n\n-Video file == %s--\n\n\n",[savedVideoPath UTF8String]);
[self writeImageAsMovie:imageArray toPath:savedVideoPath size:self.view.frame.size duration:3];
}
here i'm passing the imageArray and savedVideoPath to the function below
-(void)writeImageAsMovie:(NSArray *)array toPath:(NSString*)path size:(CGSize)size duration:(int)duration
{
NSError *error = nil;
AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:
[NSURL fileURLWithPath:path] fileType:AVFileTypeQuickTimeMovie
error:&error];
NSParameterAssert(videoWriter);
NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
AVVideoCodecH264, AVVideoCodecKey,
[NSNumber numberWithInt:size.width], AVVideoWidthKey,
[NSNumber numberWithInt:size.height], AVVideoHeightKey,
nil];
AVAssetWriterInput* writerInput = [[AVAssetWriterInput
assetWriterInputWithMediaType:AVMediaTypeVideo
outputSettings:videoSettings] retain];
// NSDictionary *bufferAttributes = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt:kCVPixelFormatType_32ARGB], kCVPixelBufferPixelFormatTypeKey, nil];
AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor
assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput
sourcePixelBufferAttributes:nil];
NSParameterAssert(writerInput);
NSParameterAssert([videoWriter canAddInput:writerInput]);
[videoWriter addInput:writerInput];
//Start a session:
[videoWriter startWriting];
[videoWriter startSessionAtSourceTime:kCMTimeZero];
CVPixelBufferRef buffer = NULL;
//convert uiimage to CGImage.
buffer = [self pixelBufferFromCGImage:[[array objectAtIndex:0] CGImage]];
[adaptor appendPixelBuffer:buffer withPresentationTime:kCMTimeZero];
//Write samples:
......
//Finish the session:
[writerInput markAsFinished];
[videoWriter finishWriting];
}
generate a CVPixelBufferRef here
- (CVPixelBufferRef) pixelBufferFromCGImage: (CGImageRef) image
{
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
[NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
nil];
CVPixelBufferRef pxbuffer = NULL;
CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, self.view.frame.size.width,
self.view.frame.size.height, kCVPixelFormatType_32ARGB, (CFDictionaryRef) options,
&pxbuffer);
NSParameterAssert(status == kCVReturnSuccess && pxbuffer != NULL);
CVPixelBufferLockBaseAddress(pxbuffer, 0);
void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);
NSParameterAssert(pxdata != NULL);
CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(pxdata, self.view.frame.size.width,
self.view.frame.size.height, 8, 4*self.view.frame.size.width, rgbColorSpace,
kCGImageAlphaNoneSkipFirst);
NSParameterAssert(context);
CGContextConcatCTM(context, CGAffineTransformMakeRotation(0));
CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image),
CGImageGetHeight(image)), image);
CGColorSpaceRelease(rgbColorSpace);
CGContextRelease(context);
CVPixelBufferUnlockBaseAddress(pxbuffer, 0);
return pxbuffer;
}
saving to the iPhone library
-(IBAction) saveToiPhoneLib
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
NSString *getImagePath = [basePath stringByAppendingPathComponent:#"videoOutput"];
printf(" \n\n\n-Video file == %s--\n\n\n",[getImagePath UTF8String]);
UISaveVideoAtPathToSavedPhotosAlbum ( getImagePath,self, #selector(video:didFinishSavingWithError: contextInfo:), nil);
}
- (void) video: (NSString *) videoPath didFinishSavingWithError: (NSError *) error contextInfo: (void *) contextInfo {
NSLog(#"Finished saving video with error: %#", error);
}
but while saving i m getting error message:-
Finished saving video with error: Error Domain=ALAssetsLibraryErrorDomain Code=-3302 "Invalid data" UserInfo=0x1d59f0 {NSLocalizedFailureReason=There was a problem writing this asset because the data is invalid and cannot be viewed or played., NSLocalizedRecoverySuggestion=Try with different data, NSLocalizedDescription=Invalid data}
please let me know my mistake. thanks in advance
-(void)convertimagetoVideo
{
///////////// setup OR function def if we move this to a separate function ////////////
// this should be moved to its own function, that can take an imageArray, videoOutputPath, etc...
NSError *error = nil;
// set up file manager, and file videoOutputPath, remove "test_output.mp4" if it exists...
//NSString *videoOutputPath = #"/Users/someuser/Desktop/test_output.mp4";
NSFileManager *fileMgr = [NSFileManager defaultManager];
NSString *documentsDirectory = [NSHomeDirectory()
stringByAppendingPathComponent:#"Documents"];
NSString *videoOutputPath = [documentsDirectory stringByAppendingPathComponent:#"test_output.mp4"];
//NSLog(#"-->videoOutputPath= %#", videoOutputPath);
// get rid of existing mp4 if exists...
if ([fileMgr removeItemAtPath:videoOutputPath error:&error] != YES)
NSLog(#"Unable to delete file: %#", [error localizedDescription]);
CGSize imageSize = CGSizeMake(400, 200);
// NSUInteger fps = 30;
NSUInteger fps = 30;
//NSMutableArray *imageArray;
//imageArray = [[NSMutableArray alloc] initWithObjects:#"download.jpeg", #"download2.jpeg", nil];
NSMutableArray *imageArray;
NSArray* imagePaths = [[NSBundle mainBundle] pathsForResourcesOfType:#"png" inDirectory:nil];
imageArray = [[NSMutableArray alloc] initWithCapacity:imagePaths.count];
NSLog(#"-->imageArray.count= %i", imageArray.count);
for (NSString* path in imagePaths)
{
[imageArray addObject:[UIImage imageWithContentsOfFile:path]];
//NSLog(#"-->image path= %#", path);
}
////////////// end setup ///////////////////////////////////
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];
//Start a session:
[videoWriter startWriting];
[videoWriter startSessionAtSourceTime:kCMTimeZero];
CVPixelBufferRef buffer = NULL;
//convert uiimage to CGImage.
int frameCount = 0;
double numberOfSecondsPerFrame = 6;
double frameDuration = fps * numberOfSecondsPerFrame;
//for(VideoFrame * frm in imageArray)
NSLog(#"**************************************************");
for(UIImage * img in imageArray)
{
//UIImage * img = frm._imageFrame;
buffer = [self pixelBufferFromCGImage:[img CGImage]];
BOOL append_ok = NO;
int j = 0;
while (!append_ok && j < 30) {
if (adaptor.assetWriterInput.readyForMoreMediaData) {
//print out status:
NSLog(#"Processing video frame (%d,%d)",frameCount,[imageArray count]);
//CMTime frameTime = CMTimeMake((int64_t), (int32_t)2);
CMTime frameTime = CMTimeMake(frameCount*frameDuration,(int32_t) fps);
NSLog(#"seconds = %f, %u, %d", CMTimeGetSeconds(frameTime),fps,j);
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(#"**************************************************");
//Finish the session:
[videoWriterInput markAsFinished];
[videoWriter finishWriting];
NSLog(#"Write Ended");
}
-(void)CompileFilestomakeVideo
{
// set up file manager, and file videoOutputPath, remove "test_output.mp4" if it exists...
//NSString *videoOutputPath = #"/Users/someuser/Desktop/test_output.mp4";
NSString *documentsDirectory = [NSHomeDirectory()
stringByAppendingPathComponent:#"Documents"];
NSString *videoOutputPath = [documentsDirectory stringByAppendingPathComponent:#"test_output.mp4"];
//NSLog(#"-->videoOutputPath= %#", videoOutputPath);
// get rid of existing mp4 if exists...
AVMutableComposition* mixComposition = [AVMutableComposition composition];
NSString *bundleDirectory = [[NSBundle mainBundle] bundlePath];
// audio input file...
NSString *audio_inputFilePath = [bundleDirectory stringByAppendingPathComponent:#"30secs.mp3"];
NSURL *audio_inputFileUrl = [NSURL fileURLWithPath:audio_inputFilePath];
// this is the video file that was just written above, full path to file is in --> videoOutputPath
NSURL *video_inputFileUrl = [NSURL fileURLWithPath:videoOutputPath];
// create the final video output file as MOV file - may need to be MP4, but this works so far...
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];
//nextClipStartTime = CMTimeAdd(nextClipStartTime, a_timeRange.duration);
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 = #"com.apple.quicktime-movie";
//_assetExport.outputFileType = #"public.mpeg-4";
//NSLog(#"support file types= %#", [_assetExport supportedFileTypes]);
_assetExport.outputURL = outputFileUrl;
[_assetExport exportAsynchronouslyWithCompletionHandler:
^(void ) {
[self saveVideoToAlbum:outputFilePath];
}
];
///// THAT IS IT DONE... the final video file will be written here...
NSLog(#"DONE.....outputFilePath--->%#", outputFilePath);
// the final video file will be located somewhere like here:
// /Users/caferrara/Library/Application Support/iPhone Simulator/6.0/Applications/D4B12FEE-E09C-4B12-B772-7F1BD6011BE1/Documents/outputFile.mov
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
}
- (void) saveVideoToAlbum:(NSString*)path {
NSLog(#"saveVideoToAlbum");
if(UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(path)){
UISaveVideoAtPathToSavedPhotosAlbum (path, self, #selector(video:didFinishSavingWithError: contextInfo:), nil);
}
}
-(void) video:(NSString *)videoPath didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
if(error)
NSLog(#"error: %#", error);
else
NSLog(#" OK");
}
////////////////////////
- (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,
kCGImageAlphaPremultipliedFirst);
//kCGImageAlphaNoneSkipFirst);
CGContextConcatCTM(context, CGAffineTransformMakeRotation(0));
CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image),
CGImageGetHeight(image)), image);
CGColorSpaceRelease(rgbColorSpace);
CGContextRelease(context);
CVPixelBufferUnlockBaseAddress(pxbuffer, 0);
return pxbuffer;
}
That’s simply too much code to check for errors. Make sure you can start the export session, that you really get pixel buffers for your images, that the writer is ready for receiving more data, that the buffer gets appended without errors, that the export session finishes with success and that the output movie file exists and actually contains some data. Only then you can try and save it to the system photo album. Check all the available error information along the way so that you know where the thing breaks for the first time. (Another thing is that you are simply taking code from the web and pasting it together, which is simply not going to work for AV programming.)
Yes, I had the same error:
Error Domain=AVFoundationErrorDomain Code=-11823 "Cannot Save" UserInfo=0x193ce0 {NSLocalizedRecoverySuggestion=Try saving again., NSUnderlyingError=0x179e40 "The operation couldn’t be completed. (OSStatus error -12412.)", NSLocalizedDescription=Cannot Save}
But only on simulator, when I ran on a device, the save to the photo library worked just fine.
Use the code Below
- (void)creatingVideo {
//get full path of video file from documents directory
NSError *error = nil;
NSFileManager *fileMgr = [NSFileManager defaultManager];
NSString *documentsDirectory = [self applicationDocumentsDirectory];
NSString *videoOutputPath = [documentsDirectory stringByAppendingPathComponent:#"test_output.mov"];
// get rid of existing mp4 if exists...
if ([fileMgr removeItemAtPath:videoOutputPath error:&error] != YES)
NSLog(#"Unable to delete file it does not exits on path");
//size of the video frame
CGSize imageSize = CGSizeMake(640,480);
//CGSize imageSize = CGSizeMake(1280, 720);
//frame per second
NSUInteger fps = 30;
NSLog(#"Start building video from defined frames.");
//AvAsset library to create video of images
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] retain];
NSDictionary *bufferAttributes = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:kCVPixelFormatType_32ARGB], kCVPixelBufferPixelFormatTypeKey, nil];
AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:videoWriterInput sourcePixelBufferAttributes:bufferAttributes];
NSParameterAssert(videoWriterInput);
NSParameterAssert([videoWriter canAddInput:videoWriterInput]);
videoWriterInput.expectsMediaDataInRealTime = YES;
[videoWriter addInput:videoWriterInput];
//Start a session:
[videoWriter startWriting];
[videoWriter startSessionAtSourceTime:kCMTimeZero];
CVPixelBufferRef buffer = NULL;
//frameCount.
int frameCount = 0;
double frameDuration;
double numberOfSecondsPerFrame = appDelegate.delaySecond;
NSLog(#"**************************video creation started********************************");
for (int i = 0; i<[self.arrImageDataDict count]; i++) {
{
#autoreleasepool{
UIImage *img1 = nil;
img1 = [self getImageForVideoCreation:i];
buffer = [self pixelBufferFromCGImage: [img1 CGImage]];
if (buffer == NULL) {
NSLog(#"Pixel buffer not created");
} else {
BOOL append_ok = NO;
int j = 0;
while (!append_ok && j < 20) {
if (adaptor.assetWriterInput.readyForMoreMediaData) {
//print out status:
NSLog(#"Processing video frame (%d,%d) delay %f",frameCount,[self.arrImageDataDict count],numberOfSecondsPerFrame);
frameDuration = fps * numberOfSecondsPerFrame;
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++;
CVPixelBufferRelease(buffer);
buffer = nil;
}
}
}
}
//Finish the session:
[videoWriterInput markAsFinished];
//get the iOS version of the device
float version = [[[UIDevice currentDevice] systemVersion] floatValue];
if (version < 6.0)
{
[videoWriter finishWriting];
//NSLog (#"finished writing iOS version:%f",version);
} else {
[videoWriter finishWritingWithCompletionHandler:^(){
//NSLog (#"finished writing iOS version:%f",version);
}];
}
CVPixelBufferPoolRelease(adaptor.pixelBufferPool);
[videoWriter release];
[videoWriterInput release];
//OK now add an audio file to move file
AVMutableComposition* mixComposition = [AVMutableComposition composition];
//Get the saved audio song path to merge it in video
NSURL *audio_inputFileUrl ;
NSString *filePath = [self applicationDocumentsDirectory];
NSString *outputFilePath1 = [filePath stringByAppendingPathComponent:#"mySong.m4a"];
audio_inputFileUrl = [[NSURL alloc]initFileURLWithPath:outputFilePath1];
// this is the video file that was just written above
NSURL *video_inputFileUrl = [[NSURL alloc]initFileURLWithPath:videoOutputPath];;
[NSThread sleepForTimeInterval:2.0];
// create the final video output file as MOV file - may need to be MP4, but this works so far...
NSString *outputFilePath = [documentsDirectory stringByAppendingPathComponent:#"Slideshow_video.mov"];
NSURL *outputFileUrl = [[NSURL alloc]initFileURLWithPath:outputFilePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:outputFilePath])
[[NSFileManager defaultManager] removeItemAtPath:outputFilePath error:nil];
//AVURLAsset get video without audio
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:kCMTimeZero error:nil];
[videoAsset release];
[NSThread sleepForTimeInterval:3.0];
//If audio song merged
if (![self.appDelegate.musicFilePath isEqualToString:#"Not set"])
{
//*************************make sure all exception is off***********************
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];
if (![audioAsset tracksWithMediaType:AVMediaTypeAudio].count == 0) {
[b_compositionAudioTrack insertTimeRange:audio_timeRange ofTrack:[[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:kCMTimeZero error:nil];
}
[audioAsset release];
}
// Cleanup, in both success and fail cases
[audio_inputFileUrl release];
[video_inputFileUrl release];
[NSThread sleepForTimeInterval:0.1];
//AVAssetExportSession to export the video
AVAssetExportSession* _assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetHighestQuality];
_assetExport.outputFileType = AVFileTypeQuickTimeMovie;
_assetExport.outputURL = outputFileUrl;
[_assetExport exportAsynchronouslyWithCompletionHandler:^(void){
switch (_assetExport.status) {
case AVAssetExportSessionStatusCompleted:
#if !TARGET_IPHONE_SIMULATOR
[self writeVideoToPhotoLibrary:outputFileUrl];
#endif
[self RemoveSlideshowImagesInTemp];
[self removeAudioFileFromDocumentsdirectory:outputFilePath1];
[self removeAudioFileFromDocumentsdirectory:videoOutputPath];
[outputFileUrl release];
[_assetExport release];
//NSLog(#"AVAssetExportSessionStatusCompleted");
dispatch_async(dispatch_get_main_queue(), ^{
if (alrtCreatingVideo && alrtCreatingVideo.visible) {
[alrtCreatingVideo dismissWithClickedButtonIndex:alrtCreatingVideo.firstOtherButtonIndex animated:YES];
[databaseObj isVideoCreated:appDelegate.pro_id];
[self performSelector:#selector(successAlertView) withObject:nil afterDelay:0.0];
}
});
break;
case AVAssetExportSessionStatusFailed:
NSLog(#"Failed:%#",_assetExport.error);
break;
case AVAssetExportSessionStatusCancelled:
NSLog(#"Canceled:%#",_assetExport.error);
break;
default:
break;
}
}];
}
//writeVideoToPhotoLibrary
- (void)writeVideoToPhotoLibrary:(NSURL *)url
{
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeVideoAtPathToSavedPhotosAlbum:url completionBlock:^(NSURL *assetURL, NSError *error){
if (error) {
NSLog(#"Video could not be saved");
}
}];
[library release];
}

How do you get an SQLITE database (Mydb.db) to load every time you start the iPhone App?

I have an app that access a static SQLITE database when running. A user or application is not allowed to alter or update this database. However, I need to add records or change field content to keep up with changing URLs etc. I use MesaSQLite to update the single table. But when I re-open the app in Xcode Simulator, none of the changes took effect. It's as if the app did not reload the updated database.
How can I get a reload to take place? Keep in mind that I'm still covered in shrink wrap because I'm so new to coding !!!
I'm not really sure of the SQL part. but I think that you will need to reload the table content after getting the update from the database. If you post some code, I can help you better. Here's how to reload the table:
[myTable reloadData];
And you will need to update the table with the new data in
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
This is an IOS4.2 iPhone app. Here is the code for accessing and displaying the sort results of the database. The purpose is to use the database to sort delegates by event and state, then display the results. The displayed delegates are linked to a website. Again, the user and the app DO NOT alter the database, it's static. I use an SQLite editor to make changes and import them back into the databases' single table. I just need the table reloaded when this portion of the code runs.
I'll need to know what code and where to insert it for table reload.
Thanks for your help !!!!!
//
// delegateList.m
// foundingFathers
//
// Created by __ on 6/23/10.
// Copyright 2010 MyCompanyName. All rights reserved.
//
import "delegateList.h"
static sqlite3 *database = nil;
#implementation delegateList
#synthesize tableView;
-(void)viewDidLoad
{
nameArray = [[NSMutableArray alloc] init];
stateArray = [[NSMutableArray alloc] init];
yearsArray = [[NSMutableArray alloc] init];
contArray = [[NSMutableArray alloc] init];
indArray = [[NSMutableArray alloc] init];
confArray = [[NSMutableArray alloc] init];
constArray = [[NSMutableArray alloc] init];
urlArray = [[NSMutableArray alloc] init];
stateNameArray = [[NSMutableArray alloc] init];
eventNameArray = [[NSMutableArray alloc] init];
[self loadStateData];
[self loadEventData];
// Setup some globals
databaseName = #"mydb.db";
// Get the path to the documents directory and append the databaseName
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
// Execute the "checkAndCreateDatabase" function
[self checkAndCreateDatabase];
// Query the database for all delegates
[self loadDataWithState:#"" andEvent:0];
}
-(void)loadStateData
{
[stateNameArray addObject:#"All States"];
[stateNameArray addObject:#"Connecticut"];
[stateNameArray addObject:#"Delaware"];
[stateNameArray addObject:#"Georgia"];
[stateNameArray addObject:#"Maryland"];
[stateNameArray addObject:#"Massachusetts"];
[stateNameArray addObject:#"New Hampshire"];
[stateNameArray addObject:#"New Jersey"];
[stateNameArray addObject:#"New York"];
[stateNameArray addObject:#"North Carolina"];
[stateNameArray addObject:#"Pennsylvania"];
[stateNameArray addObject:#"Rhode Island"];
[stateNameArray addObject:#"South Carolina"];
[stateNameArray addObject:#"Virginia"];
}
-(void)loadEventData
{
[eventNameArray addObject:#"All Events"];
[eventNameArray addObject:#"Continental Association"];
[eventNameArray addObject:#"Declaration of Independence"];
[eventNameArray addObject:#"Confederation of States"];
[eventNameArray addObject:#"US Constitution"];
}
-(IBAction)nextPressed:(id)sender
{
[self.navigationController pushViewController:nondelegateList animated:YES];
}
-(IBAction)menuPressed:(id)sender
{
[self.navigationController popToViewController:mainmenu animated:YES];
}
/*
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
switch (interfaceOrientation) {
case UIInterfaceOrientationPortrait:
case UIInterfaceOrientationPortraitUpsideDown:
return NO;
break;
default:
return YES;
break;
}
}*/
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [nameArray count]+1;
}
-(UITableViewCell *)tableView:(UITableView *)tblView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"MyIdentifier";
MyIdentifier = #"tblViewCell";
TableViewCell *cell = (TableViewCell *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if(cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"TableCellView" owner:self options:nil];
cell = tblCell;
}
UILabel* lbl;
if (indexPath.row == 0) //table Headers
{
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
lbl = (UILabel *)[cell viewWithTag:1];
[lbl setFont:[UIFont boldSystemFontOfSize:14]];
lbl.text = #"Name";
[lbl setTextAlignment:UITextAlignmentLeft];
lbl = (UILabel *)[cell viewWithTag:2];
[lbl setFont:[UIFont boldSystemFontOfSize:14]];
lbl.text = #"State";
[lbl setTextAlignment:UITextAlignmentLeft];
} else {
//[lbl setFont:[[lbl font] fontWithSize:9]];
[cell setSelectionStyle:UITableViewCellSelectionStyleBlue];
lbl = (UILabel *)[cell viewWithTag:1];
[lbl setTextAlignment:UITextAlignmentLeft];
[lbl setFont:[UIFont systemFontOfSize:14]];
lbl.text = [nameArray objectAtIndex:indexPath.row-1];
lbl = (UILabel *)[cell viewWithTag:2];
[lbl setTextAlignment:UITextAlignmentLeft];
[lbl setFont:[UIFont systemFontOfSize:14]];
lbl.text = [stateArray objectAtIndex:indexPath.row-1];
}
return cell;
}
(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0) {
return;
}
NSURL* page = [NSURL URLWithString:[urlArray objectAtIndex:indexPath.row - 1] ];
NSURLRequest* pageRequest = [NSURLRequest requestWithURL:page];
[webTitle setTitle:[nameArray objectAtIndex:indexPath.row - 1]];
[web loadRequest:pageRequest];
[self.navigationController pushViewController:webView animated:YES];
}
-(void) checkAndCreateDatabase{
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
success = [fileManager fileExistsAtPath:databasePath];
if(success) return;
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];
[fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
//[fileManager release];
}
-(void)loadDataWithState:(NSString*)stateSearch andEvent:(int)eventSearch
{
BOOL hasEvent = (BOOL)eventSearch;
BOOL hasState = !([stateSearch isEqualToString:#"All States"] || stateSearch.length <=0);
NSString* state = stateSearch;
NSString* event = nil;
switch (eventSearch) {
case 1:
event = #"continental";
break;
case 2:
event = #"declaration";
break;
case 3:
event = #"confederation";
break;
case 4:
event = #"constitution";
break;
default:
break;
}
// Open the database from the users filessytem
if(database || sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
// Setup the SQL Statement and compile it for faster access
NSString* sqlString = nil;
const char *sqlStatement;
if (hasEvent && hasState) {
sqlString = [[[[#"select * from founding_fathers where "stringByAppendingString:event] stringByAppendingString:#" like 'X%%' and State like '"] stringByAppendingString:state] stringByAppendingString:#"'"];
}
if (hasEvent && !hasState) {
sqlString = [[#"select * from founding_fathers where " stringByAppendingString:event] stringByAppendingString:#" like 'X%%'"];
}
if (!hasEvent && hasState) {
sqlString = [[#"select * from founding_fathers where state = '" stringByAppendingString:state] stringByAppendingString:#"'"];
}
if (!hasEvent && !hasState) {
sqlString= #"select * from founding_fathers";
}
unsigned int lengthOfMessage = [sqlString length];
char temp[lengthOfMessage + 1];
strcpy(temp, [sqlString cString]);
sqlStatement = temp;
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
// Loop through the results and add them to the feeds array
[nameArray removeAllObjects];
[stateArray removeAllObjects];
[yearsArray removeAllObjects];
[contArray removeAllObjects];
[indArray removeAllObjects];
[confArray removeAllObjects];
[constArray removeAllObjects];
[urlArray removeAllObjects];
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the data from the result row
NSString* dName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
NSString* dState = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
NSString* dYears = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];
NSString* dCont = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 4)];
NSString* dInd = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 5)];
NSString* dConf = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 6)];
NSString* dConst = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 7)];
NSString* dUrl = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 8)];
[nameArray addObject:dName];
[stateArray addObject:dState];
[yearsArray addObject:dYears];
[contArray addObject:dCont];
[indArray addObject:dInd];
[confArray addObject:dConf];
[constArray addObject:dConst];
[urlArray addObject:dUrl];
}
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
}
}
-(void)viewDidUnload
{
sqlite3_close(database);
}
-(IBAction)stateSearch:(id)sender
{
pickerArray = stateNameArray;
[picker reloadAllComponents];
[picker setHidden:NO];
[doneButton setHidden:NO];
}
-(IBAction)eventSearch:(id)sender
{
pickerArray = eventNameArray;
[picker reloadAllComponents];
[picker setHidden:NO];
[doneButton setHidden:NO];
}
(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return [pickerArray count];
}
(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [pickerArray objectAtIndex:row];
}
(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
}
(void) doneClicked:(id)sender
{
if (pickerArray == stateNameArray)
{
stateSearchChoice = [stateNameArray objectAtIndex:[picker selectedRowInComponent:0]];
[stateButton setTitle:stateSearchChoice];
}
if (pickerArray == eventNameArray) {
eventSearchChoice = [picker selectedRowInComponent:0];
[eventButton setTitle:[eventNameArray objectAtIndex:[picker selectedRowInComponent:0]]];
}
[picker setHidden:YES];
[doneButton setHidden:YES];
[self loadDataWithState:stateSearchChoice andEvent:eventSearchChoice];
[tableView reloadData];
}
#end

Resources