JavaScriptとSwift&JavaをつなげるCapacitorと、これからのWeb Frontend/Linking JavaScript with Swift&Java,
And the future of Web Frontend.

7ce46cdba50db99f3403024fe2519c91?s=47 Masahiko Sakakibara
December 01, 2019
2.4k

JavaScriptとSwift&JavaをつなげるCapacitorと、これからのWeb Frontend/Linking JavaScript with Swift&Java,
And the future of Web Frontend.

7ce46cdba50db99f3403024fe2519c91?s=128

Masahiko Sakakibara

December 01, 2019
Tweet

Transcript

  1. -JOLJOH+BWB4DSJQUXJUI4XJGU+BWB  "OEUIFGVUVSFPG8FC'SPOUFOE +BWB4DSJQUͱ4XJGU+BWBΛͭͳ͛Δ$BQBDJUPSͱɺ͜Ε͔Βͷ8FC'SPOUFOE

  2. *OUSPEVDF .BTBIJLP4BLBLJCBSB $&0 PG3FMBUJPO%FTJHO-BC $50PG "SFB*OOPWBUJPO"MMJBODF *POJD+BQBO6TFS(SPVQ 0SHBOJ[FS

  3. $POUSJCVUF ionic-team/ionic ionic-team/starters ionic-team/ionic-cli ionic-team/ionic-docs ionic-team/ionic-react -conference-app GoogleChrome/lighthouse

  4. !SEMBCPDBQBDJUPSGBDFCPPLMPHJO

  5. !SEMBCPDBQBDJUPSBENPC

  6. ఆֹॅΈ์୊ºՈकͷֶߍ ʮ݄ສͰશࠃॅΈ์୊ʯͰόζͬͨ"%%SFTTͷڌ఺ϚωʔδϟʔεΫʔ ϧΛߦ͍·͢ɻ"%%SFTTͷڌ఺ʹॅΈɺ஍ҬΛม͑ͯΈ·ͤΜ͔ʁʁ ڌ఺ʢॅډʣΛ࣋ͬͯ஍ҬͱؔΘΓͳ͕Βࣄۀ͕Ͱ͖ΔͷͰɺϦϞʔτ ϫʔΧʔͷ৽͍͠ಇ͖ํʹ͓͢͢ΊͰ͢ʂ Ոकͷֶߍ

  7. 8IBUJT$BQBDJUPS

  8. $BQBDJUPS

  9. )PXXPSLTPG8FC/BUJWF"QQ w 7JFXT-PDBMT8FC"QQVTJOHB 8FC7JFXDBMMFE"QQ w "1*BWBJMBCMFUPBDDFTT/BUJWF 'VODUJPOT 888

  10. %J⒎FSFODFPG3FBDU/BUJWF/BUJWF4DSJQU

  11. /PUGBTUFTU#VUOPUTMPX https://vimeo.com/55486684

  12. 6TJOH$BQBDJUPS )PX

  13. 6TJOH$BQBDJUPS $ npm install @capacitor/core @capacitor/cli $ npx cap init

    { "appId": “jp.rdlabo.capacitor", "appName": "ng-capacitor", "bundledWebRuntime": false, "npmClient": "npm", "webDir": “dist/ng-capacitor", "cordova": {} } capacitor.config.json
  14. 6TJOH$BQBDJUPSJ04 $ npx cap add ios SFG /FX4XJGU1SPKFDU

  15. 4XJGUUP)5.-+BWB4DSJQU

  16. 6TJOH$BQBDJUPSJ04 DPNQBSF/FX4XJGU1SPKFDU SFG /FX4XJGU1SPKFDU

  17. /FX4XJGU1SPKFDUˠ#MBOL

  18. $BQBDJUPSJ041SPKFDUˠ$"1#SJEHF7JFX$POUSPMMFS <viewController id="BYZ-38-t0r" customClass="CAPBridgeViewController" customModule="Capacitor" sceneMemberID="viewController"/>

  19. 8IBUJT$"1#SJEHF7JFX$POUSPMMFS ˠ1PEpMF platform :ios, '11.0' use_frameworks! # workaround to avoid

    Xcode 10 caching of Pods that requires # Product -> Clean Build Folder after new Cordova plugins installed # Requires CocoaPods 1.6 or newer install! 'cocoapods', :disable_input_output_p aths => true def capacitor_pods # Automatic Capacitor Pod dependencies, do not delete pod 'Capacitor', :path => '../../ node_modules/@capacitor/ios' pod 'CapacitorCordova', :path => '../../node_modules/@capacitor/ios' # Do not delete end Podfile
  20. $"1#SJEHF7JFX$POUSPMMFSWJFXTQVCMJD func loadWebView() { let fullStartPath = URL(fileURLWithPath: "public").appendingPathComponent(startDir).appen dingPathComponent("index")

    if Bundle.main.path(forResource: fullStartPath.relativePath, ofType: "html") == nil { fatalLoadError() } hostname = bridge!.config.getString("server.url") ?? "\ (bridge!.getLocalUrl())" allowNavigationConfig = bridge!.config.getValue("server.allowNavigation") as? Array<String> CAPLog.print("⚡ Loading app at \ (hostname!)...") let request = URLRequest(url: URL(string: hostname!)!) _ = webView?.load(request) } CAPBridgeViewController.swift
  21. 8IBUJTAQVCMJDA $ npm install @capacitor/core @capacitor/cli $ npx cap init

    { "appId": “jp.rdlabo.capacitor", "appName": "ng-capacitor", "bundledWebRuntime": false, "npmClient": "npm", "webDir": “dist/ng-capacitor", "cordova": {} } capacitor.config.json 5PQVCMJDEJSFDUPSZ
  22. /PU.VTUSFRVJSF41" 4BNF0SJHJO0OMZ JOEFYIUNM OFYUIUNM UIJSETIUNM #VU"QQNVTUMPBEBTTFUTpMFFWFSZUJNF

  23. )5.-+BWB4DSJQUUP4XJGU

  24. 6TJOH$BQBDJUPS1MVHJO $ npx @capacitor/cli plugin:generate

  25. 6TJOH$BQBDJUPS1MVHJO TIPVME4UBSU-PBE8JUI3FRVFTU

  26. TIPVME4UBSU-PBE8JUI3FRVFTU 1MVHJOI1MVHJON w "EE$VTUPN63-4DIFNF w "EELFZUP8JOEPX0CKFDUJO8FC7JFX w FY XJOXFCLJUNFTTBHF)BOEMFSTCSJEHFQPTU.FTTBHF BSH

    *GBQQBDDFTT8JOEPX 0CKFDU VTJOHBSH UIJTpMF XJMMCFFYFDVUFE Plugin.swift
  27. #SJEHF'VODUJPO if (win.webkit && win.webkit.messageHandlers && win.webkit.messageHandlers.bridge) { // ios

    platform postToNative = function iosBridge(data) { data.type = 'message'; win.webkit.messageHandlers.bridge.postMessage(data); }; capacitor.isNative = true; capacitor.isIOS = true; capacitor.platform = 'ios'; } capacitor/core/native-bridge.js
  28. 4Pʜ JOEFYIUNM #VOEMFKT OBUJWFCSJEHFKT 1MVHJON 1MVHJO I 1MVHJOTXJGU TIPVME4UBSU-PBE8JUI3FRVFTU $IFDLSVOFOWJSPONFOU

    $BMM'VODUJPO
  29. +BWBUP)5.-+BWB4DSJQU

  30. 6TJOH$BQBDJUPS"OESPJE $ npx cap add android SFG /FX+BWB1SPKFDU

  31. 6TJOH$BQBDJUPS"OESPJE SFG /FX+BWB1SPKFDU

  32. .BJO"DUJWJUZFYUFOET#SJEHF"DUJWJUZ public class MainActivity extends BridgeActivity { @Override public void

    onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Initializes the Bridge this.init(savedInstanceState, new ArrayList<Class<? extends Plugin>>() {{ // Additional plugins you've installed go here // Ex: add(TotallyAwesomePlugin.class); }}); } } MainActivity.java
  33. #SJEHF"DUJWJUZMPBET#SJEHF$MBTT protected void load(Bundle savedInstanceState) { Log.d(LogUtils.getCoreTag(), "Starting BridgeActivity"); webView

    = findViewById(R.id.webview); … pluginManager = mockWebView.getPluginManager(); cordovaInterface.onCordovaInit(pluginManager); bridge = new Bridge(this, webView, initialPlugins, cordovaInterface, pluginManager, preferences); Splash.showOnLaunch(this); if (savedInstanceState != null) { bridge.restoreInstanceState(savedInstanceState); } this.keepRunning = preferences.getBoolean("KeepRunning", true); this.onNewIntent(getIntent()); } MainActivity.java
  34. #SJEHF$MBTTMPBETXFCWJFX Bridge.java public class Bridge { … public static final

    String DEFAULT_WEB_ASSET_DIR = "public"; public static final String CAPACITOR_HTTP_SCHEME = "http"; public static final String CAPACITOR_HTTPS_SCHEME = "https"; public static final String CAPACITOR_FILE_START = "/_capacitor_file_"; public static final String CAPACITOR_CONTENT_START = "/_capacitor_content_"; public Bridge(Activity context, WebView webView, List<Class<? extends Plugin>> initialPlugins, CordovaInterfaceImpl cordovaInterface, PluginManager pluginManager, CordovaPreferences preferences) { this.context = context; this.webView = webView; this.initialPlugins = initialPlugins; this.cordovaInterface = cordovaInterface; this.preferences = preferences; … this.loadWebView(); }
  35. #SJEHF$MBTTMPBETXFCWJFX Bridge.java private void loadWebView() { appUrlConfig = Config.getString("server.url"); String[]

    appAllowNavigationConfig = Config.getArray("server.allowN avigation"); … localUrl = scheme + "://" + authority; localServer = new WebViewLocalServer(context, this, getJSInjector(), authorities, html5mode); localServer.hostAssets(DEFAU LT_WEB_ASSET_DIR);
  36. )5.-+BWB4DSJQUUP+BWB

  37. 6TJOH$BQBDJUPS1MVHJO $ npx @capacitor/cli plugin:generate

  38. #SJEHF$MBTTJTl+BWB4DSJQU*OUFSGBDFz Bridge.java public Bridge(Activity context, WebView webView, List<Class<? extends Plugin>>

    initialPlugins, CordovaInterfaceImpl cordovaInterface, PluginManager pluginManager, CordovaPreferences preferences) { this.context = context; this.webView = webView; this.initialPlugins = initialPlugins; this.cordovaInterface = cordovaInterface; this.preferences = preferences; // Start our plugin execution threads and handlers handlerThread.start(); taskHandler = new Handler(handlerThread.getLooper()); Config.load(getActivity()); // Initialize web view and message handler for it this.initWebView(); this.msgHandler = new MessageHandler(this, webView, pluginManager);
  39. #SJEHF$MBTTJTl+BWB4DSJQU*OUFSGBDFz MessageHandler.java public class MessageHandler { private Bridge bridge; private

    WebView webView; private PluginManager cordovaPluginManager; public MessageHandler(Bridge bridge, WebView webView, PluginManager cordovaPluginManager) { this.bridge = bridge; this.webView = webView; this.cordovaPluginManager = cordovaPluginManager; webView.addJavascriptInterface(this, "androidBridge"); }
  40. #SJEHF'VODUJPO if (win.androidBridge) { // android platform postToNative = function

    androidBridge(data) { win.androidBridge.postMessage(JSON.stringify(data)); }; capacitor.isNative = true; capacitor.isAndroid = true; capacitor.platform = 'android'; } capacitor/core/native-bridge.js
  41. 4Pʜ JOEFYIUNM #VOEMFKT OBUJWFCSJEHFKT 1MVHJOKBWB +BWB4DSJQU*OUFSGBDF $IFDLSVOFOWJSPONFOU $BMM'VODUJPO

  42. %FTDSJQUJPO

  43. 4Pʜ QVCMJD JOEFYIUNM 8FC #SPXTFS J04 "OESPJE 63-3FRVFTU +BWB4DSJQU XFC7JFX

    MPBE SFRVFTU TIPVME4UBSU-PBE8JUI3FRVFTU XFC7JFXMPBE6SM BQQ6SM +BWB4DSJQU*OUFSGBDF
  44. .PCJMF%FWJDF"1* %5PVDI "##::3FBM5JNF 3FDPHOJUJPO "&4 "DUJPO4IFFU "E.PC'SFF "E.PC1MVT "E.PC1SP "EKVTU

    "ENPC "MJQBZ "OBMZUJDT'JSFCBTF "OESPJE&YP1MBZFS "OESPJE'JOHFSQSJOU "VUI "OESPJE'VMM4DSFFO "OESPJE 1FSNJTTJPOT "OTXFST "OZMJOF "QQ"WBJMBCJMJUZ "QQ$FOUFS "OBMZUJDT "QQ$FOUFS $SBTIFT "QQ$FOUFS1VTI "QQ-BVODIFS #BTF #BUUFSZ4UBUVT #JP$BUDI #JPNFUSJD8SBQQFS #MJOL*E #MJOL6Q #MVFUPPUI4FSJBM #MVFUPPUI-& #SBJOUSFF #SBODI*P #SJHIUOFTT #SPBEDBTUFS #SPXTFS5BC $BMFOEBS $BMM%JSFDUPSZ $BMM-PH $BMM/VNCFS $BNFSB1SFWJFX $BNFSB $BSE*0 $IPPTFS $MBTT,JU $MFWFS5BQ $MJQCPBSE $MPVE4FUUJOHT $PEF1VTI $PMPSFE#SPXTFS &NN"QQ$POpH &TUJNPUF#FBDPOT &YUFOEFE%FWJDF *OGPSNBUJPO '$. '51 'BDFCPPL 'JMF$IPPTFS 'JMF&ODSZQUJPO 'JMF0QFOFS 'JMF1BUI 'JMF5SBOTGFS 'JMF 'JOHFSQSJOU"*0 'JSFCBTF"OBMZUJDT 'JSFCBTF "VUIFOUJDBUJPO 'JSFCBTF$POpH 'JSFCBTF $SBTIMZUJDT 'JSFCBTF%ZOBNJD -JOLT 'JSFCBTF.FTTBHJOH 'JSFCBTF9 'JSFCBTF 'JSFCBTF$SBTI 'MBTIMJHIU )ZQFS5SBDL *#FBDPO *NBHF1JDLFS *NBHF3FTJ[FS *O"QQ#SPXTFS *O"QQ1VSDIBTF *O"QQ1VSDIBTF *O"QQ3FWJFX *OEFY"QQ$POUFOU *OTPNOJB *OTUBHSBN *OUFM4FDVSJUZ *OUFSDPN *POJD8FCWJFX *T%FCVH +JOT.FNF ,FZCPBSE ,FZDIBJO5PVDI*E ,FZDIBJO -BTU$BN -BVODI/BWJHBUPS -BVODI3FWJFX -JOF-PHJO -PDBM/PUJpDBUJPOT -PDBUJPO"DDVSBDZ -PUUJF4QMBTI 4DSFFO 0QFO/BUJWF 4FUUJOHT 0QFO"-13 1BZ1BM 1FEPNFUFS 1IPOFHBQ-PDBM /PUJpDBUJPO 1IPUP-JCSBSZ 1IPUP7JFXFS 1JO$IFDL 1JO%JBMPH 1JOUFSFTU 1PXFS.BOBHFNFOU 1SFWJFX"OZ'JMF 1SJOUFS 1SP 1VSDIBTFT 1VTI 224%, 234DBOOFS 2VJLLMZ1MVHJO 3FHVMB%PDVNFOU 3FBEFS 3PMMCBS 4.4 42-JUF1PSUFS 42-JUF 4UBS13/5 4UBUVT#BS 4UFQDPVOUFS 4USFBNJOH.FEJB 4USJQF 4VN6Q 5BQUJD&OHJOF 5FBMJVN 5FBMJVN"E*EFOUJpFS 5FBMJVN*OTUBMM3FGFSS FS 5FYU5P4QFFDI 5IFNF%FUFDUJPO 5IFNFBCMF#SPXTFS 5PBTU 5PVDI*% 5XJUUFS$POOFDU 6JE 6OJRVF%FWJDF*% 6OWJSFE$PSEPWB 4%, 6QUJNF 6SCBO"JS4IJQ 6TFS"HFOU 7JCSBUJPO 7JEFP$BQUVSF1MVT 7JEFP&EJUPS
  45. 8FCJT.BJO8FC7JFXPOMZ *GUIJTJTTMPX XFCJONPCJMFJTBMMTMPX 8FDBOBDDFTT4XJGUBOE+BWB$PEFGSPN+BWB4DSJQU 8JOEPX0CKFDU  8FDBODSFBUF/BUJWF7JFXBOEUPCFBCMFDPOUSPMGSPN/BUJWF$PEF

  46. *GZPVJOUFSFTUFEJO.PCJMF%FWJDF  ZPVTIPVMEVTF$BQBDJUPS

  47. %PZPVXBOU.PCJMF"QQ6* 'SBNFXPSL $PNQBUJCJMJUZ lOPOMJOFBS OBWJHBUJPO .PCJMF6* /BWJHBUJPO 4UBDL

  48. /FFE.PCJMF"QQ6*.PCJMF6* .PCJMF6TFS*OUFSGBDF

  49. /FFE.PCJMF"QQ6*'SBNFXPSL$PNQBUJCJMJUZ 'SBNFXPSL$PNQBUJCJMJUZ ʮίϯύνϏϦςΟͱ͸ɺϋʔυ΢ΣΞ΍ιϑτ΢ΣΞ͕ɺ࢓༷ͷҟͳΔ΋ͷʹஔ͖ ׵͑ΒΕ্ͨͰ΋ɺݩ௨Γͷಈ࡞Λ͢Δͱ͍͏ঢ়ଶͷ͜ͱͰ͋Δʯ

  50. /FFE.PCJMF"QQ6*lOPOMJOFBSOBWJHBUJPO lOPOMJOFBSOBWJHBUJPO

  51. /FFE.PCJMF"QQ6*/BWJHBUJPO4UBDL /BWJHBUJPOTUBDL

  52. *POJD'SBNFXPSL

  53. /PUPOMZPOF8IJDIpSTU8FC18"PS.PCJMF IUUQTXXXBGQCCDPNBSUJDMFT

  54. $SFBUF.PCJMF"QQTVTJOH*POJD IUUQTBN[OUP1"S&M