SimSim, open up

    imageHello!

    Many of you write under iOS. Almost any developer sooner or later needs to dig deeper into the insides of their application at the file level - to see if any bundle is correctly unpacked, if the database has flown. The most persistent use the SimPholders application.

    My colleagues and I exploited the aforementioned creation for some time, and then weary and ceased.


    The reason was simple - SimPholders Nano (a paid application from the App Store) stopped working. Contacted the developers, they said that they were about to fix it and that they were not at all to blame. A little later, they removed the version of Nano from the App Store. They wrote to them again, as usual - in response to silence. After that I did not want to buy a non-AppStore version.

    Easy to say - stopped. The need to debug the engine through the exhaust pipe has not disappeared. We sat, played up - and wrote our own alternative, so - meet SimSim!

    Able to open applications installed both on the simulator and on the device. Get into the source - get ready for the worst. The first item on the agenda was not the elegance of the syllable, but the quickest possible achievement of the result. Well, import substitution, again.

    Deprecated screenshot


    To view applications on the simulator - just download, unzip, run, use. There is a kutsee on the github, but a description.

    The process of obtaining data about simulators and applications is not very interesting for the end user - just parsing several xml, matching data. To whom it is very interesting - see source codes.

    To view applications on the device - everything works, but there are nuances. About them below.

    To begin with, Apple does not provide an accessible API for working with iOS devices. Moreover - to access the file system. There are several libraries working either through private frameworks or through implementing protocols, knowledge of which was obtained as a result of reverse engineering, so it is difficult to predict their performance in the next version of both iOS and OS X.

    But our task is somewhat simpler? We do not need access to the entire file system of the device - only to our application. And then the local server enters the scene. More precisely, WebDav on top of GCDWebServer is GCDWebDAVServer. Easily links to the project, works stably - what’s more?

    So, we started the project with the linked GCDWebDAVServer on the device, started it, and we can even connect to our application, for example, from Finder. Already good, but I want more - auto-mount from the SimSim menu.

    Here we were waiting for a plug. There was no simple solution to mounting WebDav with the specified path and opening Finder in the appropriate place programmatically. Though cry, even crack. Various options have been tried as jerking Finder'a for AppleScript, and call mount'a. All wrong. Something seems to work, but somehow crooked and uncomfortable.

    In parallel, I had to sit in Finder's disassembled code in an attempt to spy - or maybe you can programmatically show hidden files without restarting Finder itself? Tedious, sad, long to study the listing of the disassembler at 200Mb. The result is FIG. Well, okay. Apple is to blame.

    While we pretended to mess with Finder — us — hurray-hurray — they poked our nose into a probable solution, which, when tested, turned out to be what we needed, namely, NetFSMountURLAsync (). The function is also, say, not too documented, but no alternative was visible.

    Briefly: it knows how to accept the options for mounting a network address, usernames, passwords, and after mounting it, asynchronously pull a 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 is no reason or time to understand them thoroughly.

    We only needed:

    openOptions = { kNAUIOptionKey : kNAUIOptionNoUI}, чтобы пользователя никто ни о чем не спрашивал.
    mountOptions = 
    { 
    kNetFSAllowSubMountsKey : YES, - чтобы монтировался не только верхний уровень шары
    kNetFSMountAtMountDirKey: YES - чтобы монтировалось туда, куда мы хотим смонтировать
    } 
    




    It is time to take the mount addresses, device names, and other information from somewhere, in order to use it to display it in the SimSim menu. Gloomy thoughts about settings dialogs, validation of everything entered, parsing of this and that ... got into my head ... Reluctance. The smaller the user interface in such utilities, the better. The result of the reflections was the Solomon’s decision - and let’s throw off the concern about the correctness of the data to users, and indeed let them write down what they want and where they want. Almost wherever they want - to a specific .plist. (We like our defaults - see paragraph 1.).

    For the persistent, who have read up to this point and decided to use SimSim to view the application on the device - it's time for the code.
    • Add GCDWebServer and GCDWebDAVServer to the project. Through cocoapods, or somehow else - in general, sort it out.
    • Add the initialization of GCDWebDAVServer to your application - pull the below somewhere at the start. (NSApplicationSupportDirectory here is just an example. You decide 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 the com.dsmelov.devices.plist file in the ~ / Library / Preferences directory. It will contain the name of the device and its address. Example:

      DevicesnameiPad2urlhttp://:@192.168.1.26:8082
    • It is done. Take the black mark ... Launch your application on the device - now you can open it directly from SimSim.


    In general, use it . And if someone doesn’t like something in the code, or, more likely, fresh ideas arise, join the development! The laziest ones can simply promote a project on the network - we will drop SimPholders, albeit mediocre, but open source!

    Also popular now: