skip to Main Content

right now i am using method channel for fetch IOS device name in flutter, that a user given by in the about section. it is perfectly working in below IOS version 16 ipad’s only. But i need to work this also above IOS version 16+ ipad’s.

this is how I read the device name using method channel in flutter.

Swift code written for fetch iPad device name

import UIKit
import Flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {

    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        // Register Flutter plugins
        GeneratedPluginRegistrant.register(with: self)

        // Set up a platform channel to fetch device name
        let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
        let deviceInfoChannel = FlutterMethodChannel(name: "device_info", binaryMessenger: controller.binaryMessenger)
        deviceInfoChannel.setMethodCallHandler({
            [weak self] (call: FlutterMethodCall, result: FlutterResult) -> Void in
            guard call.method == "getDeviceName" else {
                result(FlutterMethodNotImplemented)
                return
            }
            let deviceName = self?.getCustomDeviceName()
            result(deviceName)
        })

        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }

    func getCustomDeviceName() -> String {
        var deviceName: String?

        // Fetch device name from UserDefaults
        if let deviceNameValue = UserDefaults.standard.string(forKey: "DeviceName") {
            deviceName = deviceNameValue
        }

        // If device name not found in UserDefaults, use the default device name
        if deviceName == nil || deviceName!.isEmpty {
            deviceName = UIDevice.current.name
        }

        return deviceName!
    }
}

This is the Flutter code for fetch iPad device name

import 'dart:async';
import 'dart:developer';
import 'dart:io' show Platform;
import 'package:device_id/service/device_name_finder.dart';
import 'package:flutter/material.dart';

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  var actualDeviceName = '';

  @override
  void initState() {
    super.initState();
    findDeviceName();
    // readIos();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Center(
          child: Padding(
            padding: const EdgeInsets.all(12.0),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.center,
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text(
                  'Device Name : $actualDeviceName',
                  textAlign: TextAlign.center,
                ),
                const SizedBox(
                  height: 20,
                ),
                ElevatedButton(
                  onPressed: () {
                    setState(() {
                      findDeviceName();
                    });
                  },
                  child: const Text('Check Device'),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  Future<void> findDeviceName() async {
    if (Platform.isAndroid) {
      actualDeviceName = (await AndroidDeviceInformation.getDeviceName())!;
      setState(() {});
      log("The Device name is $actualDeviceName");
    } else if (Platform.isIOS) {
      actualDeviceName = (await IosDeviceInformation.getDeviceName())!;
      setState(() {});
      log("The Device name is $actualDeviceName");
    }
  }
}

Also I created a separate class for manage the method channel

import 'package:flutter/services.dart';

class IosDeviceInformation {
  static const MethodChannel _channel = MethodChannel('device_info');

  static Future<String?> getDeviceName() async {
    try {
      return await _channel.invokeMethod('getDeviceName');
    } on PlatformException catch (e) {
      print("Failed to get device name: '${e.message}'.");
      return null;
    }
  }
}

class AndroidDeviceInformation {
  static const MethodChannel _channel = MethodChannel('android_device_info');

  static Future<String?> getDeviceName() async {
    try {
      return await _channel.invokeMethod('getDeviceName');
    } on PlatformException catch (e) {
      print("Failed to get device name: '${e.message}'.");
      return null;
    }
  }
}

How i can working this solution on 16+ iPad devices?

2

Answers


  1. In iOS 16 and later, the actual device name is not available without a special entitlement from Apple. This is for privacy reasons. If you meet all of the requirements then you can apply for the entitlement.

    Without this entitlement you will get a generic value such as "iPad". If you have the entitlement then you will get the actual device name as you did on earlier versions of iOS.

    Login or Signup to reply.
  2. DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
    
    
     IosDeviceInfo iosInfo = await deviceInfo.iosInfo;
      print('Running on ${iosInfo.systemName}');
    

    first add device_info_plus in pubsec.yml

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search