Skip to content

Commit 9986034

Browse files
Merge pull request #35 from telerik/kerezov/docs
Improve docs
2 parents 382c9c6 + 25fbd17 commit 9986034

File tree

1 file changed

+290
-9
lines changed

1 file changed

+290
-9
lines changed

README.md

+290-9
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,14 @@ ios-device-lib
33

44
JavaScript library, designed to facilitate communication with iOS devices. The library’s interface is Promise-based.
55

6-
Usage
6+
Quick overview
77
==
88

9-
In order to use `ios-device-lib`, just add a reference to it in your package.json:
10-
```JSON
11-
dependencies: {
12-
"ios-device-lib": "*"
13-
}
14-
```
9+
In order to use `ios-device-lib`, just add a reference to it in your package.json by executing
10+
11+
`$ npm install --save --save-exact ios-device-lib`
1512

16-
After that execute `npm install` in the directory, where your `package.json` is located. This command will install all your dependencies in `node_modules` directory. Now you are ready to use `ios-device-lib` in your project:
13+
In your project. Now you are ready to use `ios-device-lib` in your project:
1714

1815
```JavaScript
1916
const DeviceLib = require("ios-device-lib");
@@ -33,7 +30,291 @@ dl.install("./app.ipa", ["deviceId1", "deviceId2"])
3330
});
3431
```
3532

