forked from tidev/node-ios-device
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ios-device.js
155 lines (132 loc) · 3.79 KB
/
ios-device.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/**
* Public API for the node-ios-device library.
*
* @module ios-device
*
* @copyright
* Copyright (c) 2012-2016 by Appcelerator, Inc. All Rights Reserved.
*
* @license
* Licensed under the terms of the Apache Public License
* Please see the LICENSE included with this distribution for details.
*/
'use strict';
var binary = require('node-pre-gyp');
var exec = require('child_process').exec;
var fs = require('fs');
var path = require('path');
var binding = require(binary.find(path.resolve(__dirname, './package.json')));
var platformErrorMsg = 'OS "' + process.platform + '" not supported';
// reference counter to track how many trackDevice() calls are active
var pumping = 0;
var timer;
module.exports.pumpInterval = 10;
module.exports.devices = devices;
module.exports.trackDevices = trackDevices;
module.exports.installApp = installApp;
module.exports.log = log;
/**
* Retrieves an array of all connected iOS devices.
*
* @param {Function} callback(err, devices) - A function to call with the connected devices.
*/
function devices(callback) {
if (process.platform !== 'darwin') {
return callback(new Error(platformErrorMsg));
}
binding.pumpRunLoop();
callback(null, binding.devices());
}
/**
* Continuously retrieves an array of all connected iOS devices. Whenever a
* device is connected or disconnected, the specified callback is fired.
*
* @param {Function} callback(err, devices) - A function to call with the connected devices.
* @returns {Function} off() - A function that discontinues tracking.
*/
function trackDevices(callback) {
if (process.platform !== 'darwin') {
return callback(new Error(platformErrorMsg));
}
// if we're not already pumping, start up the pumper
if (!pumping) {
pump();
}
pumping++;
// immediately return the array of devices
exports.devices(callback);
var stopped = false;
// listen for any device connects or disconnects
binding.on('devicesChanged', function (devices) {
stopped || callback(null, binding.devices());
});
// return the stop() function
return function () {
if (!stopped) {
stopped = true;
pumping = Math.max(pumping - 1, 0);
pumping || clearTimeout(timer);
}
};
}
/**
* Installs an iOS app on the specified device.
*
* @param {String} udid - The device udid to install the app to.
* @param {String} appPath - The path to iOS .app directory to install.
* @param {Function} callback(err) - A function to call when the install finishes.
*/
function installApp(udid, appPath, callback) {
if (process.platform !== 'darwin') {
return callback(new Error(platformErrorMsg));
}
appPath = path.resolve(appPath);
if (!fs.existsSync(appPath)) {
return callback(new Error('Specified .app path does not exist'));
}
if (!fs.statSync(appPath).isDirectory() || !fs.existsSync(path.join(appPath, 'PkgInfo'))) {
return callback(new Error('Specified .app path is not a valid app'));
}
binding.pumpRunLoop();
try {
binding.installApp(udid, appPath);
callback(null);
} catch (ex) {
callback(ex);
}
}
/**
* Forwards the specified iOS device's log messages.
*
* @param {String} udid - The device udid to forward log messages.
* @param {Function} callback(err) - A function to call with each log message.
*/
function log(udid, callback) {
if (process.platform !== 'darwin') {
return callback(new Error(platformErrorMsg));
}
// if we're not already pumping, start up the pumper
if (!pumping) {
pump();
}
pumping++;
var stopped = false;
binding.log(udid, function (msg) {
stopped || callback(msg);
});
// return the off() function
return function () {
if (!stopped) {
stopped = true;
pumping = Math.max(pumping - 1, 0);
pumping || clearTimeout(timer);
}
};
}
/**
* Ticks the CoreFoundation run loop.
*/
function pump() {
binding.pumpRunLoop();
timer = setTimeout(pump, exports.pumpInterval);
}