Skip to content

2.5.1 iOS incremental build generates inconsistent binary #2557

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
toddanglin opened this issue Feb 21, 2017 · 28 comments
Closed

2.5.1 iOS incremental build generates inconsistent binary #2557

toddanglin opened this issue Feb 21, 2017 · 28 comments
Assignees
Labels
Milestone

Comments

@toddanglin
Copy link

There appears to be an issue with 2.5.1 that is corrupting all incremental iOS builds targeting the simulator. The issue is captured and well described here:

https://discourse.nativescript.org/t/ns-2-5-1-ios-incremental-build-generates-inconsistent-binary/591

Steps to reproduce:

  • Build and deploy an app to the iOS simulator using CLI 2.5.1
  • Trigger an incremental/LiveSync build
  • After successful build/sync, the app will crash on simulator
  • App cannot be re-opened or run until a fresh build is forced (using tns build or tns deploy)

This problem did not exist in 2.5.0.

@dtopuzov
Copy link
Contributor

dtopuzov commented Feb 21, 2017

@toddanglin
Can you reproduce the issue with hello-world templates?
Can you post your package.json?

I can not reproduce with:

npm uninstall -g nativescript
npm install -g [email protected]
tns create TestApp && cd TestApp
code app (open app folder in VSCode)
tns run ios

Make whatever changes (in css, js, xml, break the app on purpose with invalid changes and then fix it)
Result: No issues.

Same with release branch of https://github.com/NativeScript/sample-Groceries -> No issues.

@toddanglin
Copy link
Author

Let me try to create a project that reproduces the issue. Clearly, as per the forum thread, I'm not the only one encountering this error...but it's also clear that it's not impacting every project.

I have a hunch that it could be related to plugins, most like i18n since it does the most during the build process. Let me test and report back...

@toddanglin
Copy link
Author

Still struggling to get a new project to recreate the error. Here is the series of log messages that occurs when a LiveSync happens on my existing app (run with tns run ios --emulator):

Executing before-prepare hook from myapp/hooks/before-prepare/nativescript-dev-typescript.js
Executing before-prepare hook from myapp/hooks/before-prepare/nativescript-i18n.js
Preparing project...
Project successfully prepared (ios)
Executing after-prepare hook from myapp/hooks/after-prepare/nativescript-i18n.js
Transferring project files...
Successfully transferred myView.xml.
Refreshing application...
Successfully synced application com.htmlui.MyApp on device [UUID].

NativeScript debugger attached.
CONSOLE LOG file:///app/tns_modules/tns-core-modules/trace/trace.js:151:28: Debug: TabView._onSelectedIndexPropertyChangedSetNativeValue(1)
CONSOLE LOG file:///app/views/tabs/devicesView.ts:76:16: OLD INDEX undefined
Skipping prepare.
Transferring project files...
Successfully transferred InfoPlist.strings.
Successfully transferred Localizable.strings.
Refreshing application...
Feb 21 17:12:30 Mac-Pro com.apple.CoreSimulator.SimDevice.[UUID].launchd_sim[427] (UIKitApplication:com.htmlui.MyApp[0xd35f][5579]): Service exited due to signal: Terminated: 15
Unable to sync files. Error is: Command xcrun with arguments simctl launch [UUID] com.htmlui.MyApp failed with exit code 3. Error output:
 An error was encountered processing the command (domain=NSPOSIXErrorDomain, code=3):
Failed to lookup the process ID of com.htmlui.MyApp after successful launch.  Perhaps it crashed after launch.
No such process

Everything looks fine...the sync happens the app is refreshed...but then the process keeps going and seemingly attempts to build and refresh a 2nd time. Not sure if this will help trigger any ideas about what could be happening. Will keep trying to create a local, isolated problem reproduction.

@toddanglin
Copy link
Author

Okay. Got it. This simple hello-world project reproduces the error:
https://github.com/toddanglin/ns-build-error

The steps to recreate the project:

  • Create a new hello world project with CLI 2.5.1, with or without TypeScript template (tns create demo --tsc)
  • Add the iOS platform (tns platform add ios)
  • Add the i18n plugin (tns plugin add nativescript-i18n)
  • Create the folder/file for i18n strings: app > i18n > en > strings.xml
  • Add some string keys to the strings.xml file like:
