Flutter 플러그 인 개발:위 챗 SDK 를 예 로 들 면

React Native 처럼 Flutter 응용 에서 제3자 라 이브 러 리 를 호출 하 는 방법 이나 일부 기능 을 원생 개발 로 제공 해 야 한다 면 Flutter Plugin 을 사용 하 는 것 이 좋 은 방법 입 니 다.본질 적 으로 Dart Package 이지 만 다른 package 와 다른 점 은...Flutter 플러그 인 에는 일반적으로 두 개의 특수 한 폴 더 가 존재 합 니 다.androidios자바,Kotlin 또는 Object-C,Swift 코드 를 작성 하려 면 이 두 폴 더 프로젝트 에서 진행 한 다음 에 해당 하 는 방법 으로 네 이 티 브 코드 에서 개발 한 방법 을 dart 에 투사 해 야 합 니 다.
본 고 는 위 챗 플러그 인 을 개발 하 는 것 을 예 로 들 어 Flutter 응용 에 위 챗 공유,로그 인,결제 등 기능 을 제공 하고 프로젝트 코드 는 아래 에서 직접 찾 을 수 있 으 며 Pub 라 이브 러 리 에 제출 되 었 습 니 다.
원본 주소:https://pantao.onmr.com/press/flutter-wechat-plugin.htmlPub라 이브 러 리:https://pub.dartlang.org/packages/wechat항목 주소:https://github.com/pantao/flutter-wechat
플러그 인 디 렉 터 리 만 들 기
플러그 인 을 개발 하려 면 아래 코드 를 사용 하여 빠 른 속도 로plugin템 플 릿 을 기반 으로 시작 할 수 있 습 니 다.
flutter create --template=plugin wechat

위의 코드 에서plugin템 플 릿 으로wechat라 는package템 플 릿 을 만 들 었 다 고 밝 혔 다.생 성 이 완 료 된 후에 전체 프로젝트 의 디 렉 터 리 구 조 는 모두 제공 되 었 고 정부 에서 기본 적 인 개발 사례 도 제공 했다.
디 렉 터 리 구조
- android // Android         
- ios // ios         
- lib // Dart     
- example //                    Flutter App
- pubspec.yaml //       
example/lib/main.dart부터
우리 의 응용 프로그램 을 개발 한 후에 먼저flutter우리 에 게 생 성 된 파일 들 을 알 아 보고example/lib/main.dart을 엽 니 다.코드 는 다음 과 같 습 니 다.
import 'package:flutter/material.dart';
import 'dart:async';

import 'package:flutter/services.dart';
import 'package:wechat/wechat.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State {
  String _platformVersion = 'Unknown';

  @override
  void initState() {
    super.initState();
    initPlatformState();
  }

  // Platform messages are asynchronous, so we initialize in an async method.
  Future initPlatformState() async {
    String platformVersion;
    // Platform messages may fail, so we use a try/catch PlatformException.
    try {
      platformVersion = await Wechat.platformVersion;
    } on PlatformException {
      platformVersion = 'Failed to get platform version.';
    }

    // If the widget was removed from the tree while the asynchronous platform
    // message was in flight, we want to discard the reply rather than calling
    // setState to update our non-existent appearance.
    if (!mounted) return;

    setState(() {
      _platformVersion = platformVersion;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
        ),
        body: Center(
          child: Text('Running on: $_platformVersion
'), ), ), ); } }

여기 서 특히 주의해 야 할 것 은initPlatformState()방법 에서Wechat.platformVersion을 호출 하 는 것 입 니 다.이 안의Wechat은 바로 우리 의 플러그 인 입 니 다.platformVersion은 플러그 인 이 제공 하 는get방법 입 니 다.이 파일 을 따라lib/wechat.dart파일 을 찾 습 니 다.코드 는 다음 과 같 습 니 다.
import 'dart:async';

import 'package:flutter/services.dart';

class Wechat {
  static const MethodChannel _channel =
      const MethodChannel('wechat');

  static Future get platformVersion async {
    final String version = await _channel.invokeMethod('getPlatformVersion');
    return version;
  }
}

이 파일 에서class Wechat방법get을 정의 한 것 을 볼 수 있 습 니 다.함수 체 는 약간 특별 합 니 다.
final String version = await _channel.invokeMethod('getPlatformVersion');
return version;

우리 의platformVersionversion방법 으로 호출 된 것 입 니 다.이것_channel.invokeMethod('getPlatformVersion')은 바로 우리 Dart 코드 가 네 이 티 브 코드 와 통신 하 는 다리 이자 Flutter 네 이 티 브 플러그 인의 핵심 입 니 다.(물론,당신 이 작성 한 플러그 인 이 네 이 티 브 코드 와 관련 된 기능 이 필요 하지 않다 면_channel있 으 나 마 나 한 것 입 니 다.예 를 들 어 우 리 는 다음 과 같은 방법 을 써 서 두 개의 숫자_channela의 합 을 되 돌려 줄 수 있다.
class Wechat {
  ...
  static int calculate (int a, int b) {
    return a + b;
  }
}

이후 코드 수정b:

class _MyAppState extends State {
  String _platformVersion = 'Unknown';
  //      int    ,        
  int _calculateResult;

  @override
  void initState() {
    super.initState();
    initPlatformState();
  }

  Future initPlatformState() async {
    String platformVersion;
    try {
      platformVersion = await Wechat.platformVersion;
    } on PlatformException {
      platformVersion = 'Failed to get platform version.';
    }

    if (!mounted) return;
    // init    ,     10 + 10    
    _calculateResult = Wechat.calculate(10, 10);

    setState(() {
      _platformVersion = platformVersion;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
        ),
        body: Container(
          padding: EdgeInsets.all(16.0),
          child: SingleChildScrollView(
            child: Column(
              children: [
                Text('Running on: $_platformVersion
'), // Text('Calculate Result: $_calculateResult
'), ], ), ), ), ), ); } }

네 이 티 브 인 코딩 지원 방법
플러그 인 을 쓸 때 가 많 습 니 다.더 많은 것 은 네 이 티 브 코드 를 호출 할 수 있 는 방법 이 필요 하기 때 문 입 니 다.어떻게 해 야 합 니까?
안 드 로 이 드 시스템example/lib/main.dart파일 을 열 고 다음 코드 를 보십시오.
package com.example.wechat;

import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.common.PluginRegistry.Registrar;

/** WechatPlugin */
public class WechatPlugin implements MethodCallHandler {
  /** Plugin registration. */
  public static void registerWith(Registrar registrar) {
    final MethodChannel channel = new MethodChannel(registrar.messenger(), "wechat");
    channel.setMethodCallHandler(new WechatPlugin());
  }

  @Override
  public void onMethodCall(MethodCall call, Result result) {
    if (call.method.equals("getPlatformVersion")) {
      result.success("Android " + android.os.Build.VERSION.RELEASE);
    } else {
      result.notImplemented();
    }
  }
}

위 에서 언급 한 것android/src/main/java/com/example/wechat/WechatPlugin.java을 기억 하 십 니까?기억 나getPlatformVersion그럼 이 안에서 도 보 이 는 대응 하 는 존재 가 아 닐 까?맞습니다._channel중의dartgetPlatformVersion을 통 해 요청 을 한 다음 에_channel.invokeMethod코드 중의Java방법 이 다시 호출 되 었 습 니 다.이 방법 은 두 개의 매개 변수 가 있 습 니 다.
  • onMethodCall:요청 자체
  • MethodCall call:결과 처리 방법
  • 그리고Result result를 통 해call.method의 방법 명 을 알 수 있 고_channel.invokeMethod리 셋 을 통 해 성공 결과 에 대한 응답 을 되 돌려 줍 니 다.
    registerWith
    위 에 작은 코드result.success가 있 는데 그 안에 호출 이 있 는 것 을 볼 수 있 습 니 다.
    final MethodChannel channel = new MethodChannel(registrar.messenger(), "wechat");
    channel.setMethodCallHandler(new WechatPlugin());

    여기 가 바로 우리 의 플러그 인 을 등록 하고registerWith을 우리 의wechat이름 으로 등록 해 야channel플러그 인의 호출 이 마지막 으로alipay플러그 인 에 호출 되 지 않 습 니 다.
    iOS 시스템
    마찬가지 로 이번에 우 리 는wechat파일 을 열 었 다.
    #import "WechatPlugin.h"
    
    @implementation WechatPlugin
    + (void)registerWithRegistrar:(NSObject*)registrar {
      FlutterMethodChannel* channel = [FlutterMethodChannel
          methodChannelWithName:@"wechat"
                binaryMessenger:[registrar messenger]];
      WechatPlugin* instance = [[WechatPlugin alloc] init];
      [registrar addMethodCallDelegate:instance channel:channel];
    }
    
    - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
      if ([@"getPlatformVersion" isEqualToString:call.method]) {
        result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]);
      } else {
        result(FlutterMethodNotImplemented);
      }
    }
    
    @end

    문법 은 다 르 지만ios/Classes/WechatPlugin.m의 자바 코드 구조 와 거의 똑 같은 것 을 볼 수 있다.먼저android한 명registerwechat을 가 져 간 다음 에channel같은 방법 명handleMethodCall을 통 해 방법 명 을 얻 고call.method을 통 해 응답 했다.
    소 칼 을 조금 시험 해 보다.
    그 다음 에 우 리 는 앞의result방법 을 네 이 티 브 코드 로 옮 겨 제공 할 것 이다.
    Android
    앞에서 열 린caculate파일 에서 수정android/src/main/java/com/example/wechat/WechatPlugin.java방법:
      @Override
      public void onMethodCall(MethodCall call, Result result) {
        if (call.method.equals("getPlatformVersion")) {
          result.success("Android " + android.os.Build.VERSION.RELEASE);
        } else if (call.method.equals("calculate")) {
          int a = call.argument("a");
          int b = call.argument("b");
          int r = a + b;
          result.success("" + r);
        } else {
          result.notImplemented();
        }
      }
    onMethodCall판단 을 추 가 했 는데 이 안의 구체 적 인 과정 은:
  • 호출call.method.equals("calculate")방법 으로call.argument()에서 전 달 된 매개 변수
  • 를 얻 을 수 있 습 니 다.
  • 계산 결과
  • 호출wechat.dart응답 결과
  • 그 다음 에 우 리 는result.success()에서lib/wechat.dart방법의 실현 을 수정 해 야 한다.코드 는 다음 과 같다.
      static Future calculate (int a, int b) async {
        final String result = await _channel.invokeMethod('calculate', {
          'a': a,
          'b': b
        });
        return int.parse(result);
      }
    calculate는 비동기 작업 이기 때문에_channel.invokeMethod의 반환 유형 을calculate으로 수정 하고Future를 더 해 야 합 니 다.이때 우 리 는async키 워드 를 직접 사용 할 수 있 습 니 다.awaitJavaScript와 마찬가지 로 동기 화 된 방식 으로 비동기 코드 를 작성 할 수 있 습 니 다.새 버 전의await코드 에서...우 리 는calculate의 결 과 를 직접 계산 하지 않 고a+b방법 을 호출 하여_channel.invokeMethodabJava방법 에 전달 한 후 이 방법 으로 돌아 온 결 과 를 되 돌려 주 었 다.
    _channel.invokeMethod
    이 방법 은 두 개의 매개 변 수 를 받 아들 이 고 첫 번 째 는 하나의 방법 명 을 정의 합 니 다.이것 은 표지 입 니 다.쉽게 말 하면 원생 단의 코드 를 알려 줍 니 다.우 리 는 이번에 무엇 을 해 야 하 는 지,두 번 째 매개 변 수 는 하나의onMethodCall형 데이터 이 고 매개 변수 목록 입 니 다.우 리 는 원생 코드 에서 얻 을 수 있 습 니 다.
    이어서 우 리 는 이 방법 에 대한 호출 을 업데이트 해 야 한다.Map로 돌아 가서 다음 과 같은 호출 로 수정 해 야 한다.
    _calculateResult = await Wechat.calculate(10, 10);

    우리 의 현재example/lib/main.dart방법 은 이미 비동기 적 인 방법 이기 때문이다.
    iOS
    만약 에 우리 의 플러그 인 이calculateAndroid양 끝 을 지원 해 야 한다 면IOS에서 위의 방법 을 동기 화하 고ios파일 을 열 어 다음 과 같이 수정 해 야 합 니 다.
    - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
      NSDictionary *arguments = [call arguments];
      if ([@"getPlatformVersion" isEqualToString:call.method]) {
        result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]);
      } else if ([@"calculate" isEqualToString:call.method]) {
        NSInteger a = [arguments[@"a"] intValue];
        NSInteger b = [arguments[@"b"] intValue];
        result([NSString stringWithFormat:@"%d", a + b]);
      } else {
        result(FlutterMethodNotImplemented);
      }
    }

    실현 과정 은ios/Classes/WechatPlugin.m단 과 일치 하면 된다.
    제3자 SDK 추가
    우리 의 플러그 인 은 위 챗 의 공유 관련 기능 을 제공 할 수 있 기 때문에 제3자 SDK 를 사용 해 야 합 니까?아니면 안 드 로 이 드 부터 시작 해 야 합 니까?
    안 드 로 이 드 엔 드 WechatSDK
    공식 접속 지침 에 따 르 면 우 리 는 의존 도 를 추가 해 야 한다.
    dependencies {
        compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
    }

    혹시
    dependencies {
        compile 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+'
    }

    전 자 는 통계 기능 을 가지 고 있 습 니 다.이것 은 간단 합 니 다.java파일 을 열 고 맨 아래 에 상기 세 션 을 붙 여 넣 으 면 됩 니 다.
    ...
    android {
        compileSdkVersion 27
    
        defaultConfig {
            minSdkVersion 16
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        }
        lintOptions {
            disable 'InvalidPackage'
        }
    }
    
    dependencies {
        compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
    }

    그 다음 에android/build.gradle파일 로 돌아 가서WechatPlugin.java방법 을 추가 합 니 다.이것 은 우리 의 Appid 를 위 챗 에 등록 하 는 것 입 니까?아니면 앞의register중의onMethodCall판단 에 이 어 집 니까?
    ...
    import com.tencent.mm.opensdk.openapi.WXAPIFactory;
    ...
        else if (call.method.equals("register")) {
          appid = call.argument("appid");
          api = WXAPIFactory.createWXAPI(context, appid, true);
          result.success(api.registerApp(appid));
        }
    ...

    그리고if에 해당 하 는 호출 을 추가 합 니 다.
    ...
      /// Register app to Wechat with [appid]
      static Future register(String appid) async {
        var result = await _channel.invokeMethod(
          'register',
          {
            'appid': appid
          }
        );
        return result;
      }
    ...

    이때 우리lib/wechat.dart에서example방법 을 호출 하여 응용 프로그램 을 등록 할 수 있 을 것 이다.
    ios
    공식 ios 접속 지침 에 따 르 면 우 리 는Wechat.register을 통 해 의존 도 를 추가 할 수 있다.
    pod 'WechatOpenSDK'
    pod을 열 면 다음 과 같은 내용 을 볼 수 있 습 니 다.
    #
    # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html
    #
    Pod::Spec.new do |s|
      s.name             = 'wechat'
      s.version          = '0.0.1'
      s.summary          = 'A new flutter plugin project.'
      s.description      = < '../LICENSE' }
      s.author           = { 'Your Company' => '[email protected]' }
      s.source           = { :path => '.' }
      s.source_files = 'Classes/**/*'
      s.public_header_files = 'Classes/**/*.h'
      s.dependency 'Flutter'
    
      s.ios.deployment_target = '8.0'
    end

    세 번 째 줄ios/wechat.podspec을 유의 하 십시오.이것 은 바로 우리 가 의존 하 는 것s.dependency을 지정 하 는 것 입 니 다.다른 의존 이 있 으 면 여기에 한 줄 을 추가 하면 됩 니 다.
    ...
      s.public_header_files = 'Classes/**/*.h'
      s.dependency 'Flutter'
      s.dependency 'WechatOpenSDK'
    
      s.ios.deployment_target = '8.0'
    end

    그리고Flutter파일 을 열 고 다음 과 같이 수정 합 니 다.
    #import 
    #include "WXApi.h"
    
    @interface WechatPlugin : NSObject
    @end

    다시ios/Classes/WechatPlugin.h로 돌아 가 앞의ios/Classes/WechatPlugin.m조건 에 따라 판단 을 계속 추가 합 니 다.
    ...
      // Register app to Wechat with appid
      else if ([@"register" isEqualToString:call.method]) {
        [WXApi registerApp:arguments[@"appid"]];
        result(nil);
      }
    ...

    이때 우리 의 플러그 인 은 위 챗 SDK 의 등록 을 위 챗 기능 에 지원 했다.더 많은 실현 은 본 고 는 더 이상 토론 하지 않 고 관심 이 있 으 면 전체 프로젝트 를 직접 다운로드 할 수 있다.그 다음은 대동소이 한 실현 이다.유일 하 게 필요 한 것 은 어느 정도if인 코딩 과Java인 코딩 능력 이 필요 하 다 는 것 이다.

    좋은 웹페이지 즐겨찾기