Clean way to programmatically control Safari on iPhone? - iphone

The title say's almost all. What I have is short lived server processes that serves a web-based javascript test suite with optionally accompanying back-ends for integration tests (see here for how it's done). I'm looking for a better way to direct the iPhone Emulator's Safari to the URL given.
More, possibly optional background:
Up until iOS SDK 4.0 I've managed to control XCode using AppleScript to start a specially prepared PhoneGap project in this fashion:
AppleScript (referred to as "AS") starts XCode (referred to as "XC")
AS instructs XC to load the previously set up PhoneGap project.
AS instructs XC to launch the PhonePap project.
The PhoneGap project will redirect to the server serving the test suite, and the test suite runs.
In iOS 4.0 SDK, this only works the first round, the next time the test suite runner tries to make XC do the above routine, it fails requesting the previous run to be stopped. And I can't for the life of me find a way to stop the debugging session with AS [1], so I can only run one test suite without manual intervention, witch is pretty much a show stopper for us since we rely a lot on nightly test runs.
Now, what I really want to do is just start the iPhone Emulator, and then start Safari on the emulator with the possibility of sending an arbitrary URL to the emulated Safari.
What I've found so far is iphonesim, but I'm running into this issue and can't get it to properly start pre-compiled apps. A way to circumvent this issue in iphonesim would also be a good way forward.
[1] I'd accept a way to do this as a valid answer too.

I have a very different solution for you.
Write a custom iPhone app that just contains a web view. It will behave pretty much the same as MobileSafari. Then, embed a little web server in the app.
You can then control your app by calling specific urls on that server.
This is a very simple app. Will take you 30 minutes to put together.
This is easily integrated in Xcode or a bigger (Apple) script. You can use commands like curl to open URLs.

This is possible now:
xcrun simctl openurl booted "https://google.com"
https://apple.stackexchange.com/a/198798/144271

Post scriptum: how it was solved in the end.
A while after I asked this question, a user at github added a comment in issue 3 that what you need for iphonesim to work correctly is to give the absolute path to the application to start. So now we have a prebuilt PhoneGap project where a script modifies the contents of the www directory inside build/Debug-iphonesimulator/PhoneGap.app. The absolute path to this directory is then sent to iphonesim, starting up the project now pointing towards the correct server. No AppleScript and no XCode (except for the initial build). The test suite now takes 1/7 of the time it took to run earlier.

Related

cordova/phonegap 1.6 crash at second launch

i use xcode 4.3.2 with phonegap 1.6. my app runs well the first time, but if i close the app in the ios simulator and i launch it for the second time, it crashes. Why?
This is probably only in the simulator. I have had it a couple of times in the simulator but it never happened to me on-device.
I am currently having this issue, except in Android. This is with the release flag. More info can be found here: https://forum.ionicframework.com/t/v2-android-second-app-start-doesnt-work-for-release-version/125583
but here is a copy pasta in case the link goes down:
Synopsis:
My app has a canvas on it on the page html. On second start of initial install, app start doesn’t show canvas. I know because the body tag has a background and the canvas has a different background. The page does not have a module defined for it. This is only when built with --release
Environment:
Ionic: 3.20
Cordova: 7.1.0
Angular: 5.2.9
Android: 6.1.2 (I think build target 25)
jdk: 1.8
Additional Info:
I am sort of doing bleeding edge stuff, but I am now out of the realm of being able to solve this on my own. I am using pixi.js, specifically from an additional interface library called angular2pixi. A2p doesn’t support --aot building.
Before I go on, let me reiterate everything works, even on multiple app restarts for everything other than --release.
The top level architecture is fairly simple:
a2p provides a service that has an instance of pixi. My app uses that service and has a page with a canvas awaiting Pixi’s rendering. When the app initializes, it starts up the pixi service, passing it the canvas reference and voila: html5ified angular.
I have offloaded the actual initialization of the rendering to a user clicked button to make sure it’s not something to do with life cycles but that didn’t work either. Even more interestingly, the button I made didn’t show when the app didn’t load. So likely, this means the ion-content itself isn’t showing!
Most interestingly, if I go into app info and delete storage (not cache) then it works on next app start! I am using localstorage but I attempted removing all mentions of it and no luck. ALSO On second install, or rather what would more technically be an update, the app works on every start after that.
This happens on android and I can’t seem to replicate it in iOS other than the first time I tried. Because it is a release build, it’s difficult to debug. I attempted using Ionic Pro Monitoring to no avail.
So far, my leanings are:
some type of caching causing a bug with the canvas itself
an error that is causing cordova or ionic to terminate
problem with my build process
a2p’s architecture (how could I go about debugging this given I have little knowledge of the underlying mechanics of cordova/ng2 -> native compilation?)
a cordova plugin (perhaps causing one of the above)
So as you can probably tell from my formatting, I’m somewhere between nerd heaven and hell. Such a fascinating problem… but plis halp

iOS simulate Application and log events

I want to install and simulate iOS applications and find their malware intentions. See if connects to an IP address, downloads something, API call logs and soo on... kind of everything it does on the system. Does iOS Simulator log this events, or is there any online project that does that. If not then I should do it from scratch, do you have any advice how to do this? I only have the application file, not the entire Xcode project.
ALL i have is a bunch of applications(not the projects) that i have to test. All i want is to run them and log their actions in an automated way. Just like running a windows application on a virtual machine and log api trace, internet connections, memory, registry, disk actions... IN AN AUTOMATED WAY.
Thank you.
In the iOS simulator apps simply run on Mac, but their output is shown in the iOS simulator. This means that any tool that allows you to audit Mac applications will allow you to do the same with the iOS simulator.
Check your Activity Monitor, you'll see that the app is simply listed there. I think the standard Xcode Instruments will work fine for you.
If you have the Xcode project, then look at the code and the debugger while it is running. Other than that, if you run it in the iOS simulator you will only see the GUI portion of the app, unless you are running it side by side from Xcode (then you can use Instruments or the debugger). This documentation should allow you to run the apps on the simulator.

