19
19
import BaseHTTPServer
20
20
import webbrowser
21
21
import threading
22
+ import subprocess
23
+ import re
22
24
23
25
class CCPluginRun (cocos .CCPlugin ):
24
26
"""
@@ -67,14 +69,113 @@ def _check_custom_options(self, args):
67
69
def get_ios_sim_name (self ):
68
70
# get the version of xcodebuild
69
71
ver = cocos .get_xcode_version ()
72
+ match = re .match (r'(\d+).*' , ver )
73
+ ret = None
74
+ if match :
75
+ ver_num = int (match .group (1 ))
76
+ if ver_num <= 5 :
77
+ ret = "ios-sim-xcode5"
78
+ elif ver_num < 8 :
79
+ ret = "ios-sim-xcode6"
70
80
71
- if ver .startswith ("5" ):
72
- ret = "ios-sim-xcode5"
73
- else :
74
- ret = "ios-sim-xcode6"
81
+ return ret
75
82
83
+ def _get_cmd_output (self , cmds ):
84
+ child = subprocess .Popen (cmds , stdout = subprocess .PIPE )
85
+ out = child .stdout .read ()
86
+ child .wait ()
87
+ errCode = child .returncode
88
+
89
+ return (errCode , out )
90
+
91
+ def _get_simulator_id (self ):
92
+ (errCode , out ) = self ._get_cmd_output ([ "xcrun" , "instruments" , "-s" ])
93
+ names = []
94
+ if errCode == 0 :
95
+ pattern = r'(^iPhone[^\[]+)\[(.*)\]\s*\(Simulator\)'
96
+ lines = out .split ('\n ' )
97
+ for line in lines :
98
+ match = re .match (pattern , line )
99
+ if match :
100
+ info = {
101
+ "name" : match .group (1 ),
102
+ 'id' : match .group (2 )
103
+ }
104
+ names .append (info )
105
+
106
+ ret = None
107
+ retName = None
108
+ phoneTypeNum = 0
109
+ phoneType = ''
110
+ iosVer = 0
111
+ if len (names ) > 0 :
112
+ name_pattern = r'iPhone\s+((\d+)[^\(]+)\((.*)\)'
113
+ for info in names :
114
+ name = info ["name" ]
115
+ id = info ["id" ]
116
+ if name .find ('Apple Watch' ) > 0 :
117
+ continue
118
+
119
+ match = re .match (name_pattern , name )
120
+ if match :
121
+ # get the matched data
122
+ typeNum = int (match .group (2 ))
123
+ tmpType = match .group (1 )
124
+ tmpIOSVer = float (match .group (3 ))
125
+
126
+ if ((typeNum > phoneTypeNum ) or
127
+ (typeNum == phoneTypeNum and tmpType > phoneType ) or
128
+ (typeNum == phoneTypeNum and tmpType == phoneType and tmpIOSVer > iosVer )):
129
+ # find the max phone type number first
130
+ ret = id
131
+ retName = name .strip ()
132
+ phoneTypeNum = typeNum
133
+ phoneType = tmpType
134
+ iosVer = tmpIOSVer
135
+
136
+ if ret is None :
137
+ raise cocos .CCPluginError ('Get simulator failed!' )
138
+
139
+ print ('Using simulator: %s' % retName )
76
140
return ret
77
141
142
+ def _get_bundle_id (self , app_path ):
143
+ plistFile = os .path .join (app_path , 'Info.plist' )
144
+ (errCode , out ) = self ._get_cmd_output ([ 'plutil' , '-convert' , 'json' , '-o' , '-' , plistFile ])
145
+ ret = None
146
+ if errCode == 0 :
147
+ import json
148
+ jsonObj = json .loads (out )
149
+ if jsonObj is not None and jsonObj .has_key ('CFBundleIdentifier' ):
150
+ ret = jsonObj ['CFBundleIdentifier' ]
151
+
152
+ if ret is None :
153
+ raise cocos .CCPluginError ('Get the bundle ID of app %s failed' % app_path )
154
+
155
+ return ret
156
+
157
+ def _run_ios_app (self , ios_app_path ):
158
+ if not cocos .os_is_mac ():
159
+ raise cocos .CCPluginError ('Now only support run iOS simulator on Mac OS' )
160
+
161
+ # get bundle id
162
+ bundle_id = self ._get_bundle_id (ios_app_path )
163
+
164
+ # find simulator
165
+ simulator_id = self ._get_simulator_id ()
166
+
167
+ try :
168
+ # run the simulator
169
+ self ._run_cmd ('xcrun instruments -w "%s"' % simulator_id )
170
+ except Exception as e :
171
+ pass
172
+
173
+ # install app
174
+ self ._run_cmd ('xcrun simctl install "%s" "%s"' % (simulator_id , ios_app_path ))
175
+
176
+ # run app
177
+ self ._run_cmd ('xcrun simctl launch "%s" "%s"' % (simulator_id , bundle_id ))
178
+
78
179
def run_ios_sim (self , dependencies ):
79
180
if not self ._platforms .is_ios_active ():
80
181
return
@@ -84,13 +185,19 @@ def run_ios_sim(self, dependencies):
84
185
cocos .Logging .warning (MultiLanguage .get_string ('RUN_WARNING_IOS_FOR_DEVICE_FMT' ,
85
186
os .path .dirname (deploy_dep ._iosapp_path )))
86
187
else :
87
- if getattr (sys , 'frozen' , None ):
88
- cur_dir = os .path .realpath (os .path .dirname (sys .executable ))
188
+ ios_sim_name = self .get_ios_sim_name ()
189
+ if ios_sim_name is None :
190
+ # there is not a ios-sim for current installed xcode
191
+ # try to use xcrun commands
192
+ self ._run_ios_app (deploy_dep ._iosapp_path )
89
193
else :
90
- cur_dir = os .path .realpath (os .path .dirname (__file__ ))
91
- iossim_exe_path = os .path .join (cur_dir , 'bin' , self .get_ios_sim_name ())
92
- launch_sim = "%s launch \" %s\" &" % (iossim_exe_path , deploy_dep ._iosapp_path )
93
- self ._run_cmd (launch_sim )
194
+ if getattr (sys , 'frozen' , None ):
195
+ cur_dir = os .path .realpath (os .path .dirname (sys .executable ))
196
+ else :
197
+ cur_dir = os .path .realpath (os .path .dirname (__file__ ))
198
+ iossim_exe_path = os .path .join (cur_dir , 'bin' , ios_sim_name )
199
+ launch_sim = "%s launch \" %s\" &" % (iossim_exe_path , deploy_dep ._iosapp_path )
200
+ self ._run_cmd (launch_sim )
94
201
95
202
def _run_with_desktop_options (self , cmd ):
96
203
if self ._no_console :
0 commit comments