All Projects → Kyun-J → FlexHybridApp-iOS

Kyun-J / FlexHybridApp-iOS

Licence: BSD-3-Clause license
WebView bridge interface with Promise pattern

Programming Languages

swift
15916 projects
javascript
184084 projects - #8 most used programming language
ruby
36898 projects - #4 most used programming language

Projects that are alternatives of or similar to FlexHybridApp-iOS

FlexHybridApp-Android
WebView bridge interface with Promise pattern
Stars: ✭ 20 (+17.65%)
Mutual labels:  bridge, webview-interface-library
Wkwebviewjavascriptbridge
🌉 A Bridge for Sending Messages between Swift and JavaScript in WKWebViews.
Stars: ✭ 863 (+4976.47%)
Mutual labels:  wkwebview, bridge
react-native-android-wear-demo
Showcase of a two-way communication between React Native and Android Wear apps.
Stars: ✭ 93 (+447.06%)
Mutual labels:  bridge
rpi-roam-webapp
Setup script and web application for a wireless Raspberry Pi bridge.
Stars: ✭ 13 (-23.53%)
Mutual labels:  bridge
BridgeCommander
No description or website provided.
Stars: ✭ 24 (+41.18%)
Mutual labels:  wkwebview
native-js-interactive-encapsulation
主要用于vue和原生的交互
Stars: ✭ 18 (+5.88%)
Mutual labels:  bridge
tor-private-bridge
Bash script for setting up a private Tor bridge
Stars: ✭ 21 (+23.53%)
Mutual labels:  bridge
matrix-puppet-slack
puppet style slack bridge for matrix
Stars: ✭ 46 (+170.59%)
Mutual labels:  bridge
instagram
A Matrix-Instagram DM puppeting bridge
Stars: ✭ 69 (+305.88%)
Mutual labels:  bridge
SerialToTCPBridgeProtocol
An error tolerant serial UART to TCP connection, raw data bridge.
Stars: ✭ 16 (-5.88%)
Mutual labels:  bridge
LitoMusic
A lightweight Apple Music client for Windows and macOS, built with MusicKit JS, Edge WebView2 / WKWebView and React.
Stars: ✭ 100 (+488.24%)
Mutual labels:  wkwebview
VHLWebView
微信/支付宝样式的网络浏览器控件。WKwebview 封装,js bridge和拦截url方式两种方法实现 oc和js交互
Stars: ✭ 14 (-17.65%)
Mutual labels:  wkwebview
cordova-plugin-wkkeyboardfix
Cordova plugin to provide a temporary fix for an iOS 12 and 13 bug involving keyboards in WKWebView.
Stars: ✭ 14 (-17.65%)
Mutual labels:  wkwebview
can2mqtt
Bidirectional CAN-Bus to MQTT-Bridge
Stars: ✭ 39 (+129.41%)
Mutual labels:  bridge
skype-to-telegram
Skype to Telegram bot, for receive your message from skype in telegram
Stars: ✭ 14 (-17.65%)
Mutual labels:  bridge
matrix-appservice-bridge
Bridging infrastructure for Application Services
Stars: ✭ 119 (+600%)
Mutual labels:  bridge
rnim
A bridge between R and Nim
Stars: ✭ 22 (+29.41%)
Mutual labels:  bridge
react-native-mercadopago-px
🚀 MercadoPago PX bridge for react-native
Stars: ✭ 87 (+411.76%)
Mutual labels:  bridge
matrix-pstn-bridge
☎️ A Matrix Puppet bridge for the public telephone network that supports a number of VoIP providers (Twillo, Vonage, etc.). Sends and receives voice and SMS.
Stars: ✭ 25 (+47.06%)
Mutual labels:  bridge
magento2-pimcore-bridge
Magento 2 module for Pimcore integration.
Stars: ✭ 28 (+64.71%)
Mutual labels:  bridge

한국어 README

Android Version

Typescript Support

FlexibleHybrid

FlexHybrid simplifies the interface between WKWebView and Native, including asynchronous processing.
And it offers several convenient features to use WKWebView.

How to add Framework

Add in Podfile

  pod 'FlexHybridApp'

iOS Deployment Target is 10.0

Key Features

  1. It has similar development rules and functions to the Android version.
  2. The interface between wkwebview and native works asynchronously.
    1. Call and return Promise on the Web.
    2. Native operates on a separate Concurrent Queue.
  3. Define the operation of the interface using Swift Closure.
  4. Data can be transferred to Model Object.
  5. By specifying an Url capable of interface operation, you can prevent Native calls from unwanted sites.

and include other features...

FlexComponent

To utilize the features of FlexWebView, you must use FlexComponent.
FlexComponent is created with FlexWebView, and you can also set it up when you declare FlexWebView.
FlexComponent also includes the WKWebViewConfiguration of the WebView as a factor.

Interface Basic Usage

Basically, the interface can be registered and used in the following pattern.
All interfaces operate asynchronously.
On the Web, it becomes pending state until a response occurs.

Web-to-native

Interface registration

The interface must be set before the page is loaded into FlexWebView.

// in swift
var component = FlexComponent()
component.setInterface("funcName") { args in
    return "received from web - \(args[0]?.toString() ?? "no value"), return to web - \(100)"
}
var flexWebView = FlexWebView(frame: self.view.frame, component: component)
flexWebView.load(someUrl)

Using interface.

// in js
const test = async (req) => {
  const res = await $flex.funcName(req);
  console.log(res); // received from web - 200, return to web - 100
};
test(200);

Native-to-web

Interface registration

After the $flex object is loaded (the window.onFlexLoad function can be checked on the $flex Load time), register the interface.

// in js
window.onFlexLoad = () => {
  $flex.web.funcName = async (req) => {
    return await new Promise((resolve) => {
      setTimeout(() => resolve(`received from web - ${req}`), 100);
    });
  };
};

Using interface.

// in swift
component.evalFlexFunc("funcName", "sendData") { response in
    print(response.toString()!) // received from web - sendData
}

Interface Advanced Usage

FlexData

Data received from the Web is converted into FlexData objects for type-safe use.
Upon web-to-native interface, Arguments delivered from a function in Web are forwarded to Array<FlexData>.

// in js
$flex.funcName("test1", 2, 3.1, true, [0, 1, 2], { test: "object" }, "reified");
component.setInterface("funcName") { args in
    if (args == nil) return

    var first = args[0].asString() // "test"
    var second = args[1].asInt() // 2
    var third = args[2].asDouble() // 3.1
    var fourth = args[3].asBool() // true
    var fifth = args[4].asArray() // array of FlexData(0), FlexData(1), FlexData(2)
    var sixth = args[5].asDictionary() // map of first key - test, value - FlexData("object")
    var seventh: String? = args[6].reified() // "reified"
}

Model Obejct

Data to be used for interfaces can be used as Model Obejct.
At this time, the following rules apply.

  1. Model Objects must inherit Codable.
  2. In the Web, it is converted into an object form.
  3. When receiving Model Objects from Native as Arguments, you must deliver only one object corresponding to that model on the Web.
// in swift
struct TestModel: Codable {
  var name: String
  var data2: TestModel2
}

struct TestModel2: Codable {
  var testInt: Int
}

struct ArgsTestModel: Codable {
  var testModel: TestModel
}

component.setInterface("modelTest") { args in
    return TestModel("test", TestModel2(2000))
}

component.setInterface("modelArgsTest") { (req: ArgsTestModel?) -> Void in
    print(req?.testModel.data2.testInt) // 2000
}
// in js
const test = async () => {
  const model = await $flex.modelTest(); // model is { name: 'test', data2: { testInt: 2000 } }
  await $flex.modelArgsTest({ testModel: model });
};
test();

Action inteface

On the web-to-native interface, in a code other than the specified closure code block, It's a way to return the value.
Action objects allow you to return values from the code at the desired location.
At this time, the Web is in pending state until a response occurs.
Also, action objects that have responded once cannot be used again.

var mAction: FlexAction? = null

struct LocationResult: Codable {
  var latitude: Double?
  var longtitude: Double?
}

component.setAction("actionTest") { (action, _) in
    self.mAction = action
    self.getLocation()
}

func getLocation() {
  let status = CLLocationManager.authorizationStatus()
  var locationResult = LocationResult();
  switch status {
  case .authorizedAlways, .authorizedWhenInUse :
      self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
      self.locationManager.startUpdatingLocation()
      let coor = self.locationManager.location?.coordinate
      mAction?.promiseReturn(
        LocationResult(latitude: Double(coor?.latitude ?? 0), longtitude: Double(coor?.longitude ?? 0))
      )
      break
  default:
    mAction?.promiseReturn()
    break
  }
}

Declare closure preferred

It is a feature to easily declare and organize closures that define interfaces behavior.
You can create a closure through a predefined function in the FlexClosure class.

var closureVar = FlexClosure.interface { args in
    ... some job
}
var closureActionVar = FlexClosure.action { (action, args) in
    ... come job
}

component.setInterface("closureVarTest", closureVar)
component.setAction("closureActionVarTest", closureActionVar)

Web-to-native interface timeout settings

Since the interface operates asynchronously, there is a risk of falling into an infinite pending state on the Web.
Therefore, timeout of the interface can be set, and when timeout occurs, it is switched to reject.
If timeout is not set, the default value is 60000 ms.

Set default timeout

You can specify the default value for timeout. If timeout for each interface is not set, the corresponding value is set by default.
Setting zero does not cause timeout and pending indefinitely.
The unit is ms.

var timeout = 1000
component.setInterfaceTimeout(timeout)

Specify timeout for each interface.

When setting up an interface, you can specify the timeout of that interface.
Setting zero does not cause timeout and pending indefinitely.
The unit is ms.

var timeout = 200
component.setInterface("funcName", timeout) { args in }

Interface event listener

Initialization of interface module, interface success, failure, and events for the timeout are listened to.

// Listen for specific events
component.addEventListener(FlexEvent.EXCEPTION) { (type, url, funcName, msg) in
  print("type: \(type.name) url: \(url) funcName: \(funcName) msg: \(msg)")
}

// Listen to all events
var AllListener = { (type, url, funcName, msg) in
  print("type: \(type.name) url: \(url) funcName: \(funcName) msg: \(msg)")
}
flexWebView.addEventListener(AllListener)

// Remove specific EventListener
flexWebView.removeEventListener(AllListener)

// Remove all EventListeners
flexWebView.removeAllEventListener()

FlexWebView features

URL restrictions

It is a feature that prevents loading to unintended sites and sets whether to allow URL-specific interfaces.
This feature was implemented using the WKContentRule, so caution is required as it can be removed through the removeAllContentRuleList function in the WKWebViewConfiguration.

BaseUrl

BaseUrl is a feature that can be used when setting only interface availability without url restrictions.
FlexWebView allows access to all sites if both AllowUrlList and BaseUrl are not set, but the interface functionality is not available.
If only BaseUrl is set, access to all sites is allowed, and the interface opens only to URLs that match BaseUrl.

component.setBaseUrl("www.myurl.com")

Regular expressions can be used when setting url.

component.setBaseUrl(".*.myurl.com")

AllowUrlList

Only available for iOS 11.0 and above.

Setting the AllowUrlList blocks access to all url except for the set url and BaseUrl.

component.addAllowUrl(".*.myurl.com")

To allow an interface when setting up a URL, add true to the second canFlexLoad property of the addAllowUrl function.

component.addAllowUrl(".*.myurl.com", canFlexLoad: true)

Automanage cookie

Only available for iOS 11.0 and above.
This feature is a very basic feature, so please implement and use cookie-related features directly in case of a problem.
It's a feature that automatically maintains cookies.
The default value is inactive and operates automatically when the feature is activated.
FlexWebViews with that feature enabled in the app share all cookies.

component.setAutoCookieManage(true) // activate
component.setAutoCookieManage(true, clearAll: true) // activate and delete all cookies

Web console message output.

Displays messages from web console.log, debug, error, warn, and info in the output window of xcode.
It is activated by default.

This output may not be the same as the console message on web.

component.setShowWebViewConsole(true)

FileAccess

Ability to set allowAccessFromFileURLs, allowUniversalAccessFromFileURLs at once.

component.setAllowsUrlAccessInFile(true)

Use in js

$flex Object

$flex Object is an object composed of interfaces between FlexWebView and Promise.
$flex is declared in the webpage at runtime when the webpage is loaded in the webview.
When $flex is finished loading, you can check the window.onFlexLoad function.
$flex can also be used in any accessible frames. (Ex) iframe that does not violate Cross-Origin)
The components of $ flex Object are as follows.

window.onFlexLoad; // $flex is called upon completion of loading.
$flex; // Object that contains functions that can call Native area as WebToNative
$flex.version; // get Library version
$flex.web; // Object used to add and use functions to be used for NativeToWeb
$flex.device; // Current Device Info
$flex.isAndroid; // false
$flex.isiOS; // true
$fles.isScript; // false

ToDo

Apply async awit from Swift 5.5.
Flutter version FlexHybirdApp.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].