
Hello!
Many of you write under iOS. Almost any developer sooner or later there is a need to dig deeper into the insides of his application at the file level - to see if any bandl correctly unpacked, if the base hadn't flown. The most persistent use the application SimPholders.
My colleagues and I exploited the aforementioned creation for some time, and then we got tired and stopped.
')
The reason was simple - SimPholders Nano (a paid application from the App Store) stopped working. We contacted the developers, they said that they were about to fix everything and in general they were not to blame for anything. A little later, they removed the Nano version from the App Store. They wrote again, as usual - in response to silence. I did not want to buy the non-AppStore version after this.
Easy to say - have ceased. The need to debug the engine through the exhaust pipe has not disappeared anywhere. We sat, pogundosili - and wrote their alternative, so - meet
SimSim!Able to open applications installed on both the simulator and the device. Climb to the source - get ready for the worst. The first item on the agenda was not the elegance of the syllable, but the quickest achievement of the result. Well, import substitution, again.
To view applications on the simulator - just download, unpack, run, use. There is a shortcut on the githaba, but a description.
The process of obtaining data on simulators and applications is not too interesting for the end user - just parsing several xml, data mapping. Who is very interesting - see the source.
To view applications on the device - everything works, but there are nuances. About them below.
Let's start with the fact that Apple does not provide an accessible API for working with iOS devices. Especially since - to access the file system. There are several libraries that work either through the private frameworks, or through implementing protocols, knowledge of which was obtained as a result of reverse engineering, so that their performance in the next version of both iOS and OS X is difficult to predict.
But we have a little easier task? We do not need access to the entire device file system - only to our application. And here comes the local server. More precisely, WebDav over
GCDWebServer - GCDWebDAVServer. It is easy to link to the project, it works stably - what is more?
So, we launched the project with GCDWebDAVServer on the device, started it, and we can even connect to our application, for example, from the Finder. Already good, but I want more - auto-mounting from the SimSim menu.
Here we were waiting for plugging. There was no simple software solution for mounting WebDav with the specified path and opening Finder in the appropriate place. Though cry, even burst. Various options have been tried, such as tweaking Finder for AppleScript, and calling mount. It's not that. It seems that something works, but somehow crooked and uncomfortable.
At the same time, I had to sit in Finder’s disassembled code in an attempt to peep - or maybe you can turn on the software to show hidden files without restarting Finder himself? Tedious, sad, for a long time to study the listing disassembler 200Mb. The result is FIG. Well, okay. Apple is to blame.
While we were pretending that we were busy with Finder - we - hurray - hurray - we were stuck with a probable solution, which, when checked, turned out to be what we needed, namely, NetFSMountURLAsync (). The function is also, say, not too documented, but the alternative was not visible.
Briefly: it can take in itself the options for mounting the network address, login passwords, and upon completion of the mount, asynchronously twitch the block of code with the transfer of mount points to it.
Long and tedious:int NetFSMountURLAsync(CFURLRef networkShare, CFURLRef mountPath, CFStringRef userName, CFStringRef password, CFMutableDictionaryRef openOptions, CFMutableDictionaryRef mountOptions, AsyncRequestID* requestID, dispatch_queue_t queue, ^(int status, AsyncRequestID requestID, CFArrayRef mountpoints) {
Where
networkShare - , . mountPath - OS X. userName, password - . queue - , dispatch_get_main_queue().
The openOptions and mountOptions dictionaries contain multiple options, half of which are commented out in NetFS.h, and there was no reason or time to understand them thoroughly.
We only needed:
openOptions = { kNAUIOptionKey : kNAUIOptionNoUI}, . mountOptions = { kNetFSAllowSubMountsKey : YES, - kNetFSMountAtMountDirKey: YES - , }
It is time to get mount addresses, device names and other information from somewhere in order to use it to display in SimSim's menu. Dark thoughts about settings dialogs, validation of everything entered, parsing of this and that ... reluctance. The smaller the user interface in such utilities, the better. The result of reflection was the Solomon's decision - and let us take care of the correctness of the data on users, and in general let them prescribe what they want and where they want. Almost where they want - in a specific .plist. (We like our silence - see paragraph 1.).
For the persistent, who have read so far and decided to use SimSim to view the application on the device, the time has come for the code.
- Add GCDWebServer and GCDWebDAVServer to the project. Via cocoapods, or something else - in general, sort it out.
- Add GCDWebDAVServer initialization to your application - pull the below somewhere at the start. (NSApplicationSupportDirectory is just an example here. It's up to you where the server will have /).
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); NSString *path = [paths lastObject]; GCDWebDAVServer* server = [[GCDWebDAVServer alloc] initWithUploadDirectory:path]; server.allowHiddenItems = YES; [server startWithPort:8082 bonjourName:nil];
- Record the IP address of your iPad / iPhone.
- Create a com.dsmelov.devices.plist file in the ~ / Library / Preferences directory. It will contain the device name and its address. Example:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd"> <plist version="1.0"> <dict> <key>Devices</key> <array> <dict> <key>name</key> <string>iPad2</string> <key>url</key> <string>http://:@192.168.1.26:8082</string> </dict> </array> </dict> </plist>
- It is done. Take the black mark ... Run your application on the device - now you can open it directly from SimSim.
In general,
use . And if someone doesn’t like something in the code, or, besides aspirations, fresh ideas arise, join the development! The laziest can just popiar the project in the network - we throw SimPholders, albeit mediocre, but open source!