Comments (33)
@KrauseFx commented |
I noticed the same thing earlier today. Even tough snapshot
cleans and re-builds your app, it seems like an old version is still used in the simulator.
I don't know what's causing that.. I'll take a closer look into this.
from fastlane.
@KrauseFx commented |
I don't know what's causing this issue. The build folder gets removed before every build. The project will be cleaned build for every run. Instruments
should use the newly created .app
.
It looks like Instruments doesn't properly use the latest version....
from fastlane.
@muZZkat commented |
My guess is that it was Instruments
since it does work if you delete the app first... I had a good look around and couldn't find any other reports.
My current work around is to just delete the app manually from each simulator. Running 4 simulators vs 300 screenshots... still well in the green :)
I also looked at scripting the delete of the app, but seems like more work than it was worth.
from fastlane.
@KrauseFx commented |
That's really too bad... It can't be related to building the app.
Maybe one of those issues of an other open project will help:
jonathanpenn/ui-screen-shooter#74
https://github.com/jonathanpenn/ui-screen-shooter/pull/75/files
I still think, reseting the simulator is very bad solution, since this affects other apps as well.
from fastlane.
@stonemonk commented |
It is definitely Instruments which is not installing over the old app. It could be the intended behavior that Instruments expects a path to a bundle already installed into the device directory. (e.g. I saw this stated online in a couple places)
One option is to use simctl to install the app for each device:
xcrun simctl boot
instruments -s | sed -n "s/^iPhone 5s (8.1 Simulator) [(.*)]/\1/p"``
xcrun simctl install booted "/tmp/snapshot/build/app.app"
`xcrun simctl shutdown booted`
I think reseting or deleting app is a bad idea, some apps may need downloaded content or do other things that you don't want to redo every time.
from fastlane.
@KrauseFx commented |
@stonemonk Thanks for posting the code snippet. This looks quite interesting!
Have you tried the code yourself?
from fastlane.
@stonemonk commented |
Yes, I was previously using ui-screen-shooter (now switched to snapshot), and ran into this issue with both. After a bit of research and trial and error, I figured out the above commands. They seem to work perfectly for me. I suspect this is exactly how XCode is installing the app so should be reliable.
Couple notes though:
- simctl was only recently added, so it should be optional if you want to support previous versions of Xcode.
- These commands do not require the Sim to be open already and do not cause it to launch (It has its own internal notion of what a booted device is, it seems). However, if the Sim is open already it can sometimes cause these commands to fail with error messages about the Sim being in an invalid state. I would recommend closing the Simulator before running these commands and calling the 'xcrun simctl shutdown booted' command an extra time at the beginning as well, just to be safe. Then I think this will work 100% of time. General outline would be:
- Build app with xcodebuild
- Close the Simulator
- Call 'xcrun simctl shutdown booted' to be safe
- Loop through devices in Snapfile and call the 3 previously posted commands replacing "iPhone 5s (8.1 Simulator)" for the current device to be installed to.
- Continue with the normal instruments commands to do automation.
from fastlane.
@KrauseFx commented |
Wow, this looks really cool. Why didn't I know about this tool earlier.
Why don't we use the following commands:
Before running Instruments
xcrun simctl uninstall booted app_identifier
xcrun simctl install booted /tmp/snapshot/build/[app_name].app
The apps will always be in the same clear state, which is very good.
from fastlane.
@KrauseFx commented |
To you concern about reinstalling the app: I think it's perfectly okay to make a clean install of the app. Your automation scripts should not depend on the simulator state and should always be able to download or generate the data to run through the app.
I just tried a few more things
- Switching the simulator using the boot command does not work
- Instead, stopping the
iOS Simulator
process and launching it again usingopen -a "iOS Simulator" --args -CurrentDeviceUDID 5BDC8E90.....
works fine
Unfortunately all those things seem really buggy and unstable:
- Simulator sometimes hangs and does not start any more
- I crashed the whole Mac by running those commands
from fastlane.
@KrauseFx commented |
All this crashing of the Mac doesn't make development easier...
I got the following code now, which seems to do its job correctly, but still causes crashes:
def reinstall_app(app_path, device, app_identifier)
def com(str)
puts str.yellow
puts `#{str}`
end
def find_simulator(name)
all = `instruments -s`.split("\n")
all.each do |current|
return current.match(/\[(.*)\]/)[1] if current.include?name
end
end
udid = find_simulator(device)
com("xcrun simctl uninstall '#{udid}' '#{app_identifier}'")
com("xcrun simctl install '#{udid}' '#{app_path}'")
end
from fastlane.
@stonemonk commented |
I agree in principal that the app should be able to run from a clean slate and behave correctly, however in practice this may be a pain for some apps (such as mine where it needs to download 200MB of data first, asynchronously so hard get the timing right). Clean installing also resets user authorization settings (Allow GPS, Contacts, etc). These can be done via the UIA scripting but again its kind of a pain. Maybe offer an option weather to do an Upgrade or a Clean Install.
I have seen it crash my mac only once, and I was guessing it was when I tried to specify the device UUID with an install/uninstall command. It seems to work much better, if you use the shutdown booted
, and boot UUID
commands first, then specify 'booted' instead of a device UUID for the install/uninstall commands.
Its also much more stable when you close the Simulator first. Like I mentioned before the simctl seems to have its own notion of booted and has nothing to do with the open Simulator, but the two can interfere with each other. Thats why I recommended closing the Simulator completely before running those commands. (and not re-launching Simulator at all; Instruments will open it itself)
When I tested it, I was able to tell it to boot a device, install, shutdown, then continue to next device, and all 5 devices updated the app correctly without ever actually having the Simulator open. Note, you can also use xcrun simctl list
to see list of devices and it even tells you what state they are in. I used instruments -s
instead because it was easier to extract the UUID with sed
.
Edit: I've had it crash my mac a second time by running instruments command without calling xcrun simctl shutdown booted
first.
from fastlane.
@martnst commented |
FYI: I have this issue as well. Unf. I don't have the time to dig into it.
from fastlane.
@KrauseFx commented |
Okay, I tried some more things:
def find_simulator(name)
all = `instruments -s`.split("\n")
all.each do |current|
return current.match(/\[(.*)\]/)[1] if current.include?name
end
raise "Could not find simulator '#{name}' to install the app on."
end
udid = find_simulator(device)
com("killall 'iOS Simulator'")
com("xcrun simctl boot '#{udid}'")
com("xcrun simctl uninstall '#{udid}' 'net.sunapps.1'") # TODO: Dynamic
sleep 3
com("xcrun simctl install '#{udid}' '#{@app_path}'")
com("xcrun simctl shutdown '#{udid}'")
which works without crashing (hey, that's something \o/)
This code will run for all devices before actually running the tests.
It will kill the simulator, boot the each device, uninstall the app, install it again and shut down.
I'll keep testing and commit it later today.
from fastlane.
@stonemonk commented |
Yea, looks pretty much like what I am doing except I don't uninstall the app. Ran it on a 5 device sequence about 25 times yesterday without any hiccups.
Note once you boot the device, you don't actually need to specify the uuid in other commands they all accept the literal "booted".
And again, I would recommend calling xcrun simctl shutdown booted
one extra time at the beginning just in case. Closing the sim with killall does not unboot the device for simctl. Imagine if the uninstall/install step failed or the user Cmd-C the script midway, then simctl would still be booted and at the next run of script, the attempt at the boot command would fail.
from fastlane.
@KrauseFx commented |
@stonemonk I still have problems with this solution: It looks like changes are not applied every time. It works, but it seems like the old app is still used.
Does it work for you when you change your code and run snapshot
again?
from fastlane.
@stonemonk commented |
I don't do ruby, so didn't try to mess with the code. Instead I am running a shell script which does what I want and then calls snapshot normally. If you give me your email I can send you a PM with the script I am using. At this point I have used it to generate 1500 screenshots for my 10 apps without any issues.
As noted I am not uninstalling my app first, just installing over the old one, but I verified it really does update correctly for me every time. Perhaps the uninstall step is whats messing it up? I saw you have a delay after the uninstall and was wondering why..
from fastlane.
@stonemonk commented |
BTW, I've been trying to adapt my setup so that I can do an uninstall and reinstall, but it turns out it is not possible to script a response to some of the authorization prompts (push notifications, GPS, etc) because technically they are presented from Springboard and not from the app. So Upgrade really is my only option, and I will suggest again to make the "uninstall" part of your code an optional setting.
from fastlane.
@KrauseFx commented |
Hi @stonemonk, my email address is all over my GitHub profile and linked website. Please send me a message.
I thought the problem with the push and GPS popup were solved already. I don't show them straight after the app start, instead wait for a user interaction where I actually need GPS.
Glad to hear you created 1.500 screenshots using this tool. How have you been doing this before?
Good note, to make the re-install action optional.
from fastlane.
@stonemonk commented |
OK, I will send you an email.
I read that also, but still haven't gotten rid of the Auth messages, well I will look into it more next time I need to generate new screenshots.
Before we were using the ui-screen-shooter tool, but it required extensive customizations for it to work for us (which had to be re-applied manually after the recent updates), whereas snapshot works well pretty much out of the box.
An alternative to simctl is maybe just deleting the app folder in the sim device folder, I think that is sufficient to uninstall it (though I haven't verified it). And once uninstalled, I believe instruments will install it correctly if its not already installed.
from fastlane.
@kevinrenskers commented |
Is there a workaround available for this issue? I too had the problem where I was seeing screenshots of an old build. Uninstalled the app from all simulators and ran snapshot, but the new build isn't getting installed automatically. I had to install the app in every simulator and only then was snapshot able to run successfully.
from fastlane.
@KrauseFx commented |
@kevinrenskers Sorry, right now there is no 100% working solution out there. My most recent comment might work for you.
I'll find more time working on a better working fix early next year. In the mean time, I'm happy about any tips regarding this problem.
Thanks @stonemonk again, for the provided information 👍
from fastlane.
@tamastimar commented |
@KrauseFx Is there any progress on this issue?
Or can I use somehow your latest snippet in setup_for_device_change
?
from fastlane.
@KrauseFx commented |
Sorry, I haven't got that to be fully working yet... You can probably use something like the snippet you linked in the mean time 👍
from fastlane.
@tamastimar commented |
I've got Unknown method com
error with the following in my Snapfile
:
setup_for_device_change do |device|
udid = find_simulator(device)
com("killall 'iOS Simulator'")
com("xcrun simctl boot '#{udid}'")
com("xcrun simctl uninstall '#{udid}' 'com.logmein.authenticator'") # TODO: Dynamic
sleep 3
com("xcrun simctl install '#{udid}' '#{@app_path}'")
com("xcrun simctl shutdown '#{udid}'")
end
from fastlane.
@KrauseFx commented |
@tamastimar you forgot to copy the method you want to call:
def find_simulator(name)
all = `instruments -s`.split("\n")
all.each do |current|
return current.match(/\[(.*)\]/)[1] if current.include?name
end
raise "Could not find simulator '#{name}' to install the app on."
end
from fastlane.
@tamastimar commented |
No, I didn't.
That's right above the setup_for_device_change
callback. The error is because the com
method is unknown. Should I include anything?
from fastlane.
@KrauseFx commented |
oh, right, add
def com(cmd)
puts `#{cmd}`
end
above your code
from fastlane.
@KrauseFx commented |
I further investigated, this is not a caching problem of xcodebuild
, but really a simulator/instruments issue. I'll further investigate, since this issue must be fixed soon!
from fastlane.
@KrauseFx commented |
Looks like my current solution works, I'll keep trying a few apps and release a new version later today 👍
from fastlane.
@KrauseFx commented |
I'm happy to say, this issue is finally fixed: https://github.com/KrauseFx/snapshot/releases/tag/0.4.5
Update to the latest version and let me know if it works for you too. By default it will now re-install the app. In case you don't want this, see https://github.com/KrauseFx/snapshot/releases/tag/0.4.5
🚢
from fastlane.
@cl3m commented |
I still have problems where the app run in instrument is not the builded version.
Instead of calling reinstall_app I do :
com("killall 'iOS Simulator'")
com("instruments -w '#{device}'")
com("xcrun simctl install booted '#{@app_path}'")
That way when instruments is started a second time, it is loaded correctly
from fastlane.
@KrauseFx commented |
So, you run this instead of the few com
commands snapshot
currently uses?
from fastlane.
@cl3m commented |
yes. I don't want to reset the simulator but you could add this step with an option.
from fastlane.
Related Issues (20)
- Fastlane `2.219.0` was published without changes. HOT 2
- "ar-SA - Invalid request" when uploading metadata to Play Store with a locale it does not support HOT 1
- gym export_options : {method} resolves into empty string HOT 2
- Documentation for iOS screenshots on Xcode is outdated.
- TestFairy Action Fails with NoMethodError for key? Method on String
- Unable to ^C in response to 'Could not find fastlane ... Would you like to set fastlane up?'
- Match CLI Doc wrong? HOT 1
- [Sigh] Creating tvos provisioning profile fails when fetching devices. HOT 1
- `fastlane build_app` does not apply Flutter Flavor / Xcode Scheme HOT 3
- `fastlane match appstore` fails when generating tvOS profile HOT 2
- cert blocks sig 9
- You appear to have CocoaPods installed but it is not working. HOT 1
- exportArchive app requires a provisioning profile with the Access Wi-Fi Information, Hotspot, and Push Notifications features. HOT 1
- Match development with Appstore Connect API KEY fails due unexpected token error if there are more 18 bundle ids in matchfile
- number_of_commits run on GitHub action always returns 1 HOT 2
- Failing run via Bundler: `ensure in take_off': uninitialized constant FastlaneCore::UpdateChecker (NameError) HOT 5
- [Regression] uninitialized constant Fastlane::OpenStruct (NameError) with release 2.220.0 HOT 11
- [match] undefined local variable or method `profile` when running match with `output_path` HOT 6
- Fastlane is not reading macros from Package.Swift (SPM)
- fastlane sigh download_all and "Error parsing provisioning profile at path..."
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from fastlane.