You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by sh...@apache.org on 2012/04/21 03:12:06 UTC
ios commit: Fixed CB-391 - camera.getPicture crash
Updated Branches:
refs/heads/master 3794f4db6 -> 499cf514f
Fixed CB-391 - camera.getPicture crash
Project: http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/commit/499cf514
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/tree/499cf514
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/diff/499cf514
Branch: refs/heads/master
Commit: 499cf514fd29cd33f22baa796ace8eb8e725b8b6
Parents: 3794f4d
Author: Shazron Abdullah <sh...@apache.org>
Authored: Fri Apr 20 18:11:59 2012 -0700
Committer: Shazron Abdullah <sh...@apache.org>
Committed: Fri Apr 20 18:11:59 2012 -0700
----------------------------------------------------------------------
CordovaLib/Classes/CDVCamera.h | 5 +-
CordovaLib/Classes/CDVCamera.m | 398 +++++++++++++++------------
CordovaLib/Classes/CDVPlugin.h | 2 +
CordovaLib/Classes/CDVPlugin.m | 8 +-
CordovaLib/Classes/CDVViewController.m | 28 ++-
5 files changed, 256 insertions(+), 185 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/499cf514/CordovaLib/Classes/CDVCamera.h
----------------------------------------------------------------------
diff --git a/CordovaLib/Classes/CDVCamera.h b/CordovaLib/Classes/CDVCamera.h
index 6d7661d..9a066ab 100644
--- a/CordovaLib/Classes/CDVCamera.h
+++ b/CordovaLib/Classes/CDVCamera.h
@@ -54,6 +54,8 @@ typedef NSUInteger CDVMediaType;
@property (assign) bool correctOrientation;
@property (assign) bool saveToPhotoAlbum;
@property (assign) bool cropToSize;
+@property (retain) UIWebView* webView;
+@property (assign) BOOL popoverSupported;
- (void) dealloc;
@@ -65,7 +67,6 @@ typedef NSUInteger CDVMediaType;
UINavigationControllerDelegate,
UIPopoverControllerDelegate>
{
- CDVCameraPicker* pickerController;
}
@property (retain) CDVCameraPicker* pickerController;
@@ -89,6 +90,8 @@ typedef NSUInteger CDVMediaType;
- (UIImage*)imageByScalingAndCroppingForSize:(UIImage*)anImage toSize:(CGSize)targetSize;
- (UIImage*)imageByScalingNotCroppingForSize:(UIImage*)anImage toSize:(CGSize)frameSize;
- (UIImage*)imageCorrectedForCaptureOrientation:(UIImage*)anImage;
+
+- (void) closePicker:(CDVCameraPicker*)picker;
- (void) dealloc;
@end
http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/499cf514/CordovaLib/Classes/CDVCamera.m
----------------------------------------------------------------------
diff --git a/CordovaLib/Classes/CDVCamera.m b/CordovaLib/Classes/CDVCamera.m
index 3102193..5dc077d 100644
--- a/CordovaLib/Classes/CDVCamera.m
+++ b/CordovaLib/Classes/CDVCamera.m
@@ -22,15 +22,23 @@
#import "NSDictionary+Extensions.h"
#import <MobileCoreServices/UTCoreTypes.h>
+
+@interface CDVCamera ()
+
+@property (readwrite, assign) BOOL hasPendingOperation;
+
+@end
+
@implementation CDVCamera
-@synthesize pickerController;
+@synthesize hasPendingOperation, pickerController;
--(BOOL)popoverSupported
+- (BOOL) popoverSupported
{
return ( NSClassFromString(@"UIPopoverController") != nil) &&
(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
}
+
/* takePicture arguments:
* INDEX ARGUMENT
* 0 callbackId
@@ -48,7 +56,8 @@
- (void) takePicture:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
{
NSString* callbackId = [arguments objectAtIndex:0];
-
+ self.hasPendingOperation = NO;
+
NSString* sourceTypeString = [arguments objectAtIndex:3];
UIImagePickerControllerSourceType sourceType = UIImagePickerControllerSourceTypeCamera; // default
if (sourceTypeString != nil)
@@ -61,218 +70,247 @@
NSLog(@"Camera.getPicture: source type %d not available.", sourceType);
CDVPluginResult* result = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsString: @"no camera available"];
[self writeJavascript:[result toErrorCallbackString:callbackId]];
+ return;
- } else {
- bool allowEdit = [[arguments objectAtIndex:8] boolValue];
- NSNumber* targetWidth = [arguments objectAtIndex:4];
- NSNumber* targetHeight = [arguments objectAtIndex:5];
- NSNumber* mediaValue = [arguments objectAtIndex:7];
- CDVMediaType mediaType = (mediaValue) ? [mediaValue intValue] : MediaTypePicture;
-
- CGSize targetSize = CGSizeMake(0, 0);
- if (targetWidth != nil && targetHeight != nil) {
- targetSize = CGSizeMake([targetWidth floatValue], [targetHeight floatValue]);
- }
-
-
- if (self.pickerController == nil)
- {
- self.pickerController = [[[CDVCameraPicker alloc] init] autorelease];
- }
-
- self.pickerController.delegate = self;
- self.pickerController.sourceType = sourceType;
- self.pickerController.allowsEditing = allowEdit; // THIS IS ALL IT TAKES FOR CROPPING - jm
- self.pickerController.callbackId = callbackId;
- self.pickerController.targetSize = targetSize;
- self.pickerController.cropToSize = NO;
-
- self.pickerController.correctOrientation = [[arguments objectAtIndex:9] boolValue];
- self.pickerController.saveToPhotoAlbum = [[arguments objectAtIndex:10] boolValue];
-
- self.pickerController.encodingType = ([arguments objectAtIndex:6]) ? [[arguments objectAtIndex:6] intValue] : EncodingTypeJPEG;
+ }
+
+ bool allowEdit = [[arguments objectAtIndex:8] boolValue];
+ NSNumber* targetWidth = [arguments objectAtIndex:4];
+ NSNumber* targetHeight = [arguments objectAtIndex:5];
+ NSNumber* mediaValue = [arguments objectAtIndex:7];
+ CDVMediaType mediaType = (mediaValue) ? [mediaValue intValue] : MediaTypePicture;
+
+ CGSize targetSize = CGSizeMake(0, 0);
+ if (targetWidth != nil && targetHeight != nil) {
+ targetSize = CGSizeMake([targetWidth floatValue], [targetHeight floatValue]);
+ }
+
+ CDVCameraPicker* cameraPicker = [[CDVCameraPicker alloc] init];
+ self.pickerController = cameraPicker;
+
+ cameraPicker.delegate = self;
+ cameraPicker.sourceType = sourceType;
+ cameraPicker.allowsEditing = allowEdit; // THIS IS ALL IT TAKES FOR CROPPING - jm
+ cameraPicker.callbackId = callbackId;
+ cameraPicker.targetSize = targetSize;
+ cameraPicker.cropToSize = NO;
+ // we need to capture this state for memory warnings that dealloc this object
+ cameraPicker.webView = self.webView;
+ cameraPicker.popoverSupported = [self popoverSupported];
+
+ cameraPicker.correctOrientation = [[arguments objectAtIndex:9] boolValue];
+ cameraPicker.saveToPhotoAlbum = [[arguments objectAtIndex:10] boolValue];
+
+ cameraPicker.encodingType = ([arguments objectAtIndex:6]) ? [[arguments objectAtIndex:6] intValue] : EncodingTypeJPEG;
+
+ cameraPicker.quality = ([arguments objectAtIndex:1]) ? [[arguments objectAtIndex:1] intValue] : 50;
+ cameraPicker.returnType = ([arguments objectAtIndex:2]) ? [[arguments objectAtIndex:2] intValue] : DestinationTypeFileUri;
+
+ if (sourceType == UIImagePickerControllerSourceTypeCamera) {
+ // we only allow taking pictures (no video) in this api
+ cameraPicker.mediaTypes = [NSArray arrayWithObjects: (NSString*) kUTTypeImage, nil];
+ } else if (mediaType == MediaTypeAll) {
+ cameraPicker.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType: sourceType];
+ } else {
+ NSArray* mediaArray = [NSArray arrayWithObjects: (NSString*) (mediaType == MediaTypeVideo ? kUTTypeMovie : kUTTypeImage), nil];
+ cameraPicker.mediaTypes = mediaArray;
+ }
+
+ if ([self popoverSupported] && sourceType != UIImagePickerControllerSourceTypeCamera)
+ {
+ if (cameraPicker.popoverController == nil)
+ {
+ cameraPicker.popoverController = [[[NSClassFromString(@"UIPopoverController") alloc]
+ initWithContentViewController:cameraPicker] autorelease];
+ }
+ cameraPicker.popoverController.delegate = self;
+ [cameraPicker.popoverController presentPopoverFromRect:CGRectMake(0,32,320,480)
+ inView:[self.webView superview]
+ permittedArrowDirections:UIPopoverArrowDirectionAny
+ animated:YES];
+ }
+ else
+ {
+ self.hasPendingOperation = YES;
- self.pickerController.quality = ([arguments objectAtIndex:1]) ? [[arguments objectAtIndex:1] intValue] : 50;
- self.pickerController.returnType = ([arguments objectAtIndex:2]) ? [[arguments objectAtIndex:2] intValue] : DestinationTypeFileUri;
-
- if (sourceType == UIImagePickerControllerSourceTypeCamera) {
- // we only allow taking pictures (no video) in this api
- self.pickerController.mediaTypes = [NSArray arrayWithObjects: (NSString*) kUTTypeImage, nil];
- } else if (mediaType == MediaTypeAll) {
- self.pickerController.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType: sourceType];
+ if ([self.viewController respondsToSelector:@selector(presentViewController:::)]) {
+ [self.viewController presentViewController:cameraPicker animated:YES completion:nil];
} else {
- NSArray* mediaArray = [NSArray arrayWithObjects: (NSString*) (mediaType == MediaTypeVideo ? kUTTypeMovie : kUTTypeImage), nil];
- self.pickerController.mediaTypes = mediaArray;
-
- }
-
- if([self popoverSupported] && sourceType != UIImagePickerControllerSourceTypeCamera)
- {
- if (self.pickerController.popoverController == nil)
- {
- self.pickerController.popoverController = [[[NSClassFromString(@"UIPopoverController") alloc]
- initWithContentViewController:self.pickerController] autorelease];
- }
- self.pickerController.popoverController.delegate = self;
- [ self.pickerController.popoverController presentPopoverFromRect:CGRectMake(0,32,320,480)
- inView:[self.webView superview]
- permittedArrowDirections:UIPopoverArrowDirectionAny
- animated:YES];
- }
- else
- {
- if ([self.viewController respondsToSelector:@selector(presentViewController:::)]) {
- [self.viewController presentViewController:self.pickerController animated:YES completion:nil];
- } else {
- [self.viewController presentModalViewController:self.pickerController animated:YES ];
- }
- }
+ [self.viewController presentModalViewController:cameraPicker animated:YES ];
+ }
}
+
+ [cameraPicker release];
}
-- (void)popoverControllerDidDismissPopover:(id)popoverController
+- (void) popoverControllerDidDismissPopover:(id)popoverController
{
- [ self imagePickerControllerDidCancel:self.pickerController ];
+ //[ self imagePickerControllerDidCancel:self.pickerController ]; '
+ UIPopoverController* pc = (UIPopoverController*)popoverController;
+ [pc dismissPopoverAnimated:YES];
+ pc.delegate = nil;
}
- (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info
{
+ CDVCameraPicker* cameraPicker = (CDVCameraPicker*)picker;
- NSString* callbackId = self.pickerController.callbackId;
+ NSString* callbackId = cameraPicker.callbackId;
- if([self popoverSupported] && self.pickerController.popoverController != nil)
+ if(cameraPicker.popoverSupported && cameraPicker.popoverController != nil)
{
- [self.pickerController.popoverController dismissPopoverAnimated:YES];
- self.pickerController.popoverController.delegate = nil;
- self.pickerController.popoverController = nil;
+ [cameraPicker.popoverController dismissPopoverAnimated:YES];
+ cameraPicker.popoverController.delegate = nil;
+ cameraPicker.popoverController = nil;
}
else
{
- if ([self.pickerController respondsToSelector:@selector(presentingViewController)]) {
- [[self.pickerController presentingViewController] dismissModalViewControllerAnimated:YES];
+ if ([cameraPicker respondsToSelector:@selector(presentingViewController)]) {
+ [[cameraPicker presentingViewController] dismissModalViewControllerAnimated:YES];
} else {
- [[self.pickerController parentViewController] dismissModalViewControllerAnimated:YES];
+ [[cameraPicker parentViewController] dismissModalViewControllerAnimated:YES];
}
}
+
NSString* jsString = nil;
CDVPluginResult* result = nil;
NSString* mediaType = [info objectForKey:UIImagePickerControllerMediaType];
+ // IMAGE TYPE
if ([mediaType isEqualToString:(NSString*)kUTTypeImage])
{
-
-
-
// get the image
UIImage* image = nil;
- if (self.pickerController.allowsEditing && [info objectForKey:UIImagePickerControllerEditedImage]){
+ if (cameraPicker.allowsEditing && [info objectForKey:UIImagePickerControllerEditedImage]){
image = [info objectForKey:UIImagePickerControllerEditedImage];
- }else {
+ } else {
image = [info objectForKey:UIImagePickerControllerOriginalImage];
}
- if (self.pickerController.saveToPhotoAlbum) {
- UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
- }
-
- if (self.pickerController.correctOrientation) {
- image = [self imageCorrectedForCaptureOrientation:image];
- }
-
- UIImage *scaledImage = nil;
+
+ if (cameraPicker.saveToPhotoAlbum) {
+ UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
+ }
+
+ if (cameraPicker.correctOrientation) {
+ image = [self imageCorrectedForCaptureOrientation:image];
+ }
- if (self.pickerController.targetSize.width > 0 && self.pickerController.targetSize.height > 0) {
- // if cropToSize, resize image and crop to target size, otherwise resize to fit target without cropping
- if(self.pickerController.cropToSize) {
- scaledImage = [self imageByScalingAndCroppingForSize:image toSize:self.pickerController.targetSize];
- } else {
- scaledImage = [self imageByScalingNotCroppingForSize:image toSize:self.pickerController.targetSize];
+ UIImage *scaledImage = nil;
+
+ if (cameraPicker.targetSize.width > 0 && cameraPicker.targetSize.height > 0) {
+ // if cropToSize, resize image and crop to target size, otherwise resize to fit target without cropping
+ if(cameraPicker.cropToSize) {
+ scaledImage = [self imageByScalingAndCroppingForSize:image toSize:cameraPicker.targetSize];
+ } else {
+ scaledImage = [self imageByScalingNotCroppingForSize:image toSize:cameraPicker.targetSize];
+ }
}
- }
- NSData* data = nil;
- if (self.pickerController.encodingType == EncodingTypePNG) {
+
+ NSData* data = nil;
+
+ if (cameraPicker.encodingType == EncodingTypePNG) {
data = UIImagePNGRepresentation(scaledImage == nil ? image : scaledImage);
}
else {
- data = UIImageJPEGRepresentation(scaledImage == nil ? image : scaledImage, self.pickerController.quality / 100.0f);
- }
- if (self.pickerController.returnType == DestinationTypeFileUri){
-
- // write to temp directory and reutrn URI
- // get the temp directory path
- NSString* docsPath = [NSTemporaryDirectory() stringByStandardizingPath];
- NSError* err = nil;
- NSFileManager* fileMgr = [[NSFileManager alloc] init]; //recommended by apple (vs [NSFileManager defaultManager]) to be theadsafe
-
- // generate unique file name
- NSString* filePath;
- int i=1;
- do {
- filePath = [NSString stringWithFormat:@"%@/photo_%03d.%@", docsPath, i++, self.pickerController.encodingType == EncodingTypePNG ? @"png" : @"jpg"];
- } while([fileMgr fileExistsAtPath: filePath]);
- // save file
- if (![data writeToFile: filePath options: NSAtomicWrite error: &err]){
- result = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsString: [err localizedDescription]];
- jsString = [result toErrorCallbackString:callbackId];
- }else{
- result = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsString: [[NSURL fileURLWithPath: filePath] absoluteString]];
- jsString = [result toSuccessCallbackString:callbackId];
- }
- [fileMgr release];
-
- }else{
- result = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsString: [data base64EncodedString]];
- jsString = [result toSuccessCallbackString:callbackId];
- }
-
-
- } else {
- // was movie type
+ data = UIImageJPEGRepresentation(scaledImage == nil ? image : scaledImage, cameraPicker.quality / 100.0f);
+ }
+
+ if (cameraPicker.returnType == DestinationTypeFileUri) {
+
+ // write to temp directory and reutrn URI
+ // get the temp directory path
+ NSString* docsPath = [NSTemporaryDirectory() stringByStandardizingPath];
+ NSError* err = nil;
+ NSFileManager* fileMgr = [[NSFileManager alloc] init]; //recommended by apple (vs [NSFileManager defaultManager]) to be theadsafe
+
+ // generate unique file name
+ NSString* filePath;
+
+ int i = 1;
+ do
+ {
+ filePath = [NSString stringWithFormat:@"%@/photo_%03d.%@", docsPath, i++, cameraPicker.encodingType == EncodingTypePNG ? @"png" : @"jpg"];
+ }
+ while ([fileMgr fileExistsAtPath: filePath]);
+
+ // save file
+ if (![data writeToFile: filePath options: NSAtomicWrite error: &err]) {
+ result = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsString: [err localizedDescription]];
+ jsString = [result toErrorCallbackString:callbackId];
+ } else {
+ result = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsString: [[NSURL fileURLWithPath: filePath] absoluteString]];
+ jsString = [result toSuccessCallbackString:callbackId];
+ }
+ [fileMgr release];
+
+ } else {
+ result = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsString: [data base64EncodedString]];
+ jsString = [result toSuccessCallbackString:callbackId];
+ }
+ }
+ // NOT IMAGE TYPE (MOVIE)
+ else
+ {
NSString *moviePath = [[info objectForKey: UIImagePickerControllerMediaURL] absoluteString];
result = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsString: moviePath];
jsString = [result toSuccessCallbackString:callbackId];
-
}
+
+
if (jsString) {
[self.webView stringByEvaluatingJavaScriptFromString:jsString];
}
-
- self.pickerController.delegate = nil;
- self.pickerController = nil;
+
+ self.hasPendingOperation = NO;
}
// older api calls newer didFinishPickingMediaWithInfo
-- (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingImage:(UIImage*)image editingInfo:(NSDictionary*)editingInfo
+- (void) imagePickerController:(UIImagePickerController*)picker didFinishPickingImage:(UIImage*)image editingInfo:(NSDictionary*)editingInfo
{
NSDictionary* imageInfo = [NSDictionary dictionaryWithObject:image forKey:UIImagePickerControllerOriginalImage];
[self imagePickerController:picker didFinishPickingMediaWithInfo: imageInfo];
}
-- (void)imagePickerControllerDidCancel:(UIImagePickerController*)picker
-{
- NSString* callbackId = self.pickerController.callbackId;
-
- if ([picker respondsToSelector:@selector(presentingViewController)]) {
- [[picker presentingViewController] dismissModalViewControllerAnimated:YES];
+- (void) closePicker:(CDVCameraPicker*)cameraPicker
+{
+ if ([cameraPicker respondsToSelector:@selector(presentingViewController)]) {
+ [[cameraPicker presentingViewController] dismissModalViewControllerAnimated:YES];
} else {
- [[picker parentViewController] dismissModalViewControllerAnimated:YES];
+ [[cameraPicker parentViewController] dismissModalViewControllerAnimated:YES];
}
-
- CDVPluginResult* result = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsString: @"no image selected"]; // error callback expects string ATM
+
+ if (cameraPicker.popoverSupported && cameraPicker.popoverController != nil)
+ {
+ cameraPicker.popoverController.delegate = nil;
+ cameraPicker.popoverController = nil;
+ }
+}
- [self.webView stringByEvaluatingJavaScriptFromString:[result toErrorCallbackString: callbackId]];
-
- if([self popoverSupported] && self.pickerController.popoverController != nil)
- {
- self.pickerController.popoverController.delegate = nil;
- self.pickerController.popoverController = nil;
- }
-
- self.pickerController.delegate = nil;
- self.pickerController = nil;
-
+- (void) imagePickerControllerDidCancel:(UIImagePickerController*)picker
+{
+ CDVCameraPicker* cameraPicker = (CDVCameraPicker*)picker;
+ NSString* callbackId = cameraPicker.callbackId;
+
+ if ([cameraPicker respondsToSelector:@selector(presentingViewController)]) {
+ [[cameraPicker presentingViewController] dismissModalViewControllerAnimated:YES];
+ } else {
+ [[cameraPicker parentViewController] dismissModalViewControllerAnimated:YES];
+ }
+
+ if (cameraPicker.popoverSupported && cameraPicker.popoverController != nil)
+ {
+ cameraPicker.popoverController.delegate = nil;
+ cameraPicker.popoverController = nil;
+ }
+
+ CDVPluginResult* result = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsString: @"no image selected"]; // error callback expects string ATM
+ [cameraPicker.webView stringByEvaluatingJavaScriptFromString:[result toErrorCallbackString: callbackId]];
+
+ self.hasPendingOperation = NO;
}
-- (UIImage*)imageByScalingAndCroppingForSize:(UIImage*)anImage toSize:(CGSize)targetSize
+
+- (UIImage*) imageByScalingAndCroppingForSize:(UIImage*)anImage toSize:(CGSize)targetSize
{
UIImage *sourceImage = anImage;
UIImage *newImage = nil;
@@ -303,11 +341,10 @@
{
thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
}
- else
- if (widthFactor < heightFactor)
- {
- thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
- }
+ else if (widthFactor < heightFactor)
+ {
+ thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
+ }
}
UIGraphicsBeginImageContext(targetSize); // this will crop
@@ -320,18 +357,20 @@
[sourceImage drawInRect:thumbnailRect];
newImage = UIGraphicsGetImageFromCurrentImageContext();
- if(newImage == nil)
+ if(newImage == nil) {
NSLog(@"could not scale image");
+ }
//pop the context to get back to the default
UIGraphicsEndImageContext();
return newImage;
}
-- (UIImage*)imageCorrectedForCaptureOrientation:(UIImage*)anImage
+- (UIImage*) imageCorrectedForCaptureOrientation:(UIImage*)anImage
{
float rotation_radians = 0;
bool perpendicular = false;
+
switch ([anImage imageOrientation]) {
case UIImageOrientationUp:
rotation_radians = 0.0;
@@ -373,7 +412,7 @@
return newImage;
}
-- (UIImage*)imageByScalingNotCroppingForSize:(UIImage*)anImage toSize:(CGSize)frameSize
+- (UIImage*) imageByScalingNotCroppingForSize:(UIImage*)anImage toSize:(CGSize)frameSize
{
UIImage *sourceImage = anImage;
UIImage *newImage = nil;
@@ -391,10 +430,11 @@
CGFloat heightFactor = targetHeight / height;
// opposite comparison to imageByScalingAndCroppingForSize in order to contain the image within the given bounds
- if (widthFactor > heightFactor)
+ if (widthFactor > heightFactor) {
scaleFactor = heightFactor; // scale to fit height
- else
+ } else {
scaleFactor = widthFactor; // scale to fit width
+ }
scaledSize = CGSizeMake(width * scaleFactor, height * scaleFactor);
}
@@ -403,8 +443,9 @@
[sourceImage drawInRect:CGRectMake(0, 0, scaledSize.width, scaledSize.height)];
newImage = UIGraphicsGetImageFromCurrentImageContext();
- if(newImage == nil)
+ if(newImage == nil) {
NSLog(@"could not scale image");
+ }
//pop the context to get back to the default
UIGraphicsEndImageContext();
@@ -413,6 +454,8 @@
- (void) postImage:(UIImage*)anImage withFilename:(NSString*)filename toUrl:(NSURL*)url
{
+ self.hasPendingOperation = YES;
+
NSString *boundary = @"----BOUNDARY_IS_I";
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
@@ -446,16 +489,13 @@
// NSData* result = [NSURLConnection sendSynchronousRequest:req returningResponse:&response error:&error];
// NSString * resultStr = [[[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding] autorelease];
+
+ self.hasPendingOperation = NO;
}
- (void) dealloc
{
- if (self.pickerController)
- {
- self.pickerController.delegate = nil;
- }
- self.pickerController = nil;
[super dealloc];
}
@@ -473,15 +513,11 @@
@synthesize saveToPhotoAlbum;
@synthesize encodingType;
@synthesize cropToSize;
-
+@synthesize webView;
+@synthesize popoverSupported;
- (void) dealloc
{
- if (callbackId) {
- [callbackId release];
- }
-
-
[super dealloc];
}
http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/499cf514/CordovaLib/Classes/CDVPlugin.h
----------------------------------------------------------------------
diff --git a/CordovaLib/Classes/CDVPlugin.h b/CordovaLib/Classes/CDVPlugin.h
index b2b03cf..658cfbd 100644
--- a/CordovaLib/Classes/CDVPlugin.h
+++ b/CordovaLib/Classes/CDVPlugin.h
@@ -37,6 +37,8 @@ callerFileName:__FILE__ callerFunctionName:__PRETTY_FUNCTION__]) { return; }
@property (nonatomic, retain) UIViewController* viewController;
@property (nonatomic, retain) id<CDVCommandDelegate> commandDelegate;
+@property (readonly, assign) BOOL hasPendingOperation;
+
- (CDVPlugin*) initWithWebView:(UIWebView*)theWebView settings:(NSDictionary*)classSettings;
- (CDVPlugin*) initWithWebView:(UIWebView*)theWebView;
http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/499cf514/CordovaLib/Classes/CDVPlugin.m
----------------------------------------------------------------------
diff --git a/CordovaLib/Classes/CDVPlugin.m b/CordovaLib/Classes/CDVPlugin.m
index cdb4821..2ebf4ef 100644
--- a/CordovaLib/Classes/CDVPlugin.m
+++ b/CordovaLib/Classes/CDVPlugin.m
@@ -20,9 +20,14 @@
#import "CDVPlugin.h"
+@interface CDVPlugin ()
+
+@property (readwrite, assign) BOOL hasPendingOperation;
+
+@end
@implementation CDVPlugin
-@synthesize webView, settings, viewController, commandDelegate;
+@synthesize webView, settings, viewController, commandDelegate, hasPendingOperation;
- (CDVPlugin*) initWithWebView:(UIWebView*)theWebView settings:(NSDictionary*)classSettings
@@ -30,6 +35,7 @@
self = [self initWithWebView:theWebView];
if (self) {
self.settings = classSettings;
+ self.hasPendingOperation = NO;
}
return self;
}
http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/499cf514/CordovaLib/Classes/CDVViewController.m
----------------------------------------------------------------------
diff --git a/CordovaLib/Classes/CDVViewController.m b/CordovaLib/Classes/CDVViewController.m
index d9d00c9..24c8d93 100644
--- a/CordovaLib/Classes/CDVViewController.m
+++ b/CordovaLib/Classes/CDVViewController.m
@@ -336,8 +336,29 @@
}
- (void) didReceiveMemoryWarning {
- // Releases the view if it doesn't have a superview.
- [super didReceiveMemoryWarning];
+
+ // iterate through all the plugin objects, and call hasPendingOperation
+ // if at least one has a pending operation, we don't call [super didReceiveMemoryWarning]
+
+ NSEnumerator* enumerator = [self.pluginObjects objectEnumerator];
+ CDVPlugin* plugin;
+
+ BOOL doPurge = YES;
+ while ((plugin = [enumerator nextObject]))
+ {
+ if (plugin.hasPendingOperation) {
+ NSLog(@"Plugin '%@' has a pending operation, memory purge is delayed for didReceiveMemoryWarning.", NSStringFromClass([plugin class]));
+ doPurge = NO;
+ }
+ }
+
+ if (doPurge) {
+ // Releases the view if it doesn't have a superview.
+ [super didReceiveMemoryWarning];
+ } else {
+ // try again in 10 seconds
+ [self performSelector:@selector(didReceiveMemoryWarning) withObject:nil afterDelay:10];
+ }
// Release any cached data, images, etc. that aren't in use.
}
@@ -346,6 +367,9 @@
- (void) viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
+
+ self.webView.delegate = nil;
+ self.webView = nil;
}