33+
Building
34+
==
35+
The `ios-device-lib` package can be built on either Windows (requires Visual Studio) or macOS (requires Xcode). In order to build the application one should simply open the `.sln` or `.xcodeproj` file with the respective tool and click build. Whenever building in **release** configuration, the result binary will end up in `bin/<platform-name>/<architecture>`, relative to the root of this repository. For example `bin/win32/x64/` or `bin/darwin/x64/`. The JavaScript counterpart of the C++ code expects the binaries to be present in those exact locations, so one would have to build at least once prior to using the application.
36+
37+
Inter-process Communication
38+
==
39+
This application consists of two separate layers - one `C++` and one `Node.js`. The `C++` layer implements the application's business logic, whereas the `Node.js` layer exists simply for alleviation. Whenever the `Node.js` part is used, it launches the `C++` binary and initiates communication with it. This communication consists of requests **to the binary** via the `stdin` pipe and responses **from the binary** via the `stdout` pipe. Currently the `stderr` pipe is only used for debugging purposes.
40+
41+
The nature of this way of communication imposes some quirks:
42+
* All request messages are marked with an unique identifier which is also present in the response messages. This way the `Node.js` layer can distinguish between different messages and match a request with it's response counterpart
43+
* All messages are printed in binary on the `stdout` (and the `stderr`) pipe. Each message is prefixed with a 4 byte header, containing the length of the succeeding message. These 4-byte prefixes appear as peculiar symbols in the console whenever one decides to launch the binary directly. This is necessary as the messages have variable length and in addition it alleviates printing from the `C++` code as the strings we want to print might contain `NULL` characters which would otherwise terminate printing.
44+
3645
API Reference
3746
==
38-
This section contains information about each public method.
47+
In order to use the application directly one can either launch the binary, either directly or from within an IDE, or use the JavaScript API. Whenever using this library **make sure that there is at least one actual iOS device attached to the system**. This library has no functionality whatsoever without actual devices.
48+
49+
## C++ Binary
50+
Upon launching the binary it will report all devices currently attached in the following form:
51+
```
52+
{
53+
"deviceColor": "1",
54+
"deviceId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
55+
"deviceName": "iPhone",
56+
"event": "deviceFound",
57+
"productType": "iPhone9,4",
58+
"productVersion": "11.0.3",
59+
"status": "Connected"
60+
}
61+
```
62+
63+
After that the binary is ready to accept requests via its standart input. Currently each passed message **must be on one line**, ending with a new line (Enter key) in order for it to be parsed correctly. Each message contains the **name** of the method, which you'd like to invoke, an **identification string** and the **method's arguments**. Messages are processed asynchronously, hence multiple messages can be passed at once. Example messages for the different opperations can be found below:
64+
65+
### List applications
66+
{
67+
"methods": [
68+
{
69+
"id": "1",
70+
"name": "apps",
71+
"args": [
72+
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
73+
"yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
74+
]
75+
}
76+
]
77+
}
78+
79+
### Install application
80+
{
81+
"methods": [
82+
{
83+
"id": "2",
84+
"name": "install",
85+
"args": [
86+
"C:\\\apps\\\app.ipa",
87+
[
88+
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
89+
"yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
90+
]
91+
]
92+
}
93+
]
94+
}
95+
96+
### Uninstall application
97+
{
98+
"methods": [
99+
{
100+
"id": "3",
101+
"name": "uninstall",
102+
"args": [
103+
"com.sample.MyApp",
104+
[
105+
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
106+
"yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
107+
]
108+
]
109+
}
110+
]
111+
}
112+
113+
### List files in an application
114+
{
115+
"methods": [
116+
{
117+
"id": "4",
118+
"name": "list",
119+
"args": [
120+
{
121+
"appId": "com.sample.MyApp",
122+
"deviceId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
123+
"path": "Library\\\Application Support
124+
}
125+
]
126+
}
127+
]
128+
}
129+
130+
### Upload a file from the local file system to the device
131+
{
132+
"methods": [
133+
{
134+
"id": "5",
135+
"name": "upload",
136+
"args": [
137+
{
138+
"appId": "com.sample.MyApp",
139+
"deviceId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
140+
"source": "D:\\\Project\\\app.js",
141+
"destination": "Library\\\Application Support\\\LiveSync\\\app\\\app.js"
142+
}
143+
]
144+
}
145+
]
146+
}
147+
148+
### Delete a file from the device
149+
{
150+
"methods": [
151+
{
152+
"id": "6",
153+
"name": "delete",
154+
"args": [
155+
{
156+
"appId": "com.sample.MyApp",
157+
"deviceId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
158+
"destination": "Library\\\Application Support\\\LiveSync\\\app\\\app.js"
159+
}
160+
]
161+
}
162+
]
163+
}
164+
165+
### Retrieve the contents of a file from the device
166+
{
167+
"methods": [
168+
{
169+
"id": "7",
170+
"name": "read",
171+
"args": [
172+
{
173+
"appId": "com.sample.MyApp",
174+
"deviceId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
175+
"path": "Library\\\Application Support\\\LiveSync\\\app\\\app.js"
176+
}
177+
]
178+
}
179+
]
180+
}
181+
182+
### Download a file from the device to the local system
183+
{
184+
"methods": [
185+
{
186+
"id": "8",
187+
"name": "download",
188+
"args": [
189+
{
190+
"appId": "com.sample.MyApp",
191+
"deviceId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
192+
"source": "Library\\\Application Support\\\LiveSync\\\app\\\app.js",
193+
"destination": "D:\\\Downloads\\\app.js"
194+
}
195+
]
196+
}
197+
]
198+
}
199+
200+
### Start printing the device log for a device
201+
{
202+
"methods": [
203+
{
204+
"id": "9",
205+
"name": "log",
206+
"args": [
207+
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
208+
]
209+
}
210+
]
211+
}
212+
213+
### Post a notification to a device. (As if ot was dispatched via NSNotificationCenter). This call is non-blocking.
214+
#### Post
215+
{
216+
"methods": [
217+
{
218+
"id": "10",
219+
"name": "postNotification",
220+
"args": [
221+
{
222+
"deviceId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
223+
"commandType": "PostNotification",
224+
"notificationName": "com.sample.MyApp:NativeScript.Debug.AttachAvailabilityQuery"
225+
}
226+
]
227+
}
228+
]
229+
}
230+
231+
#### Observe
232+
{
233+
"methods": [
234+
{
235+
"id": "11",
236+
"name": "postNotification",
237+
"args": [
238+
{
239+
"deviceId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
240+
"commandType": "ObserveNotification",
241+
"notificationName": "com.sample.MyApp:NativeScript.Debug.AttachAvailable"
242+
}
243+
]
244+
}
245+
]
246+
}
247+
248+
### Post a notification to a device and await its response. This call is blocking.
249+
{
250+
"methods": [
251+
{
252+
"id": "12",
253+
"name": "awaitNotificationResponse",
254+
"args": [
255+
{
256+
"deviceId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
257+
"socket": 10,
258+
"timeout": 9,
259+
"responseCommandType": "RelayNotification",
260+
"responsePropertyName": "Name"
261+
}
262+
]
263+
}
264+
]
265+
}
266+
267+
### Start an application.
268+
{
269+
"methods": [
270+
{
271+
"id": "13",
272+
"name": "start",
273+
"args": [
274+
{
275+
"appId": "com.sample.MyApp",
276+
"deviceId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
277+
}
278+
]
279+
}
280+
]
281+
}
282+
283+
### Stop a running application.
284+
{
285+
"methods": [
286+
{
287+
"id": "14",
288+
"name": "stop",
289+
"args": [
290+
{
291+
"appId": "com.sample.MyApp",
292+
"deviceId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
293+
}
294+
]
295+
}
296+
]
297+
}
298+
299+
## JavaScript interface
300+
A detailed definition of all the methods can be found [here](https://github.com/telerik/ios-device-lib/blob/master/typings/interfaces.d.ts#L127)
301+
302+
Additional information
303+
==
304+
* Upon launching the `ios-device-lib` binary it will immediately start a detached thread with a run loop so that it can proactively detect attaching and detaching of devices.
305+
* All requests to the binary are executed in separate threads
306+
* **Error understanding:** Whenever an error is raised, for example:
307+
```
308+
{
309+
"deviceId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
310+
"error": {
311+
"code": -402653081,
312+
"deviceId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
313+
"message": "Could not install application"
314+
},
315+
"id": "1"
316+
}
317+
```
318+
How does one go about deciphering the error code?
39319

320+
First off you'd need to convert the code to hex (this can easily be done with a calculator application for example). So `-402653081` becomes `FFFFFFFFE8000067` or `E8000067` if we disregard the sign. Using this hex code you can look the error up in [this](https://github.com/samdmarshall/SDMMobileDevice/blob/master/Framework/include/SDMMobileDevice/SDMMD_Error.h) header file. In this example we can see that this is a `kAMDAPIInternalError`, hence an internal error.

0 commit comments

Comments
 (0)