<resources>
    <string name="btnText">Next</string>
</resources>
  • Run the project on the iOS simulator (tns run ios --emulator)
  • Project should build and load correctly
  • Make a change to the app source and save, triggering a LiveSync
  • Watch the build process get stuck in a loop of rebuilding and redeploying the native app

Let me know if you are unable to reproduce the problem using this project. Seems to be definitely related to the i18n plugin. To trigger, you must have the plugin installed and a strings.xml file in the project.

@toddanglin
Copy link
Author

toddanglin commented Feb 22, 2017

All of this is likely also related to this Issue in the nativescript-i18n repo:
EddyVerbruggen/nativescript-i18n#37

And this issue from 2.5.0:
#2482

Not sure if this is a regression or if the problem that those threads suggest was fixed did not cover all the scenarios. But definitely looks like same problem, only more severe in 2.5.1.

@Plamen5kov
Copy link
Contributor

Thank you @toddanglin,
We'll investigate.

@toddanglin
Copy link
Author

FWIW, I've downgraded to 2.5.0 for now. Seems to be the only way to continue working with the i18n plugin until this build issue is resolved.

@rosen-vladimirov
Copy link
Contributor

Hey @toddanglin ,
It looks like the nativescript-i18n plugin has before-prepare hook that modifies Info.plist in app/App_Resources/iOS directory: https://github.com/rborn/nativescript-i18n/blob/master/lib/before-prepare.js#L52 . All changes in App_Resources required rebuiliding the application. That's why CLI starts a new build when you apply any change. Plugin's hook always modifies the Info.plist file, no matter which file has been changed. CLI 2.5.0 has issues with checking files (it relies on the mtime of a file, not the ctime, which is incorrect), that's why you do not see the error with it - it just does not understand there's a change in App_Resources.
I'm not sure what is the best way to handle this. I have some ideas, for example:

  1. In CLI we may check the shasum of the modified files during watch and we may not transfer them to device (platforms dir in the project) in case the file there is the same. This way when you modify any other file, nativescript-i18n hook will overwrite app/App_Resources/Info.plist file, but its content will be the same and CLI will disregard this modification.
  2. Another option is to add new hook in which CLI will notify the plugins which are the modified files during watch. In this case, the plugin itself will see that the modified file is not any of the files that concerns its behavior and will not regenerate Info.plist.
  3. Third option is to add a new file at the top of the project, which will define the directories that should be watch. We may support minimatch syntax, so in case you will not modify App_Resources, you'll be able to exclude the directory from watched dirs. This will also allow watching of specific directories from node_modules and trigger livesync in case any file inside these plugins is modified.

What do you think? Ping @hshristov , @Plamen5kov as well.

@toddanglin
Copy link
Author

Personally, I like both Option 2 and 3.

  • Option 2 gives plugin authors power to make better plugins
  • Option 3 gives developers power to override default plugin behavior and explicitly opt-out folder from the watch process

Thinking of the CLI behavior before 2.5.0...the reason none of these problems existed was because LiveSync wouldn't attempt to do a native rebuild. The nativescript-i18n plugin would warn you that you'd need to manually trigger a full rebuild if you changed the strings definitions. And life was good. :)

I'm wondering if another option to consider is a flag (or config option) for tns run that lets developers disable native rebuilds during a LiveSync watch session. There are pros and cons to this approach, but it is this key change from 2.4 that is causing a lot of these problems now.

Adding @rborn since his plugin is one of the more popular impacted here.

@Plamen5kov
Copy link
Contributor

I'm for option 2. Power to the people!

I'm wondering if another option to consider is a flag (or config option) for tns run that lets developers disable native rebuilds during a LiveSync watch session.

@toddanglin I'm not so optimistic about the flag and here's why:

  • misuse (it has happened already with other flags of the sort --watch --no-watch)
  • might not resolve all variations of problems (not a general solution)
  • confusion about yet another flag
  • late adoption

@pkoleva pkoleva added the bug label Feb 27, 2017
@toddanglin
Copy link
Author

