Changelog
2.0.2
Avoid flash of white
A quick flash of white could be seen for apps not using placeholder-content. This was caused by the uninitialized webview being visible, and should now no longer happen.
2.0.1
Upgrade trustkit dependency
Upgraded from 1.6.0 to 1.7.0
2.0.0
Naming (breaking)
The framework as well as a number of classes have been renamed. The initial
implementation had the framework called Subaio
and many classes prefixed
with Subaio. The framework and import has been renamed to FintechBridge
(full
package name com.subaio.FintechBridge
). The following classes/protocols have
been renamed:
SubaioManager
->BridgeManager
SubaioView
->BridgeView
SubaioViewDelegate
->BridgeViewDelegate
- all events have been renamed to match
SubaioError
->ViewError
Share event removed (breaking)
BridgeViewDelegate.bridgeView(_:isAttemptingToShare:)
has been moved to an
internal handler. Since sharing can already be disabled during configuration, it
seems unnecessary to require an implementation from library consumers, and it is
unlikely that custom logic will be needed.
Titles can now be nil (breaking)
BridgeViewDelegate.bridgeView(_:updatedTitleTo:)
can now receive nil
as
a title. Ordinarily, this will not happen, but it can be used to indicate that
the header should be hidden. Unless it is agreed that a nil
-title is sent, it
is safe to assume that the title is never nil
.
Configuration (breaking)
The SubaioConfiguration
class has been removed entirely. The options normally
passed to the SubaioConfiguration
constructor should now be passed directly
into the BridgeManager.configure(...)
call.
As a convenience, language
can now also be passed to BridgeManager.configure(...)
as the
second parameter.
Synchronicity
Previously, the configure call was asynchronous. During the configuration, base-HTML and placeholder images were fetched, and an initial token was requested.
All this initialization has been moved to the creation of the first view. Calling configure is now entirely passive and synchronous, and can thus be done whenever convenient, as long as it is before the first view is created.
SSL pinning
To allow the usage of other libraries for authentication, TrustKit has been
moved to an optional dependency, FintechBridgeTrustKit
. This additional
library is distributed alongside the main bridge. In it, the
TrustKitAuthenticationChallenger
should be imported and passed to the
configure call as authenticationChallenger
. Its constructor is identical to
now-removed SubaioSSLPinningConfiguration
.
If using Swift Packages, include both FintechBridge
and
FintechBridgeTrustKit
as dependencies from this repository. TrustKit should be
downloaded automatically.
If using Carthage, explicitly add TrustKit as a dependency in your
Cartfile
:
github "datatheorem/TrustKit" ~> 1.6.0
If another library than TrustKit is used for SSL pinning or to otherwise
validate connections, the AuthenticationChallenger
protocol should be
implemented and passed to the manager.
If default handling of SSL is sufficient, DefaultAuthenticationChallenger
can
be used. It is required to ensure explicit disabling of SSL pinning.
Example
BridgeManager.shared.configure(
baseUrl: URL(string: "...")!,
language: "...",
allowExternalUrls: true,
allowShare: true,
authenticationChallenger: TrustKitAuthenticationChallenger(for: [
.init(domain: "subaio.com", publicKeyHashes: [
"..."
])
]),
onTokenRequired: { (language, completionHandler) in
},
customConfig: ["...": "..."]
)
Resize reporting moved to event (breaking)
The previous implementation of reporting content size relied on an internal
constraint being added, which is not idiomatic swift. This constraint has been
removed, and instead the updated height is reported to
BridgeViewDelegate.bridgeView(_:resizedTo:)
. The implementation can then
choose to add a constraint or use the view frame, and animate the change if
necessary.
The event will only be sent if reportResize
is set to true in the BridgeView
constructor. This is necessary as the underlying view will otherwise attempt to
fill the view, and thus never shrink.
Multiple manager instances (feature)
The BridgeManager constructor is now public, allowing manual administration of a single manager and allowing multiple instances to co-exist. Example:
// Using shared manager
BridgeManager.shared.configure(...)
let view = BridgeView(page: ...)
// Using own manager instance
let manager = BridgeManager()
manager.configure(...)
let view = BridgeView(page: ..., manager: manager)
Be aware that related views should share their manager. There is an initialization overhead when the first view is created for a manager, tokens are maintained and shared through the manager, and the views communicate to refresh stale data through the manager, so creating a new manager for every view is not a good idea. Multiple managers should only be used if multiple apps are embedded.
Prewarming cache (feature)
Previously, base-HTML and placeholder images were fetched on configuration. This
has now been moved to first view creation. Since it will have no cached
placeholder images, the very first BridgeView a device opens might experience a
short flash of white. To avoid this, you can call BridgeManager.prewarm()
at
any point after configuration to ensure the cache is populated. Note that this
is optional.
Custom actions and events (feature)
Support has been added for custom actions (sent to the embedded app) and events (sent from the embedded app). They generally consist of a name and some data, both of which should be agreed upon between the host and embedded apps.
Example of a custom event being used for navigation in the host application:
extension MyBridgeViewDelegate: BridgeViewDelegate {
...
func bridgeView(_ bridgeView: BridgeView, receivedCustomEvent name: String, data: Any?) {
switch (name) {
case ("navigateExternal"):
guard
let dictionary = data as? [String: Any],
let name = dictionary["name"] as? String,
let params = dictionary["params"] as? [String: String]
else {
break
}
print("Go to native \(name) \(params)")
default:
print("Custom event: \(name) \(String(describing: data))")
}
}
}
Example of a custom action being used to control internal scroll:
bridgeView.sendCustomAction(name: "scroll", data: "top")
Optional events (feature)
Previously, all events on BridgeViewDelegate
had to be implemented, even
though a number of them were unnecessary for a functional implementation. A
default no-op implementation has been added to these events.
Events that require implementation:
BridgeViewDelegate.bridgeView(_:navigatedTo:)
BridgeViewDelegate.bridgeViewDidSelectBack(_:)
BridgeViewDelegate.bridgeView(_:didReceiveError:)
Events that are optional:
BridgeViewDelegate.bridgeView(_:changedStatusTo:)
BridgeViewDelegate.bridgeView(_:updatedTitleTo:)
BridgeViewDelegate.bridgeView(_:resizedTo:)
BridgeViewDelegate.bridgeView(_:receivedCustomEvent:data:)
Enable scroll bounce (feature)
Webview scroll bounce can now be enabled through the BridgeView.bounces
property. Note that it is impossible to define different background colors for
top and bottom bounce, resulting in visual glitches if a colored header is used.
Token management (internal)
The BridgeManager
will no longer maintain a token while there are no active
BridgeView
s, nor will it automatically refresh the token before it expires.
New tokens are only requested when
- A view is created and there is no token
- A view is created and the current token is expired
- A request from a view failed because of an expired token
The implementation of onTokenRequired
should stay unchanged.