triniwiz / nativescript-pager

Apache License 2.0
90 stars 48 forks source link

iOS issues with Pager 11 when assigning the DataSource asynchronous #151

Closed felixkrautschuk closed 4 years ago

felixkrautschuk commented 5 years ago

In our scenario, we do an initial server request first to obtain the number of pages that we want to show in the pager component then, so at the beginning the pagers' datasource is an empty array and after the request we modify the pages array according to the server response.

This works perfectly on Android across different OS versions, but we have some issues on iOS side.

1.)

On iOS 12 and below, the app crashes as soon as the server request is done and the new pages-array is assigned to the pager component with the following log:

CONSOLE LOG file:///app/pager-page.js:22:0: onPagerSelectedIndexChanged: 0 CONSOLE LOG file:///app/pager-page.js:27:0: pager datasource not initialized yet -> prevent text loading process... CONSOLE LOG file:///app/pager-view-model.js:44:0: pager initialized Fatal JavaScript exception - application has been terminated. Native stack trace: 1 0x101843384 NativeScript::reportFatalErrorBeforeShutdown(JSC::ExecState, JSC::Exception, bool) 2 0x10185810c NativeScript::FFICallback::ffiClosureCallback(ffi_cif, void, void, void) 3 0x10238d3c4 ffi_closure_SYSV_inner 4 0x1023901b4 .Ldo_closure 5 0x1b2708a38 6 0x1b27097d4 7 0x1b26b7008 8 0x1b2c5cb20 9 0x1b2c57a58 10 0x1b2c56fb4 CFRunLoopRunSpecific 11 0x1b4e5879c GSEventRunModal 12 0x1df4b9c38 UIApplicationMain 13 0x102390044 ffi_call_SYSV 14 0x10238cae4 ffi_call_int 15 0x10238c5e0 ffi_call 16 0x101804f90 NativeScript::FunctionWrapper::call(JSC::ExecState) 17 0x10238b7e8 llint_entry 18 0x102389b64 llint_entry 19 0x102389b64 llint_entry 20 0x102389b64 llint_entry 21 0x102389b64 llint_entry 22 0x102389b64 llint_entry 23 0x102389b64 llint_entry 24 0x102389ac4 llint_entry 25 0x102389b64 llint_entry 26 0x10237560c vmEntryToJavaScript 27 0x101ffd658 JSC::Interpreter::executeCall(JSC::ExecState, JSC::JSObject, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) 28 0x1021d5ffc JSC::call(JSC::ExecState, JSC::JSValue, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&, WTF::NakedPtr&) 29 0x10181e148 NativeScript::GlobalObject::moduleLoaderEvaluate(JSC::JSGlobalObject, JSC::ExecState, JSC::JSModuleLoader, JSC::JSValue, JSC::JSValue, JSC::JSValue) 30 0x1019871b0 JSC::JSModuleLoader::evaluate(JSC::ExecState, JSC::JSValue, JSC::JSValue, JSC::JSValue) 31 0x10238b54c llint_entry JavaScript stack trace: scrollToItemAtIndexPathAtScrollPositionAnimated(file:///node_modules/nativescript-pager/pager.js:302:0) at file:///node_modules/nativescript-pager/pager.js:302:0 at UIApplicationMain([native code]) at _start(file:///node_modules/tns-core-modules/application/application.js:295:0) at run(file:///node_modules/tns-core-modules/application/application.js:323:0) at file:///app/app.js:46:0 at ./app.js(file:///app/bundle.js:174:34) at __webpack_require__(file:///app/webpack/bootstrap:750:0) at checkDeferredModules(file:///app/webpack/bootstrap:43:0) at webpackJsonpCallback(file:///app/webpack/bootstrap:30:0) at anonymous(file:///app/bundle.js:2:61) at evaluate([native code]) at moduleEvaluation([native code]) at promiseReactionJob([native code]) JavaScript error: file:///node_modules/nativescript-pager/pager.js:302:0: JS ERROR Error: attempt to scroll to invalid index path: <NSIndexPath: 0x9b35ad44ccd2a42f> {length = 2, path = 0 - 0} JavaScript call stack: ( 0 UIApplicationMain@[native code] 1 _start@file:///node_modules/tns-core-modules/application/application.js:295:0 2 run@file:///node_modules/tns-core-modules/application/application.js:323:0 3 @file:///app/app.js:46:0 4 ./app.js@file:///app/bundle.js:174:34 5 webpack_require__@file:///app/webpack/bootstrap:750:0 6 checkDeferredModules@file:///app/webpack/bootstrap:43:0 7 webpackJsonpCallback@file:///app/webpack/bootstrap:30:0 8 anonymous@file:///app/bundle.js:2:61 9 evaluate@[native code] 10 moduleEvaluation@:1:11 11 promiseReactionJob@:1:11 ) *** Terminating app due to uncaught exception 'NativeScript encountered a fatal error: Error: attempt to scroll to invalid index path: <NSIndexPath: 0x9b35ad44ccd2a42f> {length = 2, path = 0 - 0} at scrollToItemAtIndexPathAtScrollPositionAnimated(file:///node_modules/nativescript-pager/pager.js:302:0) at file:///node_modules/nativescript-pager/pager.js:302:0 at UIApplicationMain([native code]) at _start(file:///node_modules/tns-core-modules/application/application.js:295:0) at run(file:///node_modules/tns-core-modules/application/application.js:323:0) at file:///app/app.js:46:0 at ./app.js(file:///app/bundle.js:174:34) at webpack_require(file:///app/webpack/bootstrap:750:0) at checkDeferredModules(file:///app/webpack/bootstrap:43:0) at webpackJsonpCallback(file:///app/webpack/bootstrap:30:0) at anonymous(file:///app/bundle.js:2:61) at evaluate([native code]) at moduleEvaluation([native code]) at promiseReactionJob([native code]) ', reason: '(null)' * First throw call stack: (0x1b2ccb180 0x1b1ea39f8 0x101843808 0x10185810c 0x10238d3c4 0x1023901b4 0x1b2708a38 0x1b27097d4 0x1b26b7008 0x1b2c5cb20 0x1b2c57a58 0x1b2c56fb4 0x1b4e5879c 0x1df4\M-b\M^@\M-& NativeScript caught signal 6. Native Stack: 1 0x101887150 sig_handler(int) 2 0x1b28da9ec 3 0x1b28e0094 4 0x1b27bfea8 abort 5 0x1b1e8c788 cxa_bad_cast 6 0x1b1e8c934 7 0x1b1ea3e00 8 0x1b1e98838 9 0x1b1e981a8 cxa_get_exception_ptr 10 0x1b1e98168 11 0x1b1ea3b3c 12 0x101843808 NativeScript::reportFatalErrorBeforeShutdown(JSC::ExecState, JSC::Exception, bool) 13 0x10185810c NativeScript::FFICallback::ffiClosureCallback(ffi_cif, void, void, void) 14 0x10238d3c4 ffi_closure_SYSV_inner 15 0x1023901b4 .Ldo_closure 16 0x1b2708a38 17 0x1b27097d4 18 0x1b26b7008 19 0x1b2c5cb20 20 0x1b2c57a58 21 0x1b2c56fb4 CFRunLoopRunSpecific 22 0x1b4e5879c GSEventRunModal 23 0x1df4b9c38 UIApplicationMain 24 0x102390044 ffi_call_SYSV 25 0x10238cae4 ffi_call_int 26 0x10238c5e0 ffi_call 27 0x101804f90 NativeScript::FunctionWrapper::call(JSC::ExecState) 28 0x10238b7e8 llint_entry 29 0x102389b64 llint_entry 30 0x102389b64 llint_entry 31 0x102389b64 llint_entry JS Stack: UIApplicationMain([native code]) at _start(file:///node_modules/tns-core-modules/application/application.js:295:0) at run(file:///node_modules/tns-core-modules/application/application.js:323:0) at file:///app/app.js:46:0 at ./app.js(file:///app/bundle.js:174:34) at __webpack_require(file:///app/webpack/bootstrap:750:0) at checkDeferredModules(file:///app/webpack/bootstrap:43:0) at webpackJsonpCallback(file:///app/webpack/bootstrap:30:0) at anonymous(file:///app/bundle.js:2:61) at evaluate([native code]) at moduleEvaluation at promiseReactionJob

Note, that this crash does not occur when removing the setTimeout-call around the assignment of the datasource (to simulate the server-request... see the sample app provided below for more details).

On iOS 13, the crash does not occur at all.

2.) When the first page is visible, the layout of the page is not correct (everything is shiftes up... see the GIF for better understanding what I mean.)

NSPagerIssueIOS

In addition, when scrolling forwards and then backwards, you can see that the upper part is suddenly moved to the left. This part is just a normal GridLayout that is centered horizontally and it should work just the way it does when using it outside the pager component. Alss this issue does not occur on Android at all.

Which platform(s) does your issue occur on?

Please, provide the following version numbers that your issue occurs with:

Please, tell us how to recreate the issue in as much detail as possible.

Describe the steps to reproduce it. Just open the sample app provided below and navigate to the page that contains the pager component.

Is there any code involved?

NSPagerIssueIOS.zip

trevormackay commented 4 years ago

I have this same issue. Can we get some suggestions on how to avoid this error?

alexandruantonica commented 4 years ago

@felixkrautschuk @trevormackay

  1. The first problem seems to be a bit strange and maybe @triniwiz will be able to help you. But in my apps, in order to avoid these kinds of situations, I prefer to wrap the Pager into an ng-container or StackLayout/GridLayout/etc that will have the *ngIf condition. In this way, the Pager will be never be initiated with 0 items. Once I have at least 1 element in the list I will show the Pager. Something like that
    <StackLayout *ngIf="!!source.length">
    <Pager [items]="source | async"...></Pager>
    </StackLayout>

    and if the source is async you might do something like that. Instead of initializing the source with an empty array, you'll initialize it with null and then you'll wait for the response from the server and then initialize the source with how many items you have.

    <StackLayout *ngIf="source | async as myItems">
    <Pager [items]="myItems"...></Pager>
    </StackLayout>
  2. I haven't' see yet your code but sometimes the problem with misalignment of the slides in Pager isn't because of the plugin itself. There could be some problems with your HTML structure. Pager is trying to fill the empty space but if do not give him enough space, it won't know how much space to use and all the rendering will fail. Make sure you're using properly the layouts available in Nativescript (StackLayout/GridLayout/FlexboxLayout/etc). @triniwiz correct me if I am wrong.