Any plans to patch this before 3.x?

I'm stuck now between downgrading to 2.5.0 and getting endlessly looping builds or 2.5.2, which still breaks with i18n. May have to downgrade 2.4.x if a patch will take a while...

@Plamen5kov Plamen5kov added this to the 3.0.0-RC milestone Mar 1, 2017
@Plamen5kov
Copy link
Contributor

@toddanglin we'll try to take a look at the concrete plugin and provide some workaround, and for 3.0 we should be able to introduce Option 2 as discussed, which will require some work on the plugin author`s side, but it's the best possible solution.

@Plamen5kov
Copy link
Contributor

@toddanglin can you tell me how exactly does the above demo fail with cli 2.5.2?

@abinici
Copy link

abinici commented Mar 6, 2017

Hi, I am experiencing the same issue with NS CLI 2.5.2 and NS SASS plugin. Steps to reproduce:

Here is log that is printed when running tns run ios and making a single change to a file:

| => tns run ios
Skipping prepare.
Searching for devices...
Skipping package build. No changes detected on the native side. This will be fast!
Skipping install.
Executing before-livesync hook from /Users/binici/projects/helloworld/hooks/before-livesync/nativescript-angular-sync.js
Refreshing application...
Successfully synced application org.nativescript.helloworld on device BA2C79D3-C503-4596-8604-8EBECA0D1594.

Executing before-watch hook from /Users/binici/projects/helloworld/hooks/before-watch/nativescript-dev-typescript.js
Found peer TypeScript 2.1.6
objc[94336]: Class PLBuildVersion is implemented in both /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/PrivateFrameworks/AssetsLibraryServices.framework/AssetsLibraryServices (0x11a438998) and /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/PrivateFrameworks/PhotoLibraryServices.framework/PhotoLibraryServices (0x11a25a880). One of the two will be used. Which one is undefined.
CONSOLE LOG file:///app/tns_modules/@angular/core/bundles/core.umd.js:111:20: Angular is running in the development mode. Call enableProdMode() to enable the production mode.
9:25:03 PM - Compilation complete. Watching for file changes.

Executing before-prepare hook from /Users/binici/projects/helloworld/hooks/before-prepare/nativescript-dev-android-snapshot.js
Executing before-prepare hook from /Users/binici/projects/helloworld/hooks/before-prepare/nativescript-dev-sass.js
Executing before-prepare hook from /Users/binici/projects/helloworld/hooks/before-prepare/nativescript-dev-typescript.js
Preparing project...
Project successfully prepared (ios)
Executing after-prepare hook from /Users/binici/projects/helloworld/hooks/after-prepare/nativescript-dev-android-snapshot.js
Executing after-prepare hook from /Users/binici/projects/helloworld/hooks/after-prepare/nativescript-dev-sass.js
Transferring project files...
Successfully transferred items.component.html.
Refreshing application...
Successfully synced application org.nativescript.helloworld on device BA2C79D3-C503-4596-8604-8EBECA0D1594.

NativeScript debugger attached.
CONSOLE LOG file:///app/tns_modules/@angular/core/bundles/core.umd.js:111:20: Angular is running in the development mode. Call enableProdMode() to enable the production mode.
Executing before-prepare hook from /Users/binici/projects/helloworld/hooks/before-prepare/nativescript-dev-android-snapshot.js
Executing before-prepare hook from /Users/binici/projects/helloworld/hooks/before-prepare/nativescript-dev-sass.js
Executing before-prepare hook from /Users/binici/projects/helloworld/hooks/before-prepare/nativescript-dev-typescript.js
Preparing project...
Project successfully prepared (ios)
Executing after-prepare hook from /Users/binici/projects/helloworld/hooks/after-prepare/nativescript-dev-android-snapshot.js
Executing after-prepare hook from /Users/binici/projects/helloworld/hooks/after-prepare/nativescript-dev-sass.js
Transferring project files...
Successfully transferred app.css.
Successfully transferred app.css.
Refreshing application...
Successfully synced application org.nativescript.helloworld on device BA2C79D3-C503-4596-8604-8EBECA0D1594.

CONSOLE LOG file:///app/tns_modules/@angular/core/bundles/core.umd.js:111:20: Angular is running in the development mode. Call enableProdMode() to enable the production mode.
Executing before-prepare hook from /Users/binici/projects/helloworld/hooks/before-prepare/nativescript-dev-android-snapshot.js
Executing before-prepare hook from /Users/binici/projects/helloworld/hooks/before-prepare/nativescript-dev-sass.js
Executing before-prepare hook from /Users/binici/projects/helloworld/hooks/before-prepare/nativescript-dev-typescript.js
Preparing project...
Project successfully prepared (ios)
Executing after-prepare hook from /Users/binici/projects/helloworld/hooks/after-prepare/nativescript-dev-android-snapshot.js
Executing after-prepare hook from /Users/binici/projects/helloworld/hooks/after-prepare/nativescript-dev-sass.js
Transferring project files...
Successfully transferred app.css.
Successfully transferred app.css.
Refreshing application...
Successfully synced application org.nativescript.helloworld on device BA2C79D3-C503-4596-8604-8EBECA0D1594.

CONSOLE LOG file:///app/tns_modules/@angular/core/bundles/core.umd.js:111:20: Angular is running in the development mode. Call enableProdMode() to enable the production mode.
Executing before-prepare hook from /Users/binici/projects/helloworld/hooks/before-prepare/nativescript-dev-android-snapshot.js
Executing before-prepare hook from /Users/binici/projects/helloworld/hooks/before-prepare/nativescript-dev-sass.js
Executing before-prepare hook from /Users/binici/projects/helloworld/hooks/before-prepare/nativescript-dev-typescript.js
Preparing project...
Project successfully prepared (ios)
Executing after-prepare hook from /Users/binici/projects/helloworld/hooks/after-prepare/nativescript-dev-android-snapshot.js
Executing after-prepare hook from /Users/binici/projects/helloworld/hooks/after-prepare/nativescript-dev-sass.js
Transferring project files...
Successfully transferred app.css.
Successfully transferred app.css.
Refreshing application...
Successfully synced application org.nativescript.helloworld on device BA2C79D3-C503-4596-8604-8EBECA0D1594.

CONSOLE LOG file:///app/tns_modules/@angular/core/bundles/core.umd.js:111:20: Angular is running in the development mode. Call enableProdMode() to enable the production mode.
Executing before-prepare hook from /Users/binici/projects/helloworld/hooks/before-prepare/nativescript-dev-android-snapshot.js
Executing before-prepare hook from /Users/binici/projects/helloworld/hooks/before-prepare/nativescript-dev-sass.js
Executing before-prepare hook from /Users/binici/projects/helloworld/hooks/before-prepare/nativescript-dev-typescript.js
Preparing project...
Project successfully prepared (ios)
Executing after-prepare hook from /Users/binici/projects/helloworld/hooks/after-prepare/nativescript-dev-android-snapshot.js
Executing after-prepare hook from /Users/binici/projects/helloworld/hooks/after-prepare/nativescript-dev-sass.js
Transferring project files...
Successfully transferred app.css.
Successfully transferred app.css.
Refreshing application...
Successfully synced application org.nativescript.helloworld on device BA2C79D3-C503-4596-8604-8EBECA0D1594.

CONSOLE LOG file:///app/tns_modules/@angular/core/bundles/core.umd.js:111:20: Angular is running in the development mode. Call enableProdMode() to enable the production mode.
Skipping prepare.
Transferring project files...
Successfully transferred app.css.
Successfully transferred app.css.
Refreshing application...
Successfully synced application org.nativescript.helloworld on device BA2C79D3-C503-4596-8604-8EBECA0D1594.

CONSOLE LOG file:///app/tns_modules/@angular/core/bundles/core.umd.js:111:20: Angular is running in the development mode. Call enableProdMode() to enable the production mode.

A single file change results in multiple builds and syncs to the iOS simulator. Just as @toddanglin I will have to downgrade to 2.5.0 until this is fixed.

@Plamen5kov
Copy link
Contributor

@abinici thank you for the detailed steps. I managed to reproduce the problem, and I'll start investigating right away.

