{"id":2104,"url":"https://github.com/johnno1962/Remote","last_synced_at":"2025-08-02T23:31:30.791Z","repository":{"id":25178224,"uuid":"28601395","full_name":"johnno1962/Remote","owner":"johnno1962","description":"Control your iPhone from inside Xcode for end-to-end testing.","archived":false,"fork":false,"pushed_at":"2022-09-18T08:49:16.000Z","size":384,"stargazers_count":810,"open_issues_count":0,"forks_count":52,"subscribers_count":21,"default_branch":"main","last_synced_at":"2024-05-02T00:54:30.674Z","etag":null,"topics":["xcode-plugin"],"latest_commit_sha":null,"homepage":null,"language":"Objective-C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/johnno1962.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-12-29T18:15:56.000Z","updated_at":"2024-04-15T23:30:53.000Z","dependencies_parsed_at":"2022-08-23T18:00:42.030Z","dependency_job_id":null,"html_url":"https://github.com/johnno1962/Remote","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnno1962%2FRemote","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnno1962%2FRemote/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnno1962%2FRemote/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnno1962%2FRemote/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/johnno1962","download_url":"https://codeload.github.com/johnno1962/Remote/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228503095,"owners_count":17930509,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["xcode-plugin"],"created_at":"2024-01-05T20:16:03.635Z","updated_at":"2024-12-06T17:30:34.766Z","avatar_url":"https://github.com/johnno1962.png","language":"Objective-C","funding_links":[],"categories":["Testing","测试","Objective-C","HarmonyOS"],"sub_categories":["UI Testing","Other free courses","Windows Manager"],"readme":"## Remote - Control your iPhone from Xcode\n\n\"Remote\" is a plugin for Xcode that allows you to control an iPhone \nfrom a window on your Mac during development. Originally created to avoid\nhaving to pick  up a device during testing you can record \"macros\" \nof device touches and replay them. It will also compare the resulting screen\noutput against a snapshot for end-to-end testing. The Macro log is an \neditable WebView that can be modified at will. Finally, you can now\nrecord and save all display output into a quicktime movie.\n\n**Update:** This former Xcode plugin has been re-organised into a\nSwift Package for use in other apps. To use `Remote`, simply add this\nproject as a Swift package and the `RemoteCapture` target to your app.\nIt will connect automatically using the hostname of your desktop. You\nalso need to be running an application containg the `RemoteUI` target\nsuch as [InjectionIII](https://github.com/johnno1962/InjectionIII) or the\n[HotReloading](https://github.com/johnno1962/HotReloading) daemon with\n\"Remote Control\" enabled to receive connections and render your device's\nscreen. By default, adding the package to a project will have it try to\nconnect to a process running the remote UI. The package manifest\ncompiles your hostname into the package so it should be able to\nconnect from a device.\n\n![Icon](http://injectionforxcode.johnholdsworth.com/remote.gif)\n\n(The gif shows the recording of a macro, saving it and then playing it\nback - testing the screen is as expected in the snapshot.)\n\nTo use, download the zipped source for this plugin, build and restart \nXcode. You can then patch your project's main.m to include the Remote \nclient header using \"Product/Remote/Patch App\" or it can load from a \nbundle on the fly if using the simulator. When using a device check that\nthe correct IP address has been patched into main.m so the device can connect.\nTo use with Swift, add an empty main.m to your project so it can be patched.\n\nThe display shadowing window will not display by default. Use the\nMenu item \"Product/Remote/Load\" to have it appear. Thereafter, touches\non the shadow display or device applied and recorded. To save a macro \nor a sequence of touches, enter a name into the textfield towards the \nbottom of the touch display and click the save button. You can then \nreplay the macro either by loading it using the pulldown menu \nat the top of the touch display and clicking replay or directly from \nthe \"Product/Remote/\u003cMacro Name\u003e\" Menu.\n\nFor end-to-end testing, include a snapshot in a macro by clicking\nthe \"Snapshot\" button. On replay, the macro will pause until the screen \nmatches the snapshot within the specified tolerance or it will timeout \nasking if you would like to update the snapshot or the tolerance used \n(remember to save the updated macro.) The units of tolerance are the \nnumber of bytes the screen image differs after the run length encoding\nof simular pixel values.\n\n### Macro entries logged/replayed:\n\n- Hardware \u0026lt;hw.machine\u003e - device type from sysctlbyname()\n\n- Device \u0026lt;screen width\u003e \u0026lt;screen height\u003e \u0026lt;snapshot scale\u003e \u0026lt;device scale\u003e\n\n- Begin \u0026lt;wait time\u003e \u0026lt;x\u003e \u0026lt;y\u003e [\u0026lt;x2\u003e \u0026lt;y2\u003e] - touch(s) start\n\n- Moved/Ended \u0026lt;ditto\u003e touches moved/ended - two touches maximum\n\n- Expect timeout:\u0026lt;seconds\u003e tolerance:\u0026lt;bytes different\u003e.. \u0026lt;snapshot\u003e\n\n### Implementation Classes\n\nUI:\n\n- RMPluginController - interface between the Remote display and Xcode\n\n- RMWindowController - macro re-player and overall nib controller\n\n- RMMacroManager - controls display, saving and loading of macros\n\nInternal (connected by protocol RMDeviceDelegate):\n\n- RMImageView - subclass of NSImageView for event capture/device display\n\n- RMDeviceController - interface between remote display and device\n\n- RemoteCapture.h - #imported into application's main.m to connect to Xcode\n\nRemoteCapture.h requires a patched main.m to be compiled using ARC.\n\n### Limitations\n\nRemote uses [UIWindow.layer renderInContext:] so most activity on the device is \ncaptured including the keyboard but excepting video replay and openGL layers.\nUIAlertView prompts are also not captured as they seem to render outside the window\nhierarchy. Finally, UIDatePickers are not rendered correctly at all although they will \nrespond to events. To preserve network bandwidth to the device animations are not played.\n\nRemote performs better with swipe events if you make an initial tap on the device.\n\nPlease note: for some reason it takes about a minute before Xcode will accept remote\nconnections on it's server socket (firewall complications?). After restarting Xcode\nyou may need to wait a while before being able to use the Remote plugin from a device.\n\n### Thanks\n\nAVFoundation code for video capture adapted from:\n[https://github.com/acj/TimeLapseBuilder-Swift](https://github.com/acj/TimeLapseBuilder-Swift)\n\nMIT license. Please see the LICENSE file for the particulars.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnno1962%2FRemote","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjohnno1962%2FRemote","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnno1962%2FRemote/lists"}