triniwiz commented 4 years ago

To get proper async I would suggest using an ObservableArray it’s better supported

triniwiz commented 4 years ago

try upgrading to the latest version while using the ObservableArray

triniwiz commented 4 years ago

try upgrading to the latest version while using the ObservableArray

felixkrautschuk commented 4 years ago

@triniwiz first, thank you for relasing another upgrade on this plugin.

But unfortunately, the app still crashes on iOS 12 device.

CONSOLE LOG file:///app/pager-page.js:22:0: onPagerSelectedIndexChanged: 0 CONSOLE LOG file:///app/pager-page.js:27:0: pager datasource not initialized yet -> prevent text loading process... CONSOLE LOG file:///app/pager-view-model.js:44:0: pager initialized NativeScript caught signal 11. Native Stack: 1 0x10d743481 sig_handler(int) 2 0x11147c42d _sigtramp 3 0x7ffa0f003a00 4 0x1113bab4d libunwind::UnwindCursor<libunwind::LocalAddressSpace, libunwind::Registers_x86_64>::step() 5 0x1113bee4c _Unwind_RaiseException 6 0x110f994aa cxa_throw 7 0x10f9b0bfa _objc_exception_destructor(void*) 8 0x110b5c735 +[NSException raise:format:] 9 0x11183a30b -[UICollectionView _contentOffsetForScrollingToItemAtIndexPath:atScrollPosition:] 10 0x11183abe3 -[UICollectionView _scrollToItemAtIndexPath:atScrollPosition:animated:] 11 0x10e134b4d ffi_call_unix64 12 0x126133c00 JS Stack: scrollToItemAtIndexPathAtScrollPositionAnimated([native code]) at file:///node_modules/nativescript-pager/pager.js:306:0 at UIApplicationMain([native code]) at run(file:///node_modules/@nativescript/core/application/application.js:312:0) at file:///app/app.js:42:0 at ./app.js(file:///app/bundle.js:163:34) at webpack_require__(file:///app/webpack/bootstrap:750:0) at checkDeferredModules(file:///app/webpack/bootstrap:43:0) at webpackJsonpCallback(file:///app/webpack/bootstrap:30:0) at anonymous(file:///app/bundle.js:2:61) at evaluate([native code]) at moduleEvaluation at at asyncFunctionResume at at promiseReactionJob

On iOS 13, the crash does not occur. I also cannot see the effect anymore, where all the content was shifted up on the first page. But there is still the effect, that the upper part is suddenly moved to the left, after you go forwards for some pages and then backwards.

Bildschirmfoto 2020-02-22 um 19 35 44

It should actually be centered horizontally all the time (as it is when going forwards).

I updated the sample app, so it uses now NS 6.3.2 and nativescript-pager 12.0.0-alpha.0: NSPagerIssueIOS.zip

triniwiz commented 4 years ago

@felixkrautschuk thanks for this usage case and demo so it's fixed https://github.com/triniwiz/nativescript-pager/commit/242a359d77bd282f8cdad96a9fa4859951a6e62d also I tweaked the demo a bit, I'm saving the selectedIndex to load when with the timeout init method

felixkrautschuk commented 4 years ago

@triniwiz thanks, the latest version (12.0.0-alpha.3) fixes the crash on iOS 12.

Do you have any idea about the upper part ( < Page x of y > ) moved to the left part of the screen? It orccurs on iOS 12 and 13 and it happens randomly, mostly when going backwards. It seems to be related to the way I am accessing the parents-bindingcontext. I need to do that, because the count of pages is not part of the bindingcontext of one item within the pager. If I use static content for the Label, then this issue does not occur, everything stays centered horizontally then.

triniwiz commented 4 years ago

Not sure what's happening but with the demo you sent me

Before

Before

Tweaked

After

felixkrautschuk commented 4 years ago

@triniwiz very strange that this effect does not occur on your side. Are you using the native iOS Simulator from Xcode?

Because on my side, the latest version of the demo app looks like this: pager_issue_gif

triniwiz commented 4 years ago

I'll try on other sim versions

felixkrautschuk commented 4 years ago

@triniwiz I found a solution for the upper part being shifted to the left side.. just by tweaking the outer GridLayout a bit. So you do not need to try this on other simulators anymore.

Thanks for your help on this issue