Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
477530f3
Commit
477530f3
authored
Jan 19, 2016
by
Chinmay Garde
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1249 from chinmaygarde/master
First take on `flutter start` for iOS devices
parents
32078052
c8672a40
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
165 additions
and
71 deletions
+165
-71
application_package.dart
packages/flutter_tools/lib/src/application_package.dart
+5
-7
start.dart
packages/flutter_tools/lib/src/commands/start.dart
+24
-15
device.dart
packages/flutter_tools/lib/src/device.dart
+124
-49
flutter_command_runner.dart
.../flutter_tools/lib/src/runner/flutter_command_runner.dart
+12
-0
No files found.
packages/flutter_tools/lib/src/application_package.dart
View file @
477530f3
...
...
@@ -47,11 +47,11 @@ class AndroidApk extends ApplicationPackage {
}
class
IOSApp
extends
ApplicationPackage
{
static
const
String
_default
Name
=
'SkyShell.app
'
;
static
const
String
_default
Id
=
'com.google.SkyShell
'
;
static
const
String
_default
Id
=
'io.flutter.runner.Runner
'
;
static
const
String
_default
Path
=
'ios
'
;
IOSApp
({
String
localPath
,
String
localPath
:
_defaultPath
,
String
id:
_defaultId
})
:
super
(
localPath:
localPath
,
id:
id
);
}
...
...
@@ -98,14 +98,12 @@ class ApplicationPackageStore {
case
TargetPlatform
.
iOS
:
assert
(
iOS
==
null
);
assert
(
config
.
type
!=
BuildType
.
prebuilt
);
iOS
=
new
IOSApp
(
localPath:
path
.
join
(
config
.
buildDir
,
IOSApp
.
_defaultName
));
iOS
=
new
IOSApp
();
break
;
case
TargetPlatform
.
iOSSimulator
:
assert
(
iOSSimulator
==
null
);
assert
(
config
.
type
!=
BuildType
.
prebuilt
);
iOSSimulator
=
new
IOSApp
(
localPath:
path
.
join
(
config
.
buildDir
,
IOSApp
.
_defaultName
));
iOSSimulator
=
new
IOSApp
();
break
;
case
TargetPlatform
.
mac
:
...
...
packages/flutter_tools/lib/src/commands/start.dart
View file @
477530f3
...
...
@@ -9,6 +9,7 @@ import 'package:path/path.dart' as path;
import
'../application_package.dart'
;
import
'../base/logging.dart'
;
import
'../build_configuration.dart'
;
import
'../device.dart'
;
import
'../runner/flutter_command.dart'
;
import
'build.dart'
;
...
...
@@ -84,22 +85,30 @@ abstract class StartCommandBase extends FlutterCommand {
continue
;
logging
.
fine
(
'Running build command for
$device
.'
);
BuildCommand
builder
=
new
BuildCommand
();
builder
.
inheritFromParent
(
this
);
await
builder
.
buildInTempDir
(
mainPath:
mainPath
,
onBundleAvailable:
(
String
localBundlePath
)
{
logging
.
fine
(
'Starting bundle for
$device
.'
);
final
AndroidDevice
androidDevice
=
device
;
// https://github.com/flutter/flutter/issues/1035
if
(
androidDevice
.
startBundle
(
package
,
localBundlePath
,
poke:
poke
,
checked:
argResults
[
'checked'
],
traceStartup:
argResults
[
'trace-startup'
],
route:
argResults
[
'route'
],
clearLogs:
clearLogs
))
startedSomething
=
true
;
if
(
device
.
platform
==
TargetPlatform
.
android
)
{
BuildCommand
builder
=
new
BuildCommand
();
builder
.
inheritFromParent
(
this
);
await
builder
.
buildInTempDir
(
mainPath:
mainPath
,
onBundleAvailable:
(
String
localBundlePath
)
{
logging
.
fine
(
'Starting bundle for
$device
.'
);
final
AndroidDevice
androidDevice
=
device
;
// https://github.com/flutter/flutter/issues/1035
if
(
androidDevice
.
startBundle
(
package
,
localBundlePath
,
poke:
poke
,
checked:
argResults
[
'checked'
],
traceStartup:
argResults
[
'trace-startup'
],
route:
argResults
[
'route'
],
clearLogs:
clearLogs
))
startedSomething
=
true
;
}
);
}
else
{
bool
result
=
await
device
.
startApp
(
package
);
if
(!
result
)
{
logging
.
severe
(
'Could not start
\'
${package.name}
\'
on
\'
${device.id}
\'
'
);
}
);
}
}
if
(!
startedSomething
)
{
...
...
packages/flutter_tools/lib/src/device.dart
View file @
477530f3
...
...
@@ -95,8 +95,7 @@ class IOSDevice extends Device {
'To copy files to iOS devices, please install ios-deploy. '
'You can do this using homebrew as follows:
\n
'
'
\$
brew tap flutter/flutter
\n
'
'
\$
brew install ios-deploy'
,
'Copying files to iOS devices is not currently supported on Linux.'
);
'
\$
brew install ios-deploy'
);
}
static
List
<
IOSDevice
>
getAttachedDevices
([
IOSDevice
mockIOS
])
{
...
...
@@ -178,7 +177,7 @@ class IOSDevice extends Device {
@override
bool
isAppInstalled
(
ApplicationPackage
app
)
{
try
{
String
apps
=
runCheckedSync
([
installerPath
,
'-
l
'
]);
String
apps
=
runCheckedSync
([
installerPath
,
'-
-list-apps
'
]);
if
(
new
RegExp
(
app
.
id
,
multiLine:
true
).
hasMatch
(
apps
))
{
return
true
;
}
...
...
@@ -190,22 +189,42 @@ class IOSDevice extends Device {
@override
Future
<
bool
>
startApp
(
ApplicationPackage
app
)
async
{
if
(!
isAppInstalled
(
app
))
{
logging
.
fine
(
"Attempting to build and install
${app.name}
on
$id
"
);
// Step 1: Install the precompiled application if necessary
bool
buildResult
=
await
_buildIOSXcodeProject
(
app
,
true
);
if
(!
buildResult
)
{
logging
.
severe
(
'Could not build the precompiled application for the device'
);
return
false
;
}
// idevicedebug hangs forever after launching the app, so kill it after
// giving it plenty of time to send the launch command.
return
await
runAndKill
(
[
debuggerPath
,
'run'
,
app
.
id
],
new
Duration
(
seconds:
3
)
).
then
(
(
_
)
{
return
true
;
},
onError:
(
e
)
{
logging
.
info
(
'Failure running
$debuggerPath
: '
,
e
);
return
false
;
}
);
// Step 2: Check that the application exists at the specified path
Directory
bundle
=
new
Directory
(
path
.
join
(
app
.
localPath
,
'build'
,
'Release-iphoneos'
,
'Runner.app'
));
bool
bundleExists
=
await
bundle
.
exists
();
if
(!
bundleExists
)
{
logging
.
severe
(
'Could not find the built application bundle at
${bundle.path}
'
);
return
false
;
}
// Step 3: Attempt to install the application on the device
int
installationResult
=
await
runCommandAndStreamOutput
([
'/usr/bin/env'
,
'ios-deploy'
,
'--id'
,
id
,
'--bundle'
,
bundle
.
path
,
]);
if
(
installationResult
!=
0
)
{
logging
.
severe
(
'Could not install
${bundle.path}
on
$id
'
);
return
false
;
}
logging
.
fine
(
'Installation successful'
);
return
true
;
}
@override
...
...
@@ -230,11 +249,6 @@ class IOSDevice extends Device {
]);
return
true
;
}
else
{
// TODO(iansf): It may be possible to make this work on Linux. Since this
// functionality appears to be the only that prevents us from
// supporting iOS on Linux, it may be worth putting some time
// into investigating this.
// See https://bbs.archlinux.org/viewtopic.php?id=192655
return
false
;
}
return
false
;
...
...
@@ -337,8 +351,6 @@ class IOSSimulator extends Device {
List
<
IOSSimulator
>
devices
=
[];
String
id
=
_getRunningSimulatorID
(
mockIOS
);
if
(
id
!=
null
)
{
// TODO(iansf): get the simulator's name
// String name = _getDeviceName(id, mockIOS);
devices
.
add
(
new
IOSSimulator
(
id:
id
));
}
return
devices
;
...
...
@@ -421,20 +433,53 @@ class IOSSimulator extends Device {
@override
Future
<
bool
>
startApp
(
ApplicationPackage
app
)
async
{
if
(!
isAppInstalled
(
app
))
{
logging
.
fine
(
'Building
${app.name}
for
$id
'
);
// Step 1: Build the Xcode project
bool
buildResult
=
await
_buildIOSXcodeProject
(
app
,
false
);
if
(!
buildResult
)
{
logging
.
severe
(
'Could not build the application for the simulator'
);
return
false
;
}
try
{
if
(
id
==
defaultDeviceID
)
{
runCheckedSync
(
[
xcrunPath
,
'simctl'
,
'launch'
,
'booted'
,
app
.
id
]);
}
else
{
runCheckedSync
([
xcrunPath
,
'simctl'
,
'launch'
,
id
,
app
.
id
]);
}
return
true
;
}
catch
(
e
)
{
// Step 2: Assert that the Xcode project was successfully built
Directory
bundle
=
new
Directory
(
path
.
join
(
app
.
localPath
,
'build'
,
'Release-iphonesimulator'
,
'Runner.app'
));
bool
bundleExists
=
await
bundle
.
exists
();
if
(!
bundleExists
)
{
logging
.
severe
(
'Could not find the built application bundle at
${bundle.path}
'
);
return
false
;
}
// Step 3: Install the updated bundle to the simulator
int
installResult
=
await
runCommandAndStreamOutput
([
xcrunPath
,
'simctl'
,
'install'
,
id
==
defaultDeviceID
?
'booted'
:
id
,
path
.
absolute
(
bundle
.
path
)
]);
if
(
installResult
!=
0
)
{
logging
.
severe
(
'Could not install the application bundle on the simulator'
);
return
false
;
}
// Step 4: Launch the updated application in the simulator
int
launchResult
=
await
runCommandAndStreamOutput
([
xcrunPath
,
'simctl'
,
'launch'
,
id
==
defaultDeviceID
?
'booted'
:
id
,
app
.
id
]);
if
(
launchResult
!=
0
)
{
logging
.
severe
(
'Could not launch the freshly installed application on the simulator'
);
return
false
;
}
logging
.
fine
(
'Successfully started
${app.name}
on
$id
'
);
return
true
;
}
@override
...
...
@@ -973,6 +1018,30 @@ class DeviceStore {
this
.
iOSSimulator
});
static
Device
_deviceForConfig
(
BuildConfiguration
config
,
List
<
Device
>
devices
)
{
Device
device
=
null
;
if
(
config
.
deviceId
!=
null
)
{
// Step 1: If a device identifier is specified, try to find a device
// matching that specific identifier
device
=
devices
.
firstWhere
(
(
Device
dev
)
=>
(
dev
.
id
==
config
.
deviceId
),
orElse:
()
=>
null
);
if
(
device
==
null
)
{
logging
.
severe
(
'Warning: Device ID
${config.deviceId}
not found'
);
}
}
else
if
(
devices
.
length
==
1
)
{
// Step 2: If no identifier is specified and there is only one connected
// device, pick that one.
device
=
devices
[
0
];
}
else
if
(
devices
.
length
>
1
)
{
// Step 3: D:
logging
.
severe
(
'Warning: Multiple devices are connected, but no device ID was specified.'
);
}
return
device
;
}
factory
DeviceStore
.
forConfigs
(
List
<
BuildConfiguration
>
configs
)
{
AndroidDevice
android
;
IOSDevice
iOS
;
...
...
@@ -982,27 +1051,19 @@ class DeviceStore {
switch
(
config
.
targetPlatform
)
{
case
TargetPlatform
.
android
:
assert
(
android
==
null
);
List
<
AndroidDevice
>
androidDevices
=
AndroidDevice
.
getAttachedDevices
();
if
(
config
.
deviceId
!=
null
)
{
android
=
androidDevices
.
firstWhere
(
(
AndroidDevice
dev
)
=>
(
dev
.
id
==
config
.
deviceId
),
orElse:
()
=>
null
);
if
(
android
==
null
)
{
print
(
'Warning: Device ID
${config.deviceId}
not found'
);
}
}
else
if
(
androidDevices
.
length
==
1
)
{
android
=
androidDevices
[
0
];
}
else
if
(
androidDevices
.
length
>
1
)
{
print
(
'Warning: Multiple Android devices are connected, but no device ID was specified.'
);
}
android
=
_deviceForConfig
(
config
,
AndroidDevice
.
getAttachedDevices
());
break
;
case
TargetPlatform
.
iOS
:
assert
(
iOS
==
null
);
iOS
=
new
IOSDevice
(
);
iOS
=
_deviceForConfig
(
config
,
IOSDevice
.
getAttachedDevices
()
);
break
;
case
TargetPlatform
.
iOSSimulator
:
assert
(
iOSSimulator
==
null
);
iOSSimulator
=
new
IOSSimulator
();
iOSSimulator
=
_deviceForConfig
(
config
,
IOSSimulator
.
getAttachedDevices
());
if
(
iOSSimulator
==
null
)
{
// Creates a simulator with the default identifier
iOSSimulator
=
new
IOSSimulator
();
}
break
;
case
TargetPlatform
.
mac
:
case
TargetPlatform
.
linux
:
...
...
@@ -1013,3 +1074,17 @@ class DeviceStore {
return
new
DeviceStore
(
android:
android
,
iOS:
iOS
,
iOSSimulator:
iOSSimulator
);
}
}
Future
<
bool
>
_buildIOSXcodeProject
(
ApplicationPackage
app
,
bool
isDevice
)
async
{
List
<
String
>
command
=
[
'/usr/bin/env'
,
'xcrun'
,
'xcodebuild'
,
'-target'
,
'Runner'
,
'-configuration'
,
'Release'
];
if
(!
isDevice
)
{
command
.
addAll
([
'-sdk'
,
'iphonesimulator'
]);
}
int
result
=
await
runCommandAndStreamOutput
(
command
,
workingDirectory:
app
.
localPath
);
return
result
==
0
;
}
packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
View file @
477530f3
...
...
@@ -226,6 +226,18 @@ class FlutterCommandRunner extends CommandRunner {
testable:
true
));
}
if
(
hostPlatform
==
HostPlatform
.
mac
)
{
configs
.
add
(
new
BuildConfiguration
.
prebuilt
(
hostPlatform:
HostPlatform
.
mac
,
targetPlatform:
TargetPlatform
.
iOS
));
configs
.
add
(
new
BuildConfiguration
.
prebuilt
(
hostPlatform:
HostPlatform
.
mac
,
targetPlatform:
TargetPlatform
.
iOSSimulator
));
}
}
else
{
if
(!
FileSystemEntity
.
isDirectorySync
(
enginePath
))
logging
.
warning
(
'
$enginePath
is not a valid directory'
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment