Skip to content

Commit 050b1c0

Browse files
committed
Add comprehensive error handling and logging to iOS screenshot API
Reverted to dispatch_async to avoid blocking the EDT, but added extensive error handling and logging to diagnose the NullPointerException. Changes to IOSNative.m: - Reverted dispatch_sync back to dispatch_async (don't block EDT) - Added @try/@catch block to catch Objective-C exceptions - Added null checks for view, image, PNG data, and byte array - Added NSLog statements at each step to trace execution - All error paths now call onScreenshot with nil to complete the callback Changes to IOSImplementation.java: - Added try/catch around screenshot() call with logging - Added try/catch in onScreenshot() with null checks - Added logging when imageData is null - Ensured callback is always invoked (with null on error) This will provide detailed stack traces and logs to identify the exact location of the NullPointerException.
1 parent a0be15b commit 050b1c0

File tree

2 files changed

+71
-25
lines changed

2 files changed

+71
-25
lines changed

Ports/iOSPort/nativeSources/IOSNative.m

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5212,28 +5212,52 @@ void com_codename1_impl_ios_IOSNative_updatePersonWithRecordID___int_com_codenam
52125212
}
52135213

52145214
void com_codename1_impl_ios_IOSNative_screenshot__(CN1_THREAD_STATE_MULTI_ARG JAVA_OBJECT instanceObject) {
5215-
dispatch_sync(dispatch_get_main_queue(), ^{
5215+
dispatch_async(dispatch_get_main_queue(), ^{
52165216
POOL_BEGIN();
5217-
UIView *view = [CodenameOne_GLViewController instance].view;
5218-
UIImage *img = cn1_captureView(view);
5219-
if (!img) {
5220-
POOL_END();
5221-
return;
5222-
}
5217+
@try {
5218+
UIView *view = [CodenameOne_GLViewController instance].view;
5219+
if (!view) {
5220+
NSLog(@"Screenshot failed: view is nil");
5221+
com_codename1_impl_ios_IOSImplementation_onScreenshot___byte_1ARRAY(CN1_THREAD_GET_STATE_PASS_ARG nil);
5222+
POOL_END();
5223+
return;
5224+
}
52235225

5224-
NSData *png = UIImagePNGRepresentation(img);
5225-
if (!png) {
5226-
POOL_END();
5227-
return;
5228-
}
5226+
UIImage *img = cn1_captureView(view);
5227+
if (!img) {
5228+
NSLog(@"Screenshot failed: cn1_captureView returned nil");
5229+
com_codename1_impl_ios_IOSImplementation_onScreenshot___byte_1ARRAY(CN1_THREAD_GET_STATE_PASS_ARG nil);
5230+
POOL_END();
5231+
return;
5232+
}
52295233

5230-
// Create Java byte[]
5231-
int len = (int)[png length];
5232-
JAVA_OBJECT byteArr = __NEW_ARRAY_JAVA_BYTE(CN1_THREAD_GET_STATE_PASS_ARG len);
5234+
NSData *png = UIImagePNGRepresentation(img);
5235+
if (!png) {
5236+
NSLog(@"Screenshot failed: UIImagePNGRepresentation returned nil");
5237+
com_codename1_impl_ios_IOSImplementation_onScreenshot___byte_1ARRAY(CN1_THREAD_GET_STATE_PASS_ARG nil);
5238+
POOL_END();
5239+
return;
5240+
}
52335241

5234-
memcpy((JAVA_ARRAY_BYTE*)((JAVA_ARRAY)byteArr)->data, (const jbyte*)[png bytes], len);
5242+
// Create Java byte[]
5243+
int len = (int)[png length];
5244+
NSLog(@"Screenshot captured: %d bytes", len);
5245+
JAVA_OBJECT byteArr = __NEW_ARRAY_JAVA_BYTE(CN1_THREAD_GET_STATE_PASS_ARG len);
52355246

5236-
com_codename1_impl_ios_IOSImplementation_onScreenshot___byte_1ARRAY(CN1_THREAD_GET_STATE_PASS_ARG byteArr);
5247+
if (!byteArr) {
5248+
NSLog(@"Screenshot failed: could not allocate Java byte array");
5249+
com_codename1_impl_ios_IOSImplementation_onScreenshot___byte_1ARRAY(CN1_THREAD_GET_STATE_PASS_ARG nil);
5250+
POOL_END();
5251+
return;
5252+
}
5253+
5254+
memcpy((JAVA_ARRAY_BYTE*)((JAVA_ARRAY)byteArr)->data, (const jbyte*)[png bytes], len);
5255+
5256+
com_codename1_impl_ios_IOSImplementation_onScreenshot___byte_1ARRAY(CN1_THREAD_GET_STATE_PASS_ARG byteArr);
5257+
} @catch (NSException *exception) {
5258+
NSLog(@"Screenshot failed with exception: %@", exception);
5259+
com_codename1_impl_ios_IOSImplementation_onScreenshot___byte_1ARRAY(CN1_THREAD_GET_STATE_PASS_ARG nil);
5260+
}
52375261
POOL_END();
52385262
});
52395263
}

Ports/iOSPort/src/com/codename1/impl/ios/IOSImplementation.java

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -306,17 +306,39 @@ public void addCookie(Cookie c) {
306306
@Override
307307
public void screenshot(SuccessCallback<Image> callback) {
308308
screenshotCallback = callback;
309-
nativeInstance.screenshot();
309+
try {
310+
nativeInstance.screenshot();
311+
} catch(Exception e) {
312+
Log.e(e);
313+
if(screenshotCallback != null) {
314+
screenshotCallback.onSucess(null);
315+
screenshotCallback = null;
316+
}
317+
}
310318
}
311319

312320
static void onScreenshot(final byte[] imageData) {
313-
if(screenshotCallback != null) {
314-
Display.getInstance().callSerially(new Runnable() {
315-
@Override
316-
public void run() {
317-
screenshotCallback.onSucess(EncodedImage.createImage(imageData));
318-
}
319-
});
321+
try {
322+
if(screenshotCallback != null) {
323+
Display.getInstance().callSerially(new Runnable() {
324+
@Override
325+
public void run() {
326+
try {
327+
if(imageData != null) {
328+
screenshotCallback.onSucess(EncodedImage.createImage(imageData));
329+
} else {
330+
Log.e(new RuntimeException("Screenshot failed: imageData is null"));
331+
screenshotCallback.onSucess(null);
332+
}
333+
} catch(Exception e) {
334+
Log.e(e);
335+
screenshotCallback.onSucess(null);
336+
}
337+
}
338+
});
339+
}
340+
} catch(Exception e) {
341+
Log.e(e);
320342
}
321343
}
322344

0 commit comments

Comments
 (0)