Doesn't detect Platform.operatingSystem: iOS [web]
tomasbaran opened this issue · 2 comments
I LOVE your package and need it very much BUT the package from 0.5.0 above somehow cannot detect iOS. The package thinks iPhone and iPad (your package never detected iPad as iOS but as macOS instead) are macOS instead of iOS. Can you please fix it?
Live Demo
You can check the latest version where at least iPhone was detected as iOS which is 0.4.0 here: https://experiment0.web.app/#/: as you can see iPad is still incorrectly detected as macos.
Results in various devices
Safari on iPad mini 2 (iOS 12) universal_io: 0.2.0+ (basically all versions) : I couldn't test versions below 0.2.0 since they were not compatible with Flutter 1.19
Google Chrome on iPhone XR (iOS 13.5) universal_io: 0.5.0-1.0.1 :
**Safari on iPhone XR (iOS 13.5) universal_io: 0.5.0-
1.0.1 :** (same thing on iPhone 5S (iOS12)
The package detects following OS:
- macOS: as macOS
- iPad: as macOS
- iPhone (0.5.0+): as macOS
- windows: as windows
- android: as android
Min repro code
Just use the default counter flutter app and add Platform.operatingSystem
like this:
import 'package:flutter/material.dart';
import 'package:universal_io/io.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
// This makes the visual density adapt to the platform that you run
// the app on. For desktop platforms, the controls will be smaller and
// closer together (more dense) than on mobile platforms.
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
// This call to setState tells the Flutter framework that something has
// changed in this State, which causes it to rerun the build method below
// so that the display can reflect the updated values. If we changed
// _counter without calling setState(), then the build method would not be
// called again, and so nothing would appear to happen.
_counter++;
});
}
@override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text('Platform: ${Platform.operatingSystem}'),
),
body: Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: Column(
// Column is also a layout widget. It takes a list of children and
// arranges them vertically. By default, it sizes itself to fit its
// children horizontally, and tries to be as tall as its parent.
//
// Invoke "debug painting" (press "p" in the console, choose the
// "Toggle Debug Paint" action from the Flutter Inspector in Android
// Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
// to see the wireframe for each widget.
//
// Column has various properties to control how it sizes itself and
// how it positions its children. Here we use mainAxisAlignment to
// center the children vertically; the main axis here is the vertical
// axis because Columns are vertical (the cross axis would be
// horizontal).
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
flutter doctor -v
[✓] Flutter (Channel beta, 1.19.0-4.1.pre, on Mac OS X 10.13.6 17G65, locale en-SK)
• Flutter version 1.19.0-4.1.pre at /Users/tomas/code/flutter
• Framework revision f994b76974 (4 weeks ago), 2020-06-09 15:53:13 -0700
• Engine revision 9a28c3bcf4
• Dart version 2.9.0 (build 2.9.0-14.1.beta)
[✗] Android toolchain - develop for Android devices
✗ Unable to locate Android SDK.
Install Android Studio from: https://developer.android.com/studio/index.html
On first launch it will assist you in installing the Android SDK components.
(or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions).
If the Android SDK has been installed to a custom location, set ANDROID_SDK_ROOT to that location.
You may also want to add it to your PATH environment variable.
[✗] Xcode - develop for iOS and macOS
✗ Xcode installation is incomplete; a full installation is necessary for iOS development.
Download at: https://developer.apple.com/xcode/download/
Or install Xcode via the App Store.
Once installed, run:
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
sudo xcodebuild -runFirstLaunch
✗ CocoaPods not installed.
CocoaPods is used to retrieve the iOS and macOS platform side's plugin code that responds to your plugin usage on the
Dart side.
Without CocoaPods, plugins will not work on iOS or macOS.
For more info, see https://flutter.dev/platform-plugins
To install:
sudo gem install cocoapods
[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[!] Android Studio (not installed)
• Android Studio not found; download from https://developer.android.com/studio/index.html
(or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions).
[✓] VS Code (version 1.46.1)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.12.1
[✓] Connected device (2 available)
• Web Server • web-server • web-javascript • Flutter Tools
• Chrome • chrome • web-javascript • Google Chrome 83.0.4103.116
! Doctor found issues in 3 categories.
A quick fix for basic linux & ios detection would be to change the function _operatingSystemFromUserAgent in this file:
https://github.com/dint-dev/universal_io/blob/master/packages/universal_io/lib/src/driver/default_impl_browser.dart
to this:
String _operatingSystemFromUserAgent(String userAgent) {
final userAgent = html.window.navigator.userAgent.toLowerCase();
if (userAgent.contains('iphone') ||
userAgent.contains('ipad') ||
userAgent.contains('ipod')) {
return 'ios';
}
if (userAgent.contains('mac os x')) {
return 'macos';
}
if (userAgent.contains('android')) {
return 'android';
}
if (userAgent.contains('linux')) {
return 'linux';
}
return 'windows';
}
Hi! Thanks for the issue reports. We don't have test automation for this, but this should be fixed in 2.0.3. If the issue persists,
please file a new issue.