@rborn
Copy link

rborn commented Mar 7, 2017

@Plamen5kov I think the problem is that both plugins (sass and mine) write something in the watched folder. So livesync will think something got updated and rebuild which will trigger another re-write, and so on.. 😃

@Plamen5kov
Copy link
Contributor

@rborn you're right, but in the case of your plugin, the app crashes in a totally different way, and it's not doing the constant rebuild we're seeing in @abinici's case.

@rborn
Copy link

rborn commented Mar 7, 2017

yeah 😞

@Plamen5kov
Copy link
Contributor

By popular vote, we'll implement option 2. We'll provide more information to the plugin authors through the hookArguments so they can act accordingly to the changed files about to be livesynced.

@pkoleva
Copy link
Contributor

pkoleva commented Mar 24, 2017

Hey guys, can you checkout our @next and tell us if what you requested is covered as you expected?
@rborn @abinici @toddanglin

@abinici
Copy link

abinici commented Mar 24, 2017

Hi @pkoleva , here is what I did to repeat my previous test:

  • npm i -g nativescript@next
  • tns create helloworld2 --ng
  • tns install sass

Now, when I run tns run ios I get the following error:

| => tns run ios
Executing before-prepare hook from /Users/binici/projects/helloworld2/hooks/before-prepare/nativescript-dev-android-snapshot.js
Executing before-prepare hook from /Users/binici/projects/helloworld2/hooks/before-prepare/nativescript-dev-sass.js
Executing before-prepare hook from /Users/binici/projects/helloworld2/hooks/before-prepare/nativescript-dev-typescript.js
Found peer TypeScript 2.1.6
Preparing project...
Project successfully prepared (ios)
Executing after-prepare hook from /Users/binici/projects/helloworld2/hooks/after-prepare/nativescript-dev-android-snapshot.js
Executing after-prepare hook from /Users/binici/projects/helloworld2/hooks/after-prepare/nativescript-dev-sass.js
First call of getPlatformData without providing projectData.

Before installing sass there is no problem building and running the app. Maybe sass-plugin is not compatible with version 3 of Nativescript?

Here is the output of tns info:

┌──────────────────┬───────────────────────┬────────────────┬───────────────┐
│ Component        │ Current version       │ Latest version │ Information   │
│ nativescript     │ 3.0.0-2017-03-24-8407 │ 2.5.3          │ Up to date    │
│ tns-core-modules │ 2.5.2                 │ 2.5.2          │ Up to date    │
│ tns-android      │                       │ 2.5.0          │ Not installed │
│ tns-ios          │ 3.0.0-2017-3-14-1     │ 2.5.0          │ Up to date    │
└──────────────────┴───────────────────────┴────────────────┴───────────────┘

@Plamen5kov
Copy link
Contributor

This is expected since the plugin authors haven't updated the plugins, in compliance with the changes with CLI from @next, where they have more info coming in during livesync.

@rborn
Copy link

rborn commented Mar 28, 2017

@pkoleva I'm a little overloaded these weeks, but as soon as I have a little time I'll give it a shot 😄

@plaisted
Copy link

I'm having the same issues, except using nativescript-dev-less instead of sass. It's very difficult to do anything sort of development. Is there currently any resolution here other than downgrading my TNS version to 2.4 or removing the dependency?

@Plamen5kov
Copy link
Contributor

All the changes, required by the plugin developers are already in master, so as soon as the plugin developers, update their respective plugins to use the newly provided information, the problems will be solved.

@rborn
Copy link

rborn commented Mar 28, 2017

@Plamen5kov could you give us some links where we should look ? (commits, docs, etc?)
Thank you.

@Plamen5kov
Copy link
Contributor

Plamen5kov commented Mar 28, 2017

@rborn sure:
#2605
https://github.com/NativeScript/nativescript-cli/pull/2605/files

These changes are available in @next.

@plaisted
Copy link

plaisted commented Mar 28, 2017

Are there any sample hooks using the hookArgs data? It accepted it as an allowable hook parameter however the variable was always undefined.

edit: I found it in use in nativescript-dev-babel, I'm going to start a clean project to isolate why I was getting undefined.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

8 participants