Quickly testing iOS and objective-c code

I was wondering if is there any way to quickly check iOS/objective-c snippets or new code inside my xcode project without having to compile the whole app for that, open up the simulator just to get the NSLog message traced on the console.
I remember when life was easier using ruby's irb or node command for node.js :)
It just gives me the impression that on iOS development you have to learn how to deal with this high complexity and dependencies all the time, but I am just starting on this new world. so any help would be appreciated.
thanks a lot
This timely blog post should help; I'm using it often already.
Update: there is also Code Runner available in Mac App Store - this supports many languages, including Objective-C.
An Xcode project can contain multiple targets. One of the targets can be a test driver in which you can put some class/object/snippet exercise code and drive it from the command-line, results to the debug console. Another option is to create unit test targets.
If the code you're writing has known expected input-output pairs and you're just writing code to make them work, you may want to look into using XCode's unit testing capabilities. A link to a tutorial on using unit tests is at http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/UnitTesting/0-Introduction/introduction.html . If you want to test more interactive things, it is possible to use Instruments (a program in XCode) to automate those tests as well using the Automation instrument. A guide on using Instruments is available at http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/AboutTracing/AboutTracing.html .
Not really—Objective-C is a compiled language, while I believe Ruby is interpreted (which allows for interactive testing like what you describe). You can reduce some of the overhead of building and running your project by just leaving the simulator open; stopping the app from Xcode will close the app but leave the simulator running, meaning that a rebuilt version of the app will launch more quickly when you run it.

Detecting with code if your iPhone app is live vs test

I was wondering if there was a way within an app code to determine if the app is real (in the iTunes store) versus test? The reason is that I have every part of in app purchase resolved. However when verifying the receipt you must send it to either https://buy.itunes.apple.com/verifyReceipt if live or https://sandbox.itunes.apple.com/verifyReceipt if just a test.
Currently I switch the setting prior to submission but I know such an approach can easily fail with a sandbox version being submitted by accident. I would like the code to determine which URL to use.
You could have it set using some #ifdefs and the different build configurations Xcode can create (i.e. debug vs. release vs. distribution).
You should use a #define APP_STORE, or something like that, and check with #ifdef. Then, in your build script to build your app store submission from scratch (you do have a one-step build script, right?), just have it automatically define APP_STORE, and you'll never forget.

XCode Test Automation For IPhone

I would like to have my iphone test app to be tested automatically in an IPhone. The following are the steps I would like to have:
compile, link and code sign the iphone app (Xcodebuild)
upload the newly built app to iphone
run the uploaded app in iphone automatically
collect the result from the gdb console
close the app
Right now, I have problem with step 2 and 3 where I cannot do it automatically (I can do it from XCode via "Build and Debug" button. This, however, will require manual clicking).
I did some research on automator and it does not answer my problem. Another option I am thinking about is to have the app compiled for iphone simulator and run it from there, but I am not sure how accurate the test result will be comparing to the real device.
I am new to Mac/IPhone development, perhaps someone has a better way of testing this. Any feedback and input are welcome. Thanks.
The comment section does not provide a good way of display the solution properly. Here is the summary of answer.
The task of building IPhone app, uploading and trigger the debug process on IPhone is done via AppleScript. Here is how the AppleScript looks like:
tell application "Xcode"
open "Users:chuan:Desktop:iphone_manual_client:iphone_manual_client.xcodeproj"
tell project "iphone_manual_client"
clean
build
(* for some reasons, debug will hang even the debug process has completed.
The try block is created to suppress the AppleEvent timeout error
*)
try
debug
end try
end tell
quit
end tell
AppleScript accepts ":" instead of "/" for file and folder separator.
The GDB console output can be captured by setting the GDB option to write it to file. this is done by typing the following command in Terminal:
defaults write com.apple.Xcode PBXGDBDebuggerLogToFile YES
defaults write com.apple.Xcode PBXGDBDebuggerLogFileName <path to my gdb output file>
Lastly, many thanks to various ppl who have helped to solve this problem.
The tool you probably want to use for the build and install is Applescript. Something like:
tell application "Xcode" to launch
I'm not pretending that this is a complete answer; there are still a lot of things to work out. But Applescript is going to be one of your key tools I believe.
Check out UISpec http://code.google.com/p/uispec/
It's a full automation test framework being developed for the iphone.
Check out iphone_testify, it works well with OCUnit and Google Toolbox For Mac, and I think it could be possible extend it for something like UISpec.
Regards
There's a command line tool "xcodebuild" you can call to kick off an XCode build without it being open. There are flags you can use to set targets and so on.
Dr Nic's testing with Ruby may help with some of this
Could you add a build phase to the target that runs a script to upload the binary to the iphone?
Right click the target, Add->New Build Phase->New Run Script Build Phase
xcodebuild will just build the binary and it will not upload the newly compiled binary to iphone.
actually it can upload (after signing it), but not run too bad...
maybe it can be run using gdb once connected to target but how (ip?, usb? usbnet?) ?