Is there any programmatic way to control the xcode > simulate location command? I have external location test scripts I'd like to run, and ideally the test suite could cause xcode to change the location of the connected phone at will.
Is this possible, and if so how?
Not sure if it's exactly what you're after, but you can have different unit test bundles use different locations (or GPX files) by setting it up in the scheme.
You could then have unit tests in each bundle which test what you need regarding that specific location.
xctool can also just run the unit tests in a specific target using the -only option:
path/to/xctool.sh \
-workspace YourWorkspace.xcworkspace \
-scheme YourScheme \
test -only SomeTestTarget
There is a GitHub project called Pokemon-Go-Controller that does exactly what you want.
Overview of the solution:
Create a gpx file
Create a blank project referencing (not copying) that gpx file and run it on your device
Run auto clicker which will constantly click update location in Xcode
Update gpx file using some script and the device location will be automatically updated
Instead of the auto clicker you can use this Apple Script:
#Will continue update the location to the location name below from Xcode:
property locationName : "pokemonLocation" #name of your gpx filex
###########################
tell application "System Events"
tell process "Xcode"
repeat while true
click menu item locationName of menu 1 of menu item "Simulate Location" of menu 1 of menu bar item "Debug" of menu bar 1
delay 0.2
end repeat
end tell
end tell
Yes, it is possible.
1. Set up the GPX files as described in #InsertWittyName 's answer, or as described in this blog post.
2. Use Instruments to run your app in the Simulator using the different GPX files.
I would write out the entire process, but someone more eloquent than myself already has.
As an avid S/O user, I would be bereft to leave what is basically a single-link answer. So here is some extra, bonus information.
You should definitely look into security testing your location aware features. I will be at Black Hat this year, so if you're there, let's talk about it!
If you don't like the previously linked/sort of explained answer, you could use XCTest with code to simulate different locations (like this).
It looks like there are also Apple Script solutions, like this one.
I hope I have at the very least provided enough information to qualify as more than just a lazy link-only answer. Enjoy, and good luck!
idevicelocation is a command line tool to mock geolocation in ios devices.
Usage:
$ idevicelocation [OPTIONS] LATITUDE LONGITUDE
Set the location passing two arguments, latitude and longitude:
$ idevicelocation 48.856614 2.3522219000000177
Passing negative values :
$ idevicelocation 77.432332 -- -7.008373564
Stopping Location Simulation:
$ idevicelocation --stop
Options:
-d enable connection debug messages.<br/>
-u specify device UDID.<br/>
-h help.<br/>
-s stop location simulation on device.
It uses libimobiledevice library to communicate with the process com.apple.dt.simulatelocation which is also used by Xcode internally for the same purpose.
Build instructions are there in the README file. Make sure to mount the correct developer image before going random places. Thanks to Angulo for writing this awesome utility.
This tool is not currently being shipped with libimobiledevice package although there's a Pull Request pending since long.
Related
I have a set of XCUItests that exercise a bit of functionality in my app. Currently, I have the following function that pulls up a keyboard, types some stuff in, then taps "Search" (which is the equivalent in Enter in this context.
func clickSearchOnKeyboard(_ app: XCUIApplication) {
XCTAssert(app.staticTexts["Search"].waitForExistence(timeout: 10))
app.textFields["SearchItemView.SearchTextFieldID"].clearAndEnterText(testData.productData.valid.styleColor)
XCUIApplication().buttons["Search"].tap()
}
However, after updating the simulators to iOS 13, this test will fail because now when the keyboard is first pulled up we get a "What's New" fly-out explaining the new swipe functionality.
I think I can just add an If clause to my test code to handle this the first time it pops up, but I'm wondering if anyone has found out a way to disable these sorts of things for simulator testing:
Something in the Init() method that would disable "What's New" type of pop ups?
Some clever function that could always intercept this event and click "Continue"?
EXTRA BONUS POINTS: These automated tests run as part of an automated pipeline. As part of that, an assumption is that these tests run against a completely brand new simulator set (so we can't reuse existing simulators). Specifically, we blow away simulators (using Erase All Contents & Settings) prior to every run. So whatever solution will need to be completely portable and require 0 manual intervention.
Something else?
I think just testing for the dialog and dismissing it if it appears should be the best approach.
You could also launch an apple tool and trigger the popup after the erase & reset operation is complete as part of your initial tooling setup.
e.g.
xcrun simctl erase deviceuuid
xcodebuild test-without-building test name:DismissKeyboardTour destination=deviceuuid
xcodebuild test-without-building mytestsuite destination=deviceuuid
I would think you would only need to do this once per test suite run (eg all the tests)
You can run tests on clones of an already configured simulator (use xcrun simctl clone ...)
If you want to create simulators from scratch, then add a git repository in simulator folder, configure it as you like (skip keyboard onboarding in your case) and use git status to know what shall be changed in order to configure your simulators in scripts.
Detailed:
Create new simulator
Create a new git repository from its folder
Configure simulator the way you like
Watch changes in the simulator with git
Based on these changes add steps to your CI/CD runner script (prior test running)
i am trying to install opencv on my Mac IOS and there is this step of Adding an SDK path to CMAKE_OSX_SYSROOT, it will look something like this /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk.
and Add x86_64 to CMAKE_OSX_ARCHITECTURES, but don't know how to do it
I'm assuming you're already in the CMAKE application and you're following either one of these sets of directions.
Possible Instructions:
http://blogs.wcode.org/2014/10/howto-install-build-and-use-opencv-macosx-10-10/
http://outofbedlam.github.io/opencv/2015/07/15/Build-OpenCV-MacOSX/
Given which steps you isolated, I'm assuming you also know how to check and uncheck boxes in the CMAKE window. To enter text, you just right click in the empty space ("value" section) to the right of the variable of interest. When I came across this step, the thing which tripped me up was confirming the path/determining the right thing to enter in the window.* TLDR: it turned out to be almost the same thing (for me at least) "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk."
To find your path you need to navigate to that folder WITHIN THE TERMINAL! (Using Apple's Spotlight Search (command + space bar) or using finder windows just won't work. Because they don't see "inside" the Xcode application within the Applications folder. Assuming your home directory is't at the root, you need to keep entering cd .. until you get to the section that outputs the following:
>>>/ $ls -1
Applications
Library
Network
System
User Information
Users
Volumes
anaconda
...
Then you change directories ..., and see what's inside...
>>> $cd /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/
>>> SDKs $ls
MacOSX10.11.sdk
Combine the path with whatever you find in your SDKs folder and you're done (see caveat below)!
Additional Caveat: Those instructions don't say explicitely, but at the end of the whole CMake process, you have to copy the ...opencv/SharedLibs/lib/cv2.so file to your directory of python packages: home/usr/.../lib/python2.7/dist-packages/cv2.so. Based on the advice found here, I installed the cv2.so file from the SharedLibs folder instead of the StaticLibs folder and it worked.
*I tried doing a spotlight serach for the "Developer" folder or "Xcode.app" and nothing was coming up! I thought that folder/path didn't exist and googling around for "CMAKE_OSX_SYSROOT" with "Python" or with "opencv" and a whole bunch of other things made me think the problem was every more of a jumbled mess and problematic.
I need to debug the startup for an ios application on an actual device... and by start up I mean the very first instruction that is is executed when the OS hands control over to the app. Not "main". Also, this application doesn't have any symbols (ie. the debug information isn't available.. yet). I don't care if I have to debug at the CPU instruction level. I know how to do that (done it for over 30 years). I want the debugger to stop when control is about to transfer to the app. When I use the Attach|by Name command and run, it just says "Finished running".
Oh, and this application was not built in XCode. It is, however an application I built, signed and provisioned and moved to the device. The application does run since I can see the console output. Just in case you're thinking I'm some hacker trying to debug someone's application.
How's that for a tall order? I'll bet nobody can answer this... I've not been able to find any information on how I could do this with an XCode-built project. I wonder if it is simply not possible or "allowed" by the Apple overlords?
What do you say, Stack Overflow gods?
UPDATE: I should clarify something. This application is not built with any commercially available or open-source tool. I work with a tools vendor creating compilers, frameworks, and IDEs. IOW, you cannot get this tool... yet. In the process of bootstrapping a new tool chain, one regularly must resort to some very low-level raw debugging. Especially if there are bugs in the code generated by the tools.
I'm going to answer my own question because I think I've stumbled upon a solution. If anyone has anything more elegant and simple than this, please answer as well. On to the steps:
Starting with a raw monolithic iOS executable (not a bundled .app, but the actual binary mach-o file that is the machine code).
Create a new like-named empty Xcode project. Build and run it on the device.
Locate the output bundle's .app folder.
Copy the above raw iOS executable over the existing one in the .app bundle's folder.
The application will now have an invalid signature and cannot be deployed and run.
Run codesign against the app bundle (you can find out the command-line by running xcodebuild on the above Xcode project).
In the bundle's .app folder, run otool -h -l on the binary image. Locate the LC_UNIXTHREAD load command and find the value associated with the 'pc' register. This is address where the os loader will jump to your application. If this address is odd, then these are Thumb instructions otherwise it will be ARM (I think that's how it works).
Add a symbolic breakpoint (I used GDB instead of LLDB) and enter the address as '*0x00001234' as the symbol.
Select Product|Perform Action|Run Without Building.
Assuming that GDB is able to evaluate the breakpoint expression and set the break point, and you've selected Product|Debug Workflow|Show Disassembly When Debugging, the process should break at the very first instruction to be executed in the application.
You can now single step the instructions and use the GDB console to get/set register values.
Your question does not make sense - main is the entry point into the application. It is the first code that should be encountered, unless possibly you have initialize() overridden for some classes (but even then I think main would get hit before the runtime).
I think you are seeing some kind of odd error on launch and you think you want to set a breakpoint on entry to catch it, but far more likely what would help you is to describe the problem on launch and let one of the 4000 people who have seen and fixed the same crash help you...
However, if you really want to use GDB to break on an application with no symbols (but that you launch from XCode) you can have GDB break on an assembly address as per:
How to break on assembly instruction at a given address in gdb?
To find the address of main (or other methods) you can use tool or atos, some examples in this question:
Matching up offsets in iOS crash dump to disassembled binary
ADDITION:
If for some reason XCode cannot launch your application for debugging, you could also jailbreak and install GDB on the device itself which would give complete control over debugging. If XCode can launch you application I see no reason why being able to break at an arbitrary memory address does not give you the ability you seek...
One solution for applications with webviews is to run them in the iOS Simulator, and connect to that with the remote-debugger in macOS Safari. This is off-topic but maybe the one or other could benefit.
http://hiediutley.com/2011/11/22/debugging-ios-apps-using-safari-web-inspector/
Or use NetCat for iOS... not the most perfect solution, but at least you see what's going on.
I am providing this for everyone to hopefully save you some brain damage in finding this yourself.
As I'm working on a BlackBerry project that will run on various devices I ran into an issue grabbing screenshots from the handset (including the Torch 9850 ... not quite as good as my iPhones or my Android EVO or Infuse, but much better than the Storm and finally starting to look like a real smartphone - great performance and battery life too).
Normally I'd use my trusty BBScreenShooter and everything would be fine, but it kept crashing when attempting to capture images on the 9850. I posted a couple of requests for help on this site, but nobody could tell me why my BBScreenShooter was crashing or why I'd get "Retrieving screen <active> data ... Error: buffer too small" when using RIM's JavaLoader utility directly.
For those who didn't know BBScreenShooter delegates the "heavy lifting" to JavaLoader to grab the images.
With the help of Mark Sohm (easily one of the most knowledgable BB guys I know walking the planet) he asked me to verify I was using JavaLoader that is included in the v7 SDK. Turns out I wasn't. Good catch Mark, and thanks!
From the looks of things it appears the earlier versions of the JavaLoader utility have byte[] buffers they use for image capture that are hardcoded ... and too small.
So, for all those who need to capture screen shots from RIM's new 480 x 800 based handsets I have included a quick "how to" guide to help you get productive ASAP.
Step 1 - Make sure you have the v7.0 SDK downloaded (doesn't have to be installed, though I cannot think of a good reason not to). For Eclipse users:
Step 1a) Go to the Help menu
Step 1b) Install New Software menu choice
Step 1c) Add the "BlackBerry - http://www.blackberry.com/go/eclipseUpdate/3.6/java" items in your "work with" field.
Step 1d) Under the "BlackBerry Java Plug-in Category", look for the "BlackBerry Java SDK v7.0.0.X" checkbox and click NEXT.
Step 1e) Accept the license agreements and continue the download and installation process.
Step 2 - Go to the installation directory for your newly added SDK. We're going to grab a copy of the path to the JavaLoader utility and use it within a BAT file that will automate the capture and naming of screen shots. This will be found at /plugins/net.rim.ejde.componentpack7.0.0_7.0.0.28/components/bin/JavaLoader.exe
Step 3 - Create a folder you'd like to use to save screen captures. This will also hold your BAT file as the BAT file is specific to this particular project.
Step 4 - Create the BAT file. In my example here I keep all my IDEs, SDK, ... effectively all development environments on a different hard drive than my OS. I keep these on drive D, but modify your BAT to reflect the location and needs of your configuration.
Step 4a) It's important to turn the echo off, otherwise you will probably be unable to use the icon on the desktop to launch this script/utility.
Step 4b) If your BAT file is running locally (same folder) as JavaLoader then this step will be unnecessary. On the other hand if your JavaLoader is on a different hard drive and tucked away deep in folders then you'll have to "change directory" to get to it. Notice the "/D" switch that is used with the "change directory - cd" command so that we can change drives and paths in the same step.
Step 4c) As I like to use timestamps for part of my file names ... set local variables to represent the current date and time.
step 4d) The following "for" statements parse out the current date and time from my Windows 7 computer into a format that I want to include as the file names for my screen captures ... file name == BlackBerry_<date image was taken>_<time image was taken>.bmp.
Step 4e) Copy the newly created device screen shot that JavaLoader captured to your target folder and use the file name we've just created.
Step 4f) Now that we've successfully got a copy of the screenshot saved in our desired target folder we can delete the temporary image that JavaLoader created.
Step 4g) I echo a little statement that lets me know it all worked.
Example BAT file:
#echo off
cd /D D:\Program Files (x86)\EclipseBlackBerry\plugins\net.rim.ejde.componentpack7.0.0_7.0.0.28\components\bin
JavaLoader screenshot tempImage.bmp
set timestampdate=%date%
set timestamptime=%time%
For /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set timestampdate=%%c-%%a-%%b)
For /f "tokens=1-2 delims=/:" %%a in ('time /t') do (set timestamptime=%%a%%b)
copy tempImage.bmp "C:\Users\CirrusFlyer\Desktop\<project name>\Testing\Screenshots\BlackBerry_%timestampdate%_%timestamptime%.bmp"
DEL tempImage.bmp
echo Completed "...\<project name>\Testing\Screenshots\BlackBerry_%timestampdate%_%timestamptime%.bmp"
Step 5 - Close and save your BAT file. I kept the BAT in my actual project folder, then created a shortcut and placed it on my desktop. This way I can have my Eclipse up and running and be debugging the application on my handset, and when I want to grab a screen shot simply double-click the shortcut to execute the capture.
This will create screen shots and place them in the target directory: BlackBerry_2011-10-07_1015 PM.bmp, for example.
Step 6 - Your done. Happy coding. Hope this helps.
My next project: extending Eclipse so that I can do screen captures directly from within the IDE the same way I can when doing Android based programming.
I'm looking for a way to dynamically add in information about the application during the build process of an iOS application.
During testing, it would be great to know when the application I have installed on my device was built and possibly who built it would be a good to know as well.
I'm envisioning a section in settings.app that would give basic build information for debugging purposes. I don't want to have to manually update a build information file before each build - the data should be generated dynamically.
You can also use standard macro __DATE__ which will result string like "Jun 25 1980" of course with proper current date of build.
You can write a shell script build phase in Xcode that runs at the end of your build process. In this phase you can use the defaults command to write data to an arbitrary file. I've used this technique to write to the Info.plist file, but you can write to any file you want[1].
Here's a sample script to write the current git version to Info.plist:
infoplist="$BUILT_PRODUCTS_DIR/$INFOPLIST_PATH"
gitversion="$(cd "$SRCROOT" && git describe --always --dirty 2>/dev/null)"
if [[ -n "$gitversion" ]]; then
defaults write "${infoplist%.plist}" GitVersion "$gitversion"
fi
You should be able to adapt this to point to the file you want (e.g. your Settings bundle) and write the info you want.
[1] Be careful if you write to Info.plist, Xcode has bugs that can prevent it from realizing Info.plist changed during the build, which can break the provisioning when doing a device build.