iosWebViewFix/ios/Classes/SafariViewController.swift

217 lines
7.3 KiB
Swift
Executable File

//
// SafariViewController.swift
// flutter_inappwebview
//
// Created by Lorenzo on 25/09/18.
//
import Foundation
import SafariServices
@available(iOS 9.0, *)
public class SafariViewController: SFSafariViewController, FlutterPlugin, SFSafariViewControllerDelegate {
var channel: FlutterMethodChannel?
var safariOptions: SafariBrowserOptions?
var uuid: String = ""
var menuItemList: [[String: Any]] = []
public static func register(with registrar: FlutterPluginRegistrar) {
}
deinit {
print("SafariViewController - dealloc")
}
public func prepareMethodChannel() {
channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_chromesafaribrowser_" + uuid, binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger())
SwiftFlutterPlugin.instance!.registrar!.addMethodCallDelegate(self, channel: channel!)
}
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
// let arguments = call.arguments as? NSDictionary
switch call.method {
case "close":
close(result: result)
break
default:
result(FlutterMethodNotImplemented)
break
}
}
public override func viewWillAppear(_ animated: Bool) {
// prepareSafariBrowser()
super.viewWillAppear(animated)
onChromeSafariBrowserOpened()
}
public override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
self.onChromeSafariBrowserClosed()
self.dispose()
}
func prepareSafariBrowser() {
if #available(iOS 11.0, *) {
self.dismissButtonStyle = SFSafariViewController.DismissButtonStyle(rawValue: (safariOptions?.dismissButtonStyle)!)!
}
if #available(iOS 10.0, *) {
if !(safariOptions?.preferredBarTintColor.isEmpty)! {
self.preferredBarTintColor = color(fromHexString: (safariOptions?.preferredBarTintColor)!)
}
if !(safariOptions?.preferredControlTintColor.isEmpty)! {
self.preferredControlTintColor = color(fromHexString: (safariOptions?.preferredControlTintColor)!)
}
}
self.modalPresentationStyle = UIModalPresentationStyle(rawValue: (safariOptions?.presentationStyle)!)!
self.modalTransitionStyle = UIModalTransitionStyle(rawValue: (safariOptions?.transitionStyle)!)!
}
func close(result: FlutterResult?) {
dismiss(animated: true)
// wait for the animation
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(400), execute: {() -> Void in
if result != nil {
result!(true)
}
})
}
public func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
close(result: nil)
}
public func safariViewController(_ controller: SFSafariViewController,
didCompleteInitialLoad didLoadSuccessfully: Bool) {
if didLoadSuccessfully {
onChromeSafariBrowserCompletedInitialLoad()
}
else {
print("Cant load successfully the 'SafariViewController'.")
}
}
public func safariViewController(_ controller: SFSafariViewController, activityItemsFor URL: URL, title: String?) -> [UIActivity] {
var uiActivities: [UIActivity] = []
menuItemList.forEach { (menuItem) in
let activity = CustomUIActivity(uuid: uuid, id: menuItem["id"] as! Int64, url: URL, title: title, label: menuItem["label"] as? String, type: nil, image: nil)
uiActivities.append(activity)
}
return uiActivities
}
//
// public func safariViewController(_ controller: SFSafariViewController, excludedActivityTypesFor URL: URL, title: String?) -> [UIActivity.ActivityType] {
// print("excludedActivityTypesFor")
// print(URL)
// print(title)
// return []
// }
//
// public func safariViewController(_ controller: SFSafariViewController, initialLoadDidRedirectTo URL: URL) {
// print("initialLoadDidRedirectTo")
// print(URL)
// }
public func onChromeSafariBrowserOpened() {
channel!.invokeMethod("onChromeSafariBrowserOpened", arguments: [])
}
public func onChromeSafariBrowserCompletedInitialLoad() {
channel!.invokeMethod("onChromeSafariBrowserCompletedInitialLoad", arguments: [])
}
public func onChromeSafariBrowserClosed() {
channel!.invokeMethod("onChromeSafariBrowserClosed", arguments: [])
}
public func dispose() {
delegate = nil
channel!.setMethodCallHandler(nil)
}
// Helper function to convert hex color string to UIColor
// Assumes input like "#00FF00" (#RRGGBB).
// Taken from https://stackoverflow.com/questions/1560081/how-can-i-create-a-uicolor-from-a-hex-string
func color(fromHexString: String, alpha:CGFloat? = 1.0) -> UIColor {
// Convert hex string to an integer
let hexint = Int(self.intFromHexString(hexStr: fromHexString))
let red = CGFloat((hexint & 0xff0000) >> 16) / 255.0
let green = CGFloat((hexint & 0xff00) >> 8) / 255.0
let blue = CGFloat((hexint & 0xff) >> 0) / 255.0
let alpha = alpha!
// Create color object, specifying alpha as well
let color = UIColor(red: red, green: green, blue: blue, alpha: alpha)
return color
}
func intFromHexString(hexStr: String) -> UInt32 {
var hexInt: UInt32 = 0
// Create scanner
let scanner: Scanner = Scanner(string: hexStr)
// Tell scanner to skip the # character
scanner.charactersToBeSkipped = CharacterSet(charactersIn: "#")
// Scan hex value
scanner.scanHexInt32(&hexInt)
return hexInt
}
}
class CustomUIActivity : UIActivity {
var uuid: String
var id: Int64
var url: URL
var title: String?
var type: UIActivity.ActivityType?
var label: String?
var image: UIImage?
init(uuid: String, id: Int64, url: URL, title: String?, label: String?, type: UIActivity.ActivityType?, image: UIImage?) {
self.uuid = uuid
self.id = id
self.url = url
self.title = title
self.label = label
self.type = type
self.image = image
}
override class var activityCategory: UIActivity.Category {
return .action
}
override var activityType: UIActivity.ActivityType? {
return type
}
override var activityTitle: String? {
return label
}
override var activityImage: UIImage? {
return image
}
override func canPerform(withActivityItems activityItems: [Any]) -> Bool {
return true
}
override func perform() {
let channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_chromesafaribrowser_" + uuid, binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger())
let arguments: [String: Any?] = [
"url": url.absoluteString,
"title": title,
"id": id,
]
channel.invokeMethod("onChromeSafariBrowserMenuItemActionPerform", arguments: arguments)
}
}