Flutter Tutorial - How To Call iOS Native Code | Swift Platform Specific Code

3 min read 14 hours ago
Published on Dec 28, 2024 This response is partially generated with the help of AI. It may contain inaccuracies.

Table of Contents

Introduction

In this tutorial, you will learn how to call iOS native code from your Flutter application using Swift. This process allows you to access custom platform-specific functionalities that are not directly available in Flutter. By following these steps, you'll be able to integrate native features seamlessly into your Flutter app.

Step 1: Set Up Your Flutter Project

  • Open your terminal or command prompt.
  • Create a new Flutter project if you don't have one:
    flutter create my_flutter_app
    
  • Navigate into your project directory:
    cd my_flutter_app
    

Step 2: Configure iOS Platform Code

  • Open the iOS folder of your Flutter project in Xcode:
    open ios/Runner.xcworkspace
    
  • Locate the AppDelegate.swift file within the Xcode project.

Step 3: Implement Method Channel in Flutter

  • In your Flutter project, navigate to the lib/main.dart file.
  • Import the necessary Flutter services:
    import 'package:flutter/services.dart';
    
  • Create a Method Channel to communicate with iOS code:
    class MyApp extends StatelessWidget {
      static const platform = MethodChannel('com.example.native_code');
    
      // Add your method to invoke iOS native code
      Future<void> _callNativeCode() async {
        try {
          final String result = await platform.invokeMethod('getNativeMessage');
          print(result);
        } on PlatformException catch (e) {
          print("Failed to call native code: '${e.message}'.");
        }
      }
    }
    

Step 4: Implement Native iOS Code

  • In the AppDelegate.swift file, add the following code to handle incoming method calls:
    import UIKit
    import Flutter
    
    @UIApplicationMain
    class AppDelegate: FlutterAppDelegate {
      override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
      ) -> Bool {
        let controller = window?.rootViewController as! FlutterViewController
        let nativeChannel = FlutterMethodChannel(name: "com.example.native_code",
                                                  binaryMessenger: controller.binaryMessenger)
    
        nativeChannel.setMethodCallHandler { (call, result) in
          if call.method == "getNativeMessage" {
            result("Hello from iOS Native Code!")
          } else {
            result(FlutterMethodNotImplemented)
          }
        }
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
      }
    }
    

Step 5: Send Data to iOS Code

  • If you want to send arguments from Flutter to the iOS native code, modify the _callNativeCode method in main.dart:
    Future<void> _callNativeCodeWithArg(String message) async {
      try {
        final String result = await platform.invokeMethod('sendMessage', {"message": message});
        print(result);
      } on PlatformException catch (e) {
        print("Failed to call native code: '${e.message}'.");
      }
    }
    
  • Update the iOS code in AppDelegate.swift to handle the incoming argument:
    nativeChannel.setMethodCallHandler { (call, result) in
      if call.method == "sendMessage" {
        if let args = call.arguments as? [String: Any],
           let message = args["message"] as? String {
          print("Received message: \(message)")
          result("Message received!")
        } else {
          result(FlutterError(code: "INVALID_ARGUMENT", message: "Invalid arguments", details: nil))
        }
      }
    }
    

Conclusion

You have successfully set up a Flutter project to call iOS native code using Swift. By implementing the Method Channel, you can invoke native methods and pass arguments between Flutter and iOS. This integration opens up many possibilities for your Flutter applications, allowing you to leverage native functionalities effectively.

For further exploration, consider experimenting with different native functionalities or integrating additional plugins that utilize iOS-specific features.