Inaccurate accelerometer update interval - iphone

I'm using the CoreMotion API and I would like to save the accelerometer's values every 10ms (100hz). The update intervals I obtained so far aren't accurate.
Here's an example of update intervals I got (in second):
0.010414999997
0.0105919999769
0.0117060000193
0.0198359999922
0.00989700001082
0.0100809999858
0.0100519999978
0.0106810000143
0.010420000006
0.0107459999854
0.0105899999908
0.0105130000156
0.0104829999909
0.0107439999992
0.010391000018
0.0105859999894
0.0102320000005
0.010134000011
0.0101929999946
0.010666999995
0.00996399999713
0.0123709999898
0.0181950000115
0.0107940000016
0.00988500000676
0.0101469999936
0.0103529999906
As you can see, some values are higher than 10ms.
Some more informations:
- Xcode 3.2.6 / iOS4.3 / armv7
- Tested on iPhone4 iOS5.1 and iPodTouch4 iOS4.3.3
- The source code:
-(void) viewDidLoad {
started = NO;
motionManager = [[CMMotionManager alloc] init];
if ([motionManager isAccelerometerAvailable]) {
motionManager.accelerometerUpdateInterval = 0.01; //100Hz
motionQueue = [[NSOperationQueue alloc] init];
[motionQueue setMaxConcurrentOperationCount:1]; // Serial operation queue
} else {
NSLog(#"Accelerometer is not available!\n");
}
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSMutableString *documentsDirectory = [[NSMutableString alloc] initWithString:[paths objectAtIndex:0]];
path = [[NSMutableString alloc] init];
[path setString:[NSString stringWithFormat:#"%#/timestamp.cap", documentsDirectory]];
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager removeItemAtPath:path error:NULL];
[fileManager createFileAtPath:path contents:nil attributes:nil];
}
- (IBAction) startStopButton:(id) sender {
if(!started) {
started = YES;
[sender setTitle:#"Stop" forState:UIControlStateNormal];
CMAccelerometerHandler dataHandler = ^(CMAccelerometerData *accelerometerData, NSError *error) {
NSString *content = [NSString stringWithFormat:#"%f\n", accelerometerData.timestamp];
NSFileHandle *fh = [NSFileHandle fileHandleForWritingAtPath:path];
[fh seekToEndOfFile];
[fh writeData:[content dataUsingEncoding:NSUTF8StringEncoding]];
[fh closeFile];
};
[motionManager startAccelerometerUpdatesToQueue:motionQueue withHandler:dataHandler];
} else {
started = NO;
[motionManager stopAccelerometerUpdates];
[motionQueue waitUntilAllOperationsAreFinished];
[sender setTitle:#"Start" forState:UIControlStateNormal];
}
}
Thank you in advance for your answers.

Related

Pause & resume video capture using AVCaptureMovieFileOutput and AVCaptureVideoDataOutput in iOS

I have to implement functionality to repeatedly pause and resume video capture in a single session, but have each new segment (the captured segments after each pause) added to the same video file, with AVFoundation. Currently, every time I press "stop" then "record" again, it just saves a new video file to my iPhone's Document directory and starts capturing to a new file. I need to be able to press the "record/stop" button over, only capture video & audio when record is active... then when the "done" button is pressed, have a single AV file with all the segments together. And all this needs to happen in the same capture session / preview session.
I am not using AVAssetWriterInput.
The only way I can think of to try this is when the "done" button is pressed, taking each individual output file and combining them together into a single file.
This code is working for iOS 5 but not for iOS 6. Actually for iOS 6, the first time when I pause recording (stop recording) AVCaptureFileOutputRecordingDelegate method (captureOutput: didFinishRecordingToOutputFileAtURL: fromConnections: error:) is called but after that when I start the recording the delegate method (captureOutput: didFinishRecordingToOutputFileAtURL: fromConnections: error:) is called again but it is not called at the time of stop recording.
I need a solution for that issue. Please help me.
//View LifeCycle
- (void)viewDidLoad
{
[super viewDidLoad];
self.finalRecordedVideoName = [self stringWithNewUUID];
arrVideoName = [[NSMutableArray alloc]initWithCapacity:0];
arrOutputUrl = [[NSMutableArray alloc] initWithCapacity:0];
CaptureSession = [[AVCaptureSession alloc] init];
captureDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
if ([captureDevices count] > 0)
{
NSError *error;
VideoInputDevice = [[AVCaptureDeviceInput alloc] initWithDevice:[self backFacingCamera] error:&error];
if (!error)
{
if ([CaptureSession canAddInput:VideoInputDevice])
[CaptureSession addInput:VideoInputDevice];
else
NSLog(#"Couldn't add video input");
}
else
{
NSLog(#"Couldn't create video input");
}
}
else
{
NSLog(#"Couldn't create video capture device");
}
//ADD VIDEO PREVIEW LAYER
NSLog(#"Adding video preview layer");
AVCaptureVideoPreviewLayer *layer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:CaptureSession];
[self setPreviewLayer:layer];
UIDeviceOrientation currentOrientation = [UIDevice currentDevice].orientation;
NSLog(#"%d",currentOrientation);
if (currentOrientation == UIDeviceOrientationPortrait)
{
PreviewLayer.orientation = AVCaptureVideoOrientationPortrait;
}
else if (currentOrientation == UIDeviceOrientationPortraitUpsideDown)
{
PreviewLayer.orientation = AVCaptureVideoOrientationPortraitUpsideDown;
}
else if (currentOrientation == UIDeviceOrientationLandscapeRight)
{
PreviewLayer.orientation = AVCaptureVideoOrientationLandscapeRight;
}
else if (currentOrientation == UIDeviceOrientationLandscapeLeft)
{
PreviewLayer.orientation = AVCaptureVideoOrientationLandscapeLeft;
}
[[self PreviewLayer] setVideoGravity:AVLayerVideoGravityResizeAspectFill];
//ADD MOVIE FILE OUTPUT
NSLog(#"Adding movie file output");
MovieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
VideoDataOutput = [[AVCaptureVideoDataOutput alloc] init];
[VideoDataOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()];
NSString* key = (NSString*)kCVPixelBufferBytesPerRowAlignmentKey;
NSNumber* value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA];
NSDictionary* videoSettings = [NSDictionary dictionaryWithObject:value forKey:key];
[VideoDataOutput setVideoSettings:videoSettings];
Float64 TotalSeconds = 60; //Total seconds
int32_t preferredTimeScale = 30; //Frames per second
CMTime maxDuration = CMTimeMakeWithSeconds(TotalSeconds, preferredTimeScale);//<<SET MAX DURATION
MovieFileOutput.maxRecordedDuration = maxDuration;
MovieFileOutput.minFreeDiskSpaceLimit = 1024 * 1024; //<<SET MIN FREE SPACE IN BYTES FOR RECORDING TO CONTINUE ON A VOLUME
//SET THE CONNECTION PROPERTIES (output properties)
[self CameraSetOutputProperties]; //(We call a method as it also has to be done after changing camera)
AVCaptureConnection *videoConnection = nil;
for ( AVCaptureConnection *connection in [MovieFileOutput connections] )
{
NSLog(#"%#", connection);
for ( AVCaptureInputPort *port in [connection inputPorts] )
{
NSLog(#"%#", port);
if ( [[port mediaType] isEqual:AVMediaTypeVideo] )
{
videoConnection = connection;
}
}
}
if([videoConnection isVideoOrientationSupported]) // **Here it is, its always false**
{
[videoConnection setVideoOrientation:[[UIDevice currentDevice] orientation]];
} NSLog(#"Setting image quality");
[CaptureSession setSessionPreset:AVCaptureSessionPresetLow];
//----- DISPLAY THE PREVIEW LAYER -----
CGRect layerRect = CGRectMake(5, 5, 299, ([[UIScreen mainScreen] bounds].size.height == 568)?438:348);
[self.PreviewLayer setBounds:layerRect];
[self.PreviewLayer setPosition:CGPointMake(CGRectGetMidX(layerRect),CGRectGetMidY(layerRect))];
if ([CaptureSession canAddOutput:MovieFileOutput])
[CaptureSession addOutput:MovieFileOutput];
[CaptureSession addOutput:VideoDataOutput];
//We use this instead so it goes on a layer behind our UI controls (avoids us having to manually bring each control to the front):
CameraView = [[UIView alloc] init];
[videoPreviewLayer addSubview:CameraView];
[videoPreviewLayer sendSubviewToBack:CameraView];
[[CameraView layer] addSublayer:PreviewLayer];
//----- START THE CAPTURE SESSION RUNNING -----
[CaptureSession startRunning];
}
#pragma mark - IBACtion Methods
-(IBAction)btnStartAndStopPressed:(id)sender
{
UIButton *StartAndStopButton = (UIButton*)sender;
if ([StartAndStopButton isSelected] == NO)
{
[StartAndStopButton setSelected:YES];
[btnPauseAndResume setEnabled:YES];
[btnBack setEnabled:NO];
[btnSwitchCameraInput setHidden:YES];
NSDate *date = [NSDate date];
NSLog(#" date %#",date);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *recordedFileName = nil;
recordedFileName = [NSString stringWithFormat:#"output%#.mov",date];
NSString *documentsDirectory = [paths objectAtIndex:0];
self.outputPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#",recordedFileName]];
NSLog(#"%#",self.outputPath);
[arrVideoName addObject:recordedFileName];
NSURL *outputURL = [[NSURL alloc] initFileURLWithPath:self.outputPath];
if ([[NSFileManager defaultManager] fileExistsAtPath:self.outputPath])
{
NSError *error;
if ([[NSFileManager defaultManager] removeItemAtPath:self.outputPath error:&error] == NO)
{
//Error - handle if requried
}
}
//Start recording
[MovieFileOutput startRecordingToOutputFileURL:outputURL recordingDelegate:self];
recordingTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(VideoRecording) userInfo:nil repeats:YES];
}
else
{
[StartAndStopButton setSelected:NO];
[btnPauseAndResume setEnabled:NO];
[btnBack setEnabled:YES];
[btnSwitchCameraInput setHidden:NO];
NSLog(#"STOP RECORDING");
WeAreRecording = NO;
[MovieFileOutput stopRecording];
[((ActOutAppDelegate *)ActOut_AppDelegate) showLoadingViewOnView:self.view withLabel:#"Please wait...."];
if ([recordingTimer isValid])
{
[recordingTimer invalidate];
recordingTimer = nil;
recordingTime = 30;
}
stopRecording = YES;
}
}
- (IBAction)btnPauseAndResumePressed:(id)sender
{
UIButton *PauseAndResumeButton = (UIButton*)sender;
if (PauseAndResumeButton.selected == NO)
{
PauseAndResumeButton.selected = YES;
NSLog(#"recording paused");
WeAreRecording = NO;
[MovieFileOutput stopRecording];
[self pauseTimer:recordingTimer];
[btnStartAndStop setEnabled:NO];
[btnBack setEnabled:YES];
[btnSwitchCameraInput setHidden:NO];
}
else
{
PauseAndResumeButton.selected = NO;
NSLog(#"recording resumed");
[btnStartAndStop setEnabled:YES];
[btnBack setEnabled:NO];
[btnSwitchCameraInput setHidden:YES];
WeAreRecording = YES;
NSDate *date = [NSDate date];
NSLog(#" date %#",date);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *recordedFileName = nil;
recordedFileName = [NSString stringWithFormat:#"output%#.mov",date];
NSString *documentsDirectory = [paths objectAtIndex:0];
self.outputPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#",recordedFileName]];
NSLog(#"%#",self.outputPath);
[arrVideoName addObject:recordedFileName];
NSURL *outputURL = [[NSURL alloc] initFileURLWithPath:self.outputPath];
if ([[NSFileManager defaultManager] fileExistsAtPath:self.outputPath])
{
NSError *error;
if ([[NSFileManager defaultManager] removeItemAtPath:self.outputPath error:&error] == NO)
{
//Error - handle if requried
}
}
[self resumeTimer:recordingTimer];
//Start recording
[MovieFileOutput startRecordingToOutputFileURL:outputURL recordingDelegate:self];
}
}
- (void) CameraSetOutputProperties
{
//SET THE CONNECTION PROPERTIES (output properties)
AVCaptureConnection *CaptureConnection = [MovieFileOutput connectionWithMediaType:AVMediaTypeVideo];
[CaptureConnection setVideoOrientation:AVCaptureVideoOrientationPortrait];
//Set frame rate (if requried)
CMTimeShow(CaptureConnection.videoMinFrameDuration);
CMTimeShow(CaptureConnection.videoMaxFrameDuration);
if (CaptureConnection.supportsVideoMinFrameDuration)
CaptureConnection.videoMinFrameDuration = CMTimeMake(1, CAPTURE_FRAMES_PER_SECOND);
if (CaptureConnection.supportsVideoMaxFrameDuration)
CaptureConnection.videoMaxFrameDuration = CMTimeMake(1, CAPTURE_FRAMES_PER_SECOND);
CMTimeShow(CaptureConnection.videoMinFrameDuration);
CMTimeShow(CaptureConnection.videoMaxFrameDuration);
}
- (AVCaptureDevice *) CameraWithPosition:(AVCaptureDevicePosition) Position
{
NSArray *Devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
for (AVCaptureDevice *Device in Devices)
{
if ([Device position] == Position)
{
NSLog(#"%d",Position);
return Device;
}
}
return nil;
}
#pragma mark - AVCaptureFileOutputRecordingDelegate Method
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
if(videoWriterInput.readyForMoreMediaData && WeAreRecording) [videoWriterInput appendSampleBuffer:sampleBuffer];
for(AVCaptureConnection *captureConnection in [captureOutput connections])
{
if ([captureConnection isVideoOrientationSupported])
{
AVCaptureVideoOrientation orientation = AVCaptureVideoOrientationLandscapeLeft;
[captureConnection setVideoOrientation:orientation];
}
}
UIDeviceOrientation curOr = [[UIDevice currentDevice] orientation];
CGAffineTransform t;
if (curOr == UIDeviceOrientationPortrait)
{
t = CGAffineTransformMakeRotation(-M_PI / 2);
}
else if (curOr == UIDeviceOrientationPortraitUpsideDown)
{
t = CGAffineTransformMakeRotation(M_PI / 2);
}
else if (curOr == UIDeviceOrientationLandscapeRight)
{
t = CGAffineTransformMakeRotation(M_PI);
}
else
{
t = CGAffineTransformMakeRotation(0);
}
}
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error
{
NSLog(#"didFinishRecordingToOutputFileAtURL - enter");
NSLog(#"output file url : %#", [outputFileURL absoluteString]);
BOOL RecordedSuccessfully = YES;
if ([error code] != noErr)
{
// A problem occurred: Find out if the recording was successful.
id value = [[error userInfo] objectForKey:AVErrorRecordingSuccessfullyFinishedKey];
if (value)
{
RecordedSuccessfully = [value boolValue];
}
}
AVCaptureConnection *videoConnection=nil;
for ( AVCaptureConnection *connection in [MovieFileOutput connections] )
{
NSLog(#"%#", connection);
for ( AVCaptureInputPort *port in [connection inputPorts] )
{
NSLog(#"%#", port);
if ( [[port mediaType] isEqual:AVMediaTypeVideo] )
{
videoConnection = connection;
}
}
}
if([videoConnection isVideoOrientationSupported]) // **Here it is, its always false**
{
[videoConnection setVideoOrientation:[[UIDevice currentDevice] orientation]];
} NSLog(#"Setting image quality");
NSData *videoData = [NSData dataWithContentsOfURL:outputFileURL];
[videoData writeToFile:self.outputPath atomically:NO];
[arrOutputUrl addObject:outputFileURL];
if (stopRecording)
{
[self mergeMultipleVideo];
}
}
//Method to merge multiple audios
-(void)mergeMultipleVideo
{
mixComposition = [AVMutableComposition composition];
AVMutableCompositionTrack *compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
CMTime nextClipStartTime = kCMTimeZero;
NSLog(#"Array of output file url : %#", arrOutputUrl);
if (arrOutputUrl.count > 0)
{
for(int i = 0 ;i < [arrOutputUrl count];i++)
{
AVURLAsset* VideoAsset = [[AVURLAsset alloc]initWithURL:[arrOutputUrl objectAtIndex:i] options:nil];
CMTimeRange timeRangeInAsset;
timeRangeInAsset = CMTimeRangeMake(kCMTimeZero, [VideoAsset duration]);
[compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, VideoAsset.duration) ofTrack:[[VideoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:nextClipStartTime error:nil];
nextClipStartTime = CMTimeAdd(nextClipStartTime, timeRangeInAsset.duration);
}
}
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *myPathDocs = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.mov",self.finalRecordedVideoName]];
NSURL *url = [NSURL fileURLWithPath:myPathDocs];
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetHighestQuality];
exportSession.outputURL=url;
exportSession.outputFileType = AVFileTypeQuickTimeMovie;
exportSession.shouldOptimizeForNetworkUse = YES;
[exportSession exportAsynchronouslyWithCompletionHandler:^{
dispatch_async(dispatch_get_main_queue(), ^{
[self exportDidFinish:exportSession path:myPathDocs];
});
}];
}
-(void)exportDidFinish:(AVAssetExportSession*)session path:(NSString*)outputVideoPath
{
NSLog(#"session.status : %d",session.status);
if (session.status == AVAssetExportSessionStatusCompleted)
{
NSURL *outputURL = session.outputURL;
NSData *videoData = [NSData dataWithContentsOfURL:outputURL];
[videoData writeToFile:outputVideoPath atomically:NO];
if ([arrVideoName count] > 0)
{
for (int i = 0; i < [arrVideoName count]; i++)
{
NSArray* documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* fullFilePath = [[documentPaths objectAtIndex:0] stringByAppendingPathComponent: [NSString stringWithFormat:#"%#",[arrVideoName objectAtIndex:i]]];
NSLog(#"Full path of file to be deleted: %#",fullFilePath);
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
if ([fileManager fileExistsAtPath:fullFilePath])
{
[fileManager removeItemAtPath:fullFilePath error:&error];
}
}
[arrVideoName removeAllObjects];
}
if (arrOutputUrl.count > 0)
{
[arrOutputUrl removeAllObjects];
}
[((ActOutAppDelegate *)ActOut_AppDelegate) removeLoadingViewfromView:self.view];
[self.view addSubview:afterRecordingPopupView];
}
}
Look at the AVCaptureConnection's enabled property. For your output connection, set enabled to NO instead of stopping the session.

How to record a video clip in ipad app and store it in documents folder

I have training app i want that when user click recordVideo button camera should launch to record video, is there any way to do this in ipad app.I have done audio recording already i need to do video recording.
//for video..
#import <MobileCoreServices/MobileCoreServices.h>
#import <AVFoundation/AVFoundation.h>
#import <MediaPlayer/Mediaplayer.h>
#import <CoreMedia/CoreMedia.h>
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
NSArray *mediaTypes = [NSArray arrayWithObject:(NSString*)kUTTypeMovie];
picker.mediaTypes = mediaTypes ;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
picker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModeVideo ;
[self presentModalViewController:picker animated:NO];
[picker release];
}
else
{
UIAlertView *alt=[[UIAlertView alloc]initWithTitle:#"Error" message:#" Camera Facility is not available with this Device" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alt show];
[alt release];
}
for saving into Document folder & it also save in photo Library
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths objectAtIndex:0];
//for video
NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
NSLog(#"video url-%#",videoURL);
NSData *videoData = [NSData dataWithContentsOfURL:videoURL];
NSString * videoName = [NSString stringWithFormat:#"student_%d_%d.mp4",stud_id,imgVidID];
videoPath = [documentsDirectory stringByAppendingPathComponent:videoName];
NSLog(#"video path-%#",videoPath);
[videoData writeToFile:videoPath atomically:YES];
NSString *sourcePath = [[info objectForKey:#"UIImagePickerControllerMediaURL"]relativePath];
UISaveVideoAtPathToSavedPhotosAlbum(sourcePath,nil,nil,nil);
}
Try this ::
-(void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info
{
[self dismissViewControllerAnimated:NO completion:nil];
NSString *type = [info objectForKey:UIImagePickerControllerMediaType];
if ([type isEqualToString:(NSString *)kUTTypeVideo] || [type isEqualToString:(NSString *)kUTTypeMovie])
{
videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
NSLog(#"found a video");
// Code To give Name to video and store to DocumentDirectory //
videoData = [[NSData dataWithContentsOfURL:videoURL] retain];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSDateFormatter *dateFormat = [[[NSDateFormatter alloc] init] autorelease];
[dateFormat setDateFormat:#"dd-MM-yyyy||HH:mm:SS"];
NSDate *now = [[[NSDate alloc] init] autorelease];
theDate = [dateFormat stringFromDate:now];
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:#"Default Album"];
if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
[[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:nil];
NSString *videopath= [[[NSString alloc] initWithString:[NSString stringWithFormat:#"%#/%#.mov",documentsDirectory,theDate]] autorelease];
BOOL success = [videoData writeToFile:videopath atomically:NO];
NSLog(#"Successs:::: %#", success ? #"YES" : #"NO");
NSLog(#"video path --> %#",videopath);
}
}
Hopefully, It'll help you.
Thanks.
Just try it :
-(void) imagePickerController: (UIImagePickerController *) picker didFinishPickingMediaWithInfo: (NSDictionary *) info
{
NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType];
[self dismissModalViewControllerAnimated:NO];
NSString *moviePath = [[info objectForKey: UIImagePickerControllerMediaURL] path];
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum (moviePath)){
UISaveVideoAtPathToSavedPhotosAlbum (moviePath,self, #selector(video:didFinishSavingWithError:contextInfo:), nil);
}
}
-(void)video:(NSString*)videoPath didFinishSavingWithError:(NSError*)error contextInfo:(void*)contextInfo {
if (error) {
[AJNotificationView showNoticeInView:self.view type:AJNotificationTypeRed title:#"Video Saving Failed" linedBackground:AJLinedBackgroundTypeAnimated hideAfter:1.0];
}
else{
NSURL *videoURl = [NSURL fileURLWithPath:videoPath];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoURl options:nil];
AVAssetImageGenerator *generate = [[AVAssetImageGenerator alloc] initWithAsset:asset];
generate.appliesPreferredTrackTransform = YES;
NSError *err = NULL;
CMTime time = CMTimeMake(1, 60);
CGImageRef imgRef = [generate copyCGImageAtTime:time actualTime:NULL error:&err];
self.strUploadVideoURL = videoPath;
[imgPhoto setImage:[[[UIImage alloc] initWithCGImage:imgRef] autorelease]];
intWhenPushView = 2;
btnShare.enabled = YES;
btnFacebookShare.enabled = YES;
CGImageRelease(imgRef);
[generate release];
[asset release];
}
}

Some strange error occurs when manipulating events in the calendar of iOS device

I added some events to the calendar and save their eventIdentifier to file. When i want to remove all my events i read the eventIdentifier from that file to an array and remove each event with its event id. Here is the code to add event to calendar and save their event id to file:
- (void) addEventToCalendar: (id)object
{
#autoreleasepool {
int i = 0;
NSString *string_to_file = #"";
eventStore=[[EKEventStore alloc] init];
for(Schedule *sche in scheduleArray){
EKEvent *addEvent=[EKEvent eventWithEventStore:eventStore];
addEvent.title=sche.course_Name;
addEvent.startDate = [self stringToDate:sche.from_Date];
addEvent.endDate = [self stringToDate:sche.thru_Date];
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[addEvent setCalendar:[eventStore defaultCalendarForNewEvents]];
NSDate *date_alarm = [addEvent.startDate dateByAddingTimeInterval:-(10*60)];
addEvent.alarms=[NSArray arrayWithObject:[EKAlarm alarmWithAbsoluteDate:date_alarm]];
NSError *err;
// do save event to calendar
[eventStore saveEvent:addEvent span:EKSpanThisEvent error:&err];
if (err == nil) {
NSString* str = [[NSString alloc] initWithFormat:#"%#", addEvent.eventIdentifier];
string_to_file = [string_to_file stringByAppendingString:str];
string_to_file = [string_to_file stringByAppendingString:#"\n"];
NSLog(#"String %d: %#",i, str);
}
else {
NSLog(#"Error %#",err);
}
i++;
}
// create file to save
[[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];
inFile = [NSFileHandle fileHandleForWritingAtPath: filePath];
NSData *data = [string_to_file dataUsingEncoding:NSUTF16StringEncoding];
[inFile writeData:data];
}
}
And the code below to remove all events i have added to calendar
- (void) deleteEventInCalender {
filemgr = [NSFileManager defaultManager];
NSString *filePath = [self getFilePath:#"saveeventid.txt"];
NSFileHandle *inFile;
inFile = [NSFileHandle fileHandleForReadingAtPath:filePath];
NSData *dataFile;
dataFile = [inFile readDataToEndOfFile];
NSString *tmp = #"";
NSString *temp = #"";
tmp = [NSString stringWithCharacters:[dataFile bytes] length:[dataFile length]/sizeof(unichar)];
if(![tmp isEqualToString:#""]){
tmp = [tmp substringFromIndex:1];
event_idArray = [[NSMutableArray alloc] init];
int j = 0;
while (![tmp isEqualToString:#""]){
int index_find_string = [tmp rangeOfString:#"\n"].location;
temp = [tmp substringWithRange:NSMakeRange(0, index_find_string)];
[event_idArray addObject:temp];
tmp = [tmp substringFromIndex:index_find_string + 1];
}
EKEventStore* store = [[EKEventStore alloc] init];
j = 0;
for(NSString *eventid in event_idArray){
EKEvent* event2 = [store eventWithIdentifier:eventid];
if (event2 != nil) {
NSLog(#"log: %d log id: %#", j, eventid);
NSError* error = nil;
// remove event
[store removeEvent:event2 span:EKSpanThisEvent error:&error];
}
j++;
}
[filemgr removeItemAtPath:filePath error:nil];
}
}
All codes above work well when i test on the iOS simulator with calendar.sqlitedb. But it makes some strange errors when i run on iPad device 5.0. That is sometime the calendar not remove event or when all events has been remove then after some minutes all events appear again... I don't understand, i don't know why and i very confuse. Does anyone has the same issue with me? Please share your solution!
Added another question: where the calendar database stored in the iOS 5.0 device.

UIAlertView kind of contradicts the UIActivityIndicator

I'm downloading the images from the online image for cache when offline. When I open application, The image was downloaded all completely before UIAlertView pop. It's finish incorrectly. I want to make the UIAlertView pop before images download. Here there are my code below.
- (void) operatePopupUpdating {
myAlert = [[UIAlertView alloc] initWithTitle:#"Updating database.." message:nil delegate:self cancelButtonTitle:nil otherButtonTitles: nil];
[myAlert show];
UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
indicator.center = CGPointMake(myAlert.bounds.size.width / 2, myAlert.bounds.size.height - 50);
[indicator startAnimating];
[myAlert addSubview:indicator];
[self operateUpdate];
[self updateImage];
[self operationCompleted];
}
In updateImage, operateUpdate and operationCompleted Method
- (void)updateImage {
NSString *snake_ico_file = #"snake_img_icn_";
NSString *filePath = [self dataFile:[snake_ico_file stringByAppendingString:#"0.jpg"]];
int max_count = [[self readData] count];
if (![[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
for (int i = 0; i < max_count; i++) {
NSString *path = #"http://exitosus.no.de/drngoo/image/";
path = [path stringByAppendingFormat:#"%d",i];
NSString *ico_path = [path stringByAppendingFormat:#"/ico"];
//icon
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filename = [snake_ico_file stringByAppendingFormat:#"%d.jpg"];
NSString *localFilePath = [documentsDirectory stringByAppendingPathComponent:filename];
NSData *thedata = [NSData dataWithContentsOfURL:[NSURL URLWithString:ico_path]];;
[thedata writeToFile:localFilePath atomically:YES];
}
}
-(void) operationCompleted
{
[myAlert dismissWithClickedButtonIndex:0 animated:YES];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Message form System" message:#"Database was updated successful" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
}
- (void)operateUpdate {
NSString *filePath = [self dataFileSettingPath];
int updatedVer = 0;
int version = [self checkDatabase];
if (version == -1) {
updatedVer = [self createDataBase:0];
} else {
updatedVer = [self updateDataBase:version];
}
[self.settingInfo setObject:[NSString stringWithFormat:#"%d",updatedVer] forKey:#"DBVersion"];
[self.settingInfo writeToFile:filePath atomically:YES];
}
How I fix them and work correctly?
The alertView will show only after your image downloading complete. One Solution to solve this is,
Create another class ImageDownLoad.h
in .h
#property(nonatomic,assign)id delegate;
#property(nonatomic,retain) NSString *path;
in .m
#synthesize delegate;
#synthesize path;
Create a method namely,
-(void)startDownloadImageWithUrl:(NSURL*)imageUrl withLocalFilePath:(NSSTring*)filePath{
path = filePath;
receiveData = [NSMutableData data];
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:imageUrl];
NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[receiveData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
[(id)delegate performSelector:#selector(SaveData:inFilePath:) withObject:receiveData withObject:path];
}
This will create connection and start download your image in a separate class. Then in your mai ViewController add bit of code like below.
- (void)updateImage {
NSString *snake_ico_file = #"snake_img_icn_";
NSString *filePath = [self dataFile:[snake_ico_file stringByAppendingString:#"0.jpg"]];
int max_count = [[self readData] count];
if (![[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
for (int i = 0; i < max_count; i++) {
NSString *path = #"http://exitosus.no.de/drngoo/image/";
path = [path stringByAppendingFormat:#"%d",i];
NSString *ico_path = [path stringByAppendingFormat:#"/ico"];
//icon
NSArray *paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filename = [snake_ico_file stringByAppendingFormat:#"%d.jpg"];
NSString *localFilePath = [documentsDirectory stringByAppendingPathComponent:filename];
ImageDownLoad *imageDown = [[ImageDownLoad alloc]init];
imageDown.delegate = self;
[imageDown startDownloadImageWithUrl:[NSURL URLWithString:ico_path] withLocalFilePath:localFilePath];
}
}
This method will be called each time when image download completes.
-(void)SaveData:(NSData*)data inFilePath:(NSString*)filePath{
[data writeToFile:filePath atomically:YES];
}
Your UI wont delay by doing so :)

Trying to save images in ipad app bundle from photo library

-(IBAction)saveImage{
NSMutableArray *dictWords= [[NSMutableArray alloc]initWithObjects:#"TIGER",#"CAT", #"ROSE", #"ELEPHANT",#"MOUSE IS LOOKING FOR THE CHEESE",#"KITE",#"CAR",#"AEROPLANE",#"MANGO",#"FRUITS ARE FALLING FROM THE TREE",#"MOUNTAIN",#"BIRDS ARE FLYING",#"IGLOO",#"THIS HOUSE IS BUILT OF WOODS",#"BANANA",#"RAINBOW",#"TRAIN",#"DADDY DRINKS JUICE",#"UMBRELLA",#"GOAT",#"CAT JUMPS HIGH",#"DOG RUNS FAST",#"BUS",#"GIRL IS CRYING",#"STARS",#"DOLPHIN",#"BOYS ARE PLAYING FOOTBALL",#"GLASS IS FULL OF WATER",#"SHIP",#"SNOWFALL",#"GHOST",#"RABBIT",#"WATERMELON",#"SPIDERMAN",#"DINOSAUR",#"MICKEY MOUSE",#"MONKEY IS SITTING ON A TREE",#"PEACOCK",#"LIGHTNING",#"HEN LAYS EGGS",nil];
NSString *path=[[NSBundle mainBundle] pathForResource:[youSaid text] ofType:#"png" inDirectory:#"Image"];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
for (int i=0 ; i<[assets count]; i++) {
if (i<[dictWords count]) {
[dict setObject:[[[assets objectAtIndex:i] defaultRepresentation] url] forKey:[NSString stringWithFormat:#"%#",[dictWords objectAtIndex:i]]];
NSLog(#"diccount:%d",[dict count]);
}
}
NSURL *imageurl = [dict objectForKey:[youSaid text]];
//NSLog(#"text:%#",[youSaid text]);
//Getting asset from url
typedef void (^ALAssetsLibraryAssetForURLResultBlock)(ALAsset *asset);
typedef void (^ALAssetsLibraryAccessFailureBlock)(NSError *error);
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
{
ALAssetRepresentation *rep = [myasset defaultRepresentation];
CGImageRef iref = [rep fullResolutionImage];
//Setting asset image to image view according to the image url
[imageview setImage:[UIImage imageWithCGImage:iref]];
youSaid.text = [NSString stringWithFormat:#"%#",imageurl];
};
ALAssetsLibraryAccessFailureBlock failureblock = ^(NSError *myerror)
{
NSLog(#"Error, cant get image - %#",[myerror localizedDescription]);
};
ALAssetsLibrary *assetLibrary=[[ALAssetsLibrary alloc] init];
[assetLibrary assetForURL:imageurl resultBlock:resultblock failureBlock:failureblock];
UIImage *image=[[UIImage alloc]initWithContentsOfFile:path];
NSData *imageData = UIImagePNGRepresentation(image); //convert image into .png format.
NSFileManager *fileManager = [NSFileManager defaultManager];//create instance of NSFileManager
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); //create an array and store result of our search for the documents directory in it
NSString *documentsDirectory = [paths objectAtIndex:0]; //create NSString object, that holds our exact path to the documents directory
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.png", youSaid.text]]; //add our image to the path
[fileManager createFileAtPath:fullPath contents:imageData attributes:nil]; //finally save the image
NSLog(#"image saved");
}
#end
This is the following code i wrote but i am not able to save images.i am only able to sane an image known as NULL.png .please suggest the changes to save all the pics in my library to bundle.
Thanks,
Christy
Sample Code
- (void) openPhotoLibrary {
NSLog(#"openPhotolibrary");
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
if (self.picker != nil) {
NSLog(#"releasing self.picker...");
[self.picker release];
}
self.picker = [[UIImagePickerController alloc] init];
self.picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
//self.picker.allowsImageEditing = YES;
[self.picker presentModalViewController:self.picker animated:YES];
self.picker.delegate = self;
[[[CCDirector sharedDirector] openGLView] addSubview:self.picker.view];
}
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)currentPicker {
NSLog(#"imagePickerControllerDidCancel");
// hide the self.picker if user cancels picking an image.
[currentPicker dismissModalViewControllerAnimated:YES];
self.picker.view.hidden = YES;
[self.picker.view removeFromSuperview];
}
- (void)imagePickerController:(UIImagePickerController *)currentPicker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo
{
[self saveImage:image withImageName:#"myPhoto"];
}
//saving an image
- (void)saveImage:(UIImage*)image withImageName:(NSString*)imageName {
NSData *imageData = UIImagePNGRepresentation(image); //convert image into .png format.
NSFileManager *fileManager = [NSFileManager defaultManager];//create instance of NSFileManager
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); //create an array and store result of our search for the documents directory in it
NSString *documentsDirectory = [paths objectAtIndex:0]; //create NSString object, that holds our exact path to the documents directory
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.png", imageName]]; //add our image to the path
[fileManager createFileAtPath:fullPath contents:imageData attributes:nil]; //finally save the path (image)
NSLog(#"image saved");
}
This code its working for me try it may be its helps you
-(IBAction)PhotoLibraryButtonClicked:(id)sender{
if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]){
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:imagePicker animated:YES];
}
else{
[self displaysorceError];
}
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
//[self.popoverrcontroller dismissPopoverAnimated:true];
//[popoverrcontroller release];
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
[self dismissModalViewControllerAnimated:YES];
if([mediaType isEqualToString:(NSString *)kUTTypeImage]){
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
// UIImage *rote = [image rotateInDegrees:219.0f];
img.image = image;
if(newMedia)
UIImageWriteToSavedPhotosAlbum(image, nil,nil, nil);
}else if([mediaType isEqualToString:(NSString *)kUTTypeImage]){
//not available vidio
}
}
-(IBAction)saveImageIn:(id)sender{
NSData *imageData = UIImagePNGRepresentation(img.image);
NSFileManager *fileMan = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fullPathToFile = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#" %d.png",img.image]];
[fileMan createFileAtPath:fullPathToFile contents:imageData attributes:nil];
UIAlertView *alt = [[UIAlertView alloc]
initWithTitle:#"Thank You"
message:#"Image Save In Directory"
delegate:nil cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alt show];
[alt release];
}
thank you..:)Neet