diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 3bd6988..0000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,51 +0,0 @@ ---- -version: 2 -jobs: - "RxWebKit Tests": - working_directory: ~/RxSwiftCommunity/RxWebKit - parallelism: 1 - shell: /bin/bash --login - environment: - XCODE_TEST_REPORTS: /tmp/xcode-test-results - LANG: en_US.UTF-8 - macos: - xcode: '11.4.1' - steps: - - checkout - - run: mkdir -p $CIRCLE_ARTIFACTS $CIRCLE_TEST_REPORTS $XCODE_TEST_REPORTS - - restore_cache: - keys: - - v1-dep-{{ .Branch }}- - - v1-dep-master- - - v1-dep- - - run: - name: Bootstrap Carthage - command: carthage update --no-use-binaries - - save_cache: - key: v1-dep-{{ .Branch }}-{{ epoch }} - paths: - - Carthage - - run: - name: Build (Swift 5.0) - command: > - set -o pipefail && xcodebuild build SWIFT_VERSION=5.2.2 - -workspace RxWebKit.xcworkspace - -scheme 'RxWebKit' -sdk iphonesimulator - -destination "name=iPhone 11" | xcpretty -c - - run: - name: Run Tests (Swift 5.0) - command: > - set -o pipefail && xcodebuild test SWIFT_VERSION=5.2.2 - -workspace RxWebKit.xcworkspace - -scheme 'RxWebKitTests-iOS' -sdk iphonesimulator - -destination "name=iPhone 11" | xcpretty -c --test - - store_artifacts: - path: /tmp/xcode-test-results -workflows: - version: 2 - build: - jobs: - - "RxWebKit Tests": - filters: - tags: - ignore: /[0-9]+(\.[0-9]+)*/ diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml new file mode 100644 index 0000000..f80d6a6 --- /dev/null +++ b/.github/workflows/create-release.yml @@ -0,0 +1,81 @@ +name: Create release + +on: + push: + branches: [main] + +jobs: + build: + if: "!contains(github.event.head_commit.message, 'skip ci')" + runs-on: macos-11.0 + + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Fetch all tags + run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* + + - name: Bump version + run: | + chmod +x ./scripts/bump-version.sh + ./scripts/bump-version.sh + + # - name: Changelog + # uses: scottbrenner/generate-changelog-action@master + # id: Changelog + # env: + # REPO: ${{ github.repository }} + + - name: Push changes + uses: ad-m/github-push-action@master + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + branch: ${{ github.ref }} + + - name: Restore SPM Cache + uses: actions/cache@v1 + with: + path: .build + key: ${{ runner.os }}-spm-${{ hashFiles('**/Package.resolved') }} + restore-keys: | + ${{ runner.os }}-spm- + + - name: Release XCFrameworks + run: | + chmod +x ./scripts/xcframeworks.sh + ./scripts/xcframeworks.sh + + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ env.RELEASE_VERSION }} + release_name: RxWebKit ${{ env.RELEASE_VERSION }} + # body: | + # ${{ steps.Changelog.outputs.changelog }} + draft: false + prerelease: false + + - name: Upload XCFramework + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./RxWebKit.xcframework.zip + asset_name: RxWebKit.xcframework.zip + asset_content_type: application/zip + + - name: Deploy to Cocoapods + run: | + set -eo pipefail + export RELEASE_VERSION="$(git describe --abbrev=0 | tr -d '\n')" + RELEASE_VERSION=${RELEASE_VERSION:1} + pod lib lint --allow-warnings + pod trunk push --allow-warnings + env: + COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }} diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml new file mode 100644 index 0000000..fc039d5 --- /dev/null +++ b/.github/workflows/pull_request.yml @@ -0,0 +1,49 @@ +name: Lint, build and test + +on: + pull_request: + branches: [main] + +jobs: + build: + runs-on: macos-11.0 + + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Fetch all tags + run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* + + - name: Resolve dependencies + run: | + brew bundle + bundle + + - name: Danger + run: | + bundle exec danger + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Restore SPM Cache + uses: actions/cache@v1 + with: + path: .build + key: ${{ runner.os }}-spm-${{ hashFiles('**/Package.resolved') }} + restore-keys: | + ${{ runner.os }}-spm- + + - name: Build and test (SPM) + run: | + swift build + swift test + + - name: Build Cocoapods iOS Demo + run: | + set -eo pipefail + cd Examples + xcodegen + pod install --repo-update + xcodebuild build -scheme 'RxWebKitDemo-iOS' -workspace 'RxWebKitDemo.xcworkspace' -sdk iphonesimulator -destination "platform=iOS simulator,name=iPhone 11" diff --git a/.gitignore b/.gitignore index 8eb32ff..5a92203 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,3 @@ - -# Created by https://www.gitignore.io/api/swift - -### Swift ### # Xcode # # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore @@ -20,6 +16,7 @@ DerivedData *.perspectivev3 !default.perspectivev3 xcuserdata +*.swp ## Other *.xccheckout @@ -31,21 +28,11 @@ xcuserdata *.hmap *.ipa -## Playgrounds -timeline.xctimeline -playground.xcworkspace - -# Swift Package Manager -# -# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. -# Packages/ -.build/ - # CocoaPods # # We recommend against adding the Pods directory to your .gitignore. However # you should judge for yourself, the pros and cons are mentioned at: -# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control # Pods/ @@ -53,15 +40,12 @@ Pods/ # # Add this line if you want to avoid checking in source code from Carthage dependencies. Carthage/Checkouts - Carthage/Build -# fastlane -# -# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the -# screenshots whenever they are needed. -# For more information about the recommended setup visit: -# https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md +# Swift Package Manager +.build +Package.resolved -fastlane/report.xml -fastlane/screenshots +.DS_Store +**/.idea/** +RxWebKit-SPM.xcodeproj \ No newline at end of file diff --git a/.jazzy.yaml b/.jazzy.yaml new file mode 100644 index 0000000..9b4bea1 --- /dev/null +++ b/.jazzy.yaml @@ -0,0 +1,5 @@ +output: ../docs/RxWebKit +module: RxWebKit +xcodebuild_arguments: + - -scheme + - RxWebKit iOS \ No newline at end of file diff --git a/.swiftformat b/.swiftformat new file mode 100644 index 0000000..12f7109 --- /dev/null +++ b/.swiftformat @@ -0,0 +1,45 @@ +--allman false +--binarygrouping none +--commas inline +--comments ignore +--decimalgrouping 3,6 +--elseposition same-line +--empty void +--exponentcase lowercase +--exponentgrouping disabled +--fractiongrouping disabled +--disable blankLinesAroundMark +--header ignore +--hexgrouping 4,8 +--hexliteralcase uppercase +--patternlet hoist +--ifdef indent +--indent 2 +--indentcase false +--linebreaks lf +--octalgrouping none +--operatorfunc nospace +--patternlet hoist +--ranges nospace +--self remove +--semicolons inline +--stripunusedargs closure-only +--trimwhitespace always +--wraparguments after-first +--wrapcollections before-first +--enable blankLinesBetweenScopes +--enable redundantVoidReturnType +--enable strongifiedSelf +--enable trailingClosures +--enable trailingSpace +--enable typeSugar +--enable spaceInsideParens +--enable spaceInsideBrackets +--enable spaceInsideBraces +--enable spaceAroundOperators +--enable spaceAroundBraces +--enable redundantParens +--enable redundantNilInit +--enable consecutiveSpaces +--enable anyObjectProtocol +--disable isEmpty \ No newline at end of file diff --git a/.swiftlint.yml b/.swiftlint.yml new file mode 100644 index 0000000..dcbaf65 --- /dev/null +++ b/.swiftlint.yml @@ -0,0 +1,56 @@ +disabled_rules: + - trailing_whitespace + - trailing_comma + - large_tuple + - nesting + - todo + - operator_whitespace + - colon + - identifier_name + +opt_in_rules: # some rules are only opt-in + - empty_count + - yoda_condition + # Find all the available rules by running: + # swiftlint rules + +included: + - Sources + - Tests + - Examples/RxWebKitDemo-iOS + +# excluded: # paths to ignore during linting. Takes precedence over `included`. + +# configurable rules can be customized from this configuration file +# binary rules can set their severity level +force_cast: warning # implicitly +force_try: + severity: warning # explicitly +# rules that have both warning and error levels, can set just the warning level +# implicitly +line_length: 180 +# they can set both implicitly with an array +function_body_length: 120 +type_body_length: + - 400 # warning + - 500 # error +# or they can set both explicitly +file_length: + warning: 500 + error: 1200 +# naming rules can set warnings/errors for min_length and max_length +# additionally they can set excluded names +generic_type_name: + min_length: 1 # only warning + max_length: 30 + +type_name: + min_length: 2 # only warning + max_length: # warning and error + warning: 100 + error: 120 + excluded: iPhone # excluded via string +identifier_name: + min_length: + warning: 1 +reporter: "xcode" diff --git a/RxWebKit.xcworkspace/contents.xcworkspacedata b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata similarity index 70% rename from RxWebKit.xcworkspace/contents.xcworkspacedata rename to .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata index e2b606b..919434a 100644 --- a/RxWebKit.xcworkspace/contents.xcworkspacedata +++ b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/RxWebKit.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from RxWebKit.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to .swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/.versionrc b/.versionrc new file mode 100644 index 0000000..0cd4d62 --- /dev/null +++ b/.versionrc @@ -0,0 +1,5 @@ +{ + "releaseCommitMessageFormat": "chore(release): {{currentTag}} [skip ci]", + "compareUrlFormat": "{{host}}/{{owner}}/{{repository}}/branches/compare/{{currentTag}}%0D{{previousTag}}", + "commitUrlFormat": "{{host}}/{{owner}}/{{repository}}/commits/{{hash}}" +} diff --git a/Brewfile b/Brewfile new file mode 100644 index 0000000..6c1a838 --- /dev/null +++ b/Brewfile @@ -0,0 +1 @@ +brew "xcodegen" \ No newline at end of file diff --git a/Cartfile b/Cartfile index 6a8bfd6..3f17aa5 100644 --- a/Cartfile +++ b/Cartfile @@ -1 +1 @@ -github "ReactiveX/RxSwift" ~> 5.0 +github "ReactiveX/RxSwift" ~> 6.0 \ No newline at end of file diff --git a/Cartfile.private b/Cartfile.private index c2786fb..1adc615 100644 --- a/Cartfile.private +++ b/Cartfile.private @@ -1,2 +1,2 @@ -github "Quick/Quick" -github "Quick/Nimble" +github "Quick/Quick" ~> 3.0 +github "Quick/Nimble" ~> 9.0 diff --git a/Cartfile.resolved b/Cartfile.resolved index dc79ad3..6e8c82c 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,3 +1,3 @@ -github "Quick/Nimble" "v8.0.7" -github "Quick/Quick" "v2.2.0" -github "ReactiveX/RxSwift" "5.1.1" +github "Quick/Nimble" "v9.0.0" +github "Quick/Quick" "v3.0.0" +github "ReactiveX/RxSwift" "6.0.0" diff --git a/Dangerfile b/Dangerfile new file mode 100644 index 0000000..d7eda7a --- /dev/null +++ b/Dangerfile @@ -0,0 +1,40 @@ +# Sometimes it's a README fix, or something like that - which isn't relevant for +# including in a project's CHANGELOG for example +declared_trivial = (github.pr_title + github.pr_body).include?("#trivial") + +# Make it more obvious that a PR is a work in progress and shouldn't be merged yet +warn("PR is classed as Work in Progress") if github.pr_title.include? "[WIP]" + +# Warn summary on pull request +if github.pr_body.length < 5 + warn "Please provide a summary in the Pull Request description" +end + +# If these are all empty something has gone wrong, better to raise it in a comment +if git.modified_files.empty? && git.added_files.empty? && git.deleted_files.empty? + fail "This PR has no changes at all, this is likely a developer issue." +end + +# Warn when there is a big PR +message("Big PR") if git.lines_of_code > 500 +warn("Huge PR") if git.lines_of_code > 1000 +fail("Enormous PR. Please split this pull request.") if git.lines_of_code > 3000 + +# Warn Cartfile changes +message("Cartfile changed") if git.modified_files.include?("Cartfile") +message("Cartfile.resolved changed") if git.modified_files.include?("Cartfile.resolved") + +# Lint +swiftlint.lint_all_files = true +swiftlint.max_num_violations = 20 +swiftlint.config_file = ".swiftlint.yml" +swiftlint.lint_files fail_on_error: true + +# xcov.report( +# scheme: "RxWebKit iOS", +# project: "RxWebKit.xcodeproj", +# include_targets: "RxWebKit.framework", +# minimum_coverage_percentage: 20.0, +# derived_data_path: "Build/", +# ) + \ No newline at end of file diff --git a/Example/AppDelegate.swift b/Example/AppDelegate.swift deleted file mode 100644 index 7570bd2..0000000 --- a/Example/AppDelegate.swift +++ /dev/null @@ -1,46 +0,0 @@ -// -// AppDelegate.swift -// Example -// -// Created by Daichi Ichihara on 2016/02/06. -// Copyright © 2016年 RxSwift Community. All rights reserved. -// - -import UIKit - -@UIApplicationMain -class AppDelegate: UIResponder, UIApplicationDelegate { - - var window: UIWindow? - - - private func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { - // Override point for customization after application launch. - return true - } - - func applicationWillResignActive(_ application: UIApplication) { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. - } - - func applicationDidEnterBackground(_ application: UIApplication) { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. - } - - func applicationWillEnterForeground(_ application: UIApplication) { - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. - } - - func applicationDidBecomeActive(_ application: UIApplication) { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. - } - - func applicationWillTerminate(_ application: UIApplication) { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. - } - - -} - diff --git a/Example/AuthChallengeViewController.swift b/Example/AuthChallengeViewController.swift deleted file mode 100644 index 2ccb91f..0000000 --- a/Example/AuthChallengeViewController.swift +++ /dev/null @@ -1,54 +0,0 @@ -// -// AuthChallengeViewController.swift -// Example -// -// Created by Bob Obi on 25.10.17. -// Copyright © 2017 RxSwift Community. All rights reserved. -// - -import UIKit -import WebKit -import RxWebKit -import RxSwift -import RxCocoa - -class AuthChallengeViewController: UIViewController { - - let bag = DisposeBag() - let wkWebView = WKWebView() - - override func viewDidLoad() { - super.viewDidLoad() - view.addSubview(wkWebView) - wkWebView.load(URLRequest(url: URL(string: "https://jigsaw.w3.org/HTTP/Basic/")!)) - - wkWebView.rx - .didReceiveChallenge - .debug("didReceiveChallenge") - .subscribe(onNext: {(webView, challenge, handler) in - guard challenge.previousFailureCount == 0 else { - handler(URLSession.AuthChallengeDisposition.performDefaultHandling, nil) - return - } - /* - The correct credentials are: - - user = guest - password = guest - - You might want to start with the invalid credentials to get a sense of how this code works - */ - let credential = URLCredential(user: "bad-user", password: "bad-password", persistence: URLCredential.Persistence.forSession) - challenge.sender?.use(credential, for: challenge) - handler(URLSession.AuthChallengeDisposition.useCredential, credential) - }) - .disposed(by: bag) - } - - override func viewDidLayoutSubviews() { - super.viewDidLayoutSubviews() - let originY = UIApplication.shared.statusBarFrame.maxY - wkWebView.frame = CGRect(x: 0, y: originY, width: view.bounds.width, height: view.bounds.height) - } - -} diff --git a/Example/FailedRequestViewController.swift b/Example/FailedRequestViewController.swift deleted file mode 100644 index 5580dbd..0000000 --- a/Example/FailedRequestViewController.swift +++ /dev/null @@ -1,42 +0,0 @@ -// -// FailedRequestViewController.swift -// Example -// -// Created by Bob Godwin Obi on 10/25/17. -// Copyright © 2017 RxSwift Community. All rights reserved. -// -import UIKit -import WebKit -import RxWebKit -import RxSwift -import RxCocoa - -class FailedRequestViewController: UIViewController { - - let bag = DisposeBag() - let wkWebView = WKWebView() - - override func viewDidLoad() { - super.viewDidLoad() - view.addSubview(wkWebView) - wkWebView.load(URLRequest(url: URL(string: "https://thiswebsiteisnotexisting.com")!)) - - wkWebView.rx - .didFailProvisionalNavigation - .observeOn(MainScheduler.instance) - .debug("didFailProvisionalNavigation") - .subscribe(onNext: { [weak self] webView, navigation, error in - guard let self = self else { return } - let alert = UIAlertController(title: "FailProvisionalNavigation", message: error.localizedDescription, preferredStyle: .alert) - alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) - self.present(alert, animated: true, completion: nil) - }) - .disposed(by: bag) - } - - override func viewDidLayoutSubviews() { - super.viewDidLayoutSubviews() - let originY = UIApplication.shared.statusBarFrame.maxY - wkWebView.frame = CGRect(x: 0, y: originY, width: view.bounds.width, height: view.bounds.height) - } -} diff --git a/Example/InvokeJSFunctionViewController.swift b/Example/InvokeJSFunctionViewController.swift deleted file mode 100644 index 069bdf9..0000000 --- a/Example/InvokeJSFunctionViewController.swift +++ /dev/null @@ -1,62 +0,0 @@ -// -// InvokeJSFunctionViewController.swift -// Example -// -// Created by Jesse Hao on 2019/4/1. -// Copyright © 2019 RxSwift Community. All rights reserved. -// - -import UIKit -import WebKit -import RxWebKit -import RxSwift -import RxCocoa - -fileprivate let html = """ - - - -Invoke Javascript function - - - -

Invoke Javascript function

-

Just Press 'Invoke' at top right corner.

-

After that, pay attention to your console.

- - - - - - -""" - -class InvokeJSFunctionViewController : UIViewController { - let bag = DisposeBag() - let webview = WKWebView() - - override func viewDidLoad() { - super.viewDidLoad() - view.addSubview(webview) - self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Invoke", style: .plain, target: nil, action: nil) - self.navigationItem.rightBarButtonItem?.rx.tap.bind { [weak self] in - guard let self = self else { return } - self.webview.rx.evaluateJavaScript("presentAlert()").observeOn(MainScheduler.asyncInstance).subscribe { event in - if case .next(let body) = event, let message = body as? String { - print(message) - } - }.disposed(by: self.bag) - }.disposed(by: self.bag) - webview.loadHTMLString(html, baseURL: nil) - } - - override func viewDidLayoutSubviews() { - super.viewDidLayoutSubviews() - let originY = UIApplication.shared.statusBarFrame.maxY - webview.frame = CGRect(x: 0, y: originY, width: view.bounds.width, height: view.bounds.height) - } -} diff --git a/Example/JavaScriptAlertPanelViewController.swift b/Example/JavaScriptAlertPanelViewController.swift deleted file mode 100644 index f196f7c..0000000 --- a/Example/JavaScriptAlertPanelViewController.swift +++ /dev/null @@ -1,43 +0,0 @@ -// -// JavaScriptAlertPanelViewController.swift -// Example -// -// Created by Bob Obi on 25.10.17. -// Copyright © 2017 RxSwift Community. All rights reserved. -// - -import UIKit -import WebKit -import RxWebKit -import RxSwift -import RxCocoa - -class JavaScriptAlertPanelViewController: UIViewController { - - let bag = DisposeBag() - let wkWebView = WKWebView() - - override func viewDidLoad() { - super.viewDidLoad() - view.addSubview(wkWebView) - wkWebView.load(URLRequest(url: URL(string: "https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_alert")!)) - - wkWebView.rx - .javaScriptAlertPanel - .debug("javaScriptAlertPanel") - .subscribe(onNext: { [weak self] webView, message, frame, handler in - guard let self = self else { return } - let alert = UIAlertController(title: "JavaScriptAlertPanel", message: message, preferredStyle: .alert) - alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) - self.present(alert, animated: true, completion: nil) - handler() - }) - .disposed(by: bag) - } - - override func viewDidLayoutSubviews() { - super.viewDidLayoutSubviews() - let originY = UIApplication.shared.statusBarFrame.maxY - wkWebView.frame = CGRect(x: 0, y: originY, width: view.bounds.width, height: view.bounds.height) - } -} diff --git a/Example/JavaScriptConfirmPanelViewController.swift b/Example/JavaScriptConfirmPanelViewController.swift deleted file mode 100644 index 498b724..0000000 --- a/Example/JavaScriptConfirmPanelViewController.swift +++ /dev/null @@ -1,44 +0,0 @@ -// -// JavaScriptConfirmPanelViewController.swift -// Example -// -// Created by Bob Obi on 25.10.17. -// Copyright © 2017 RxSwift Community. All rights reserved. -// - -import UIKit -import WebKit -import RxWebKit -import RxSwift -import RxCocoa - -class JavaScriptConfirmPanelViewController: UIViewController { - - let bag = DisposeBag() - let wkWebView = WKWebView() - - override func viewDidLoad() { - super.viewDidLoad() - view.addSubview(wkWebView) - wkWebView.load(URLRequest(url: URL(string: "https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_confirm2")!)) - - wkWebView.rx - .javaScriptConfirmPanel - .debug("javaScriptConfirmPanel") - .subscribe(onNext: { [weak self] webView, message, frame, handler in - guard let self = self else { return } - let alert = UIAlertController(title: "JavaScriptConfirm", message: message, preferredStyle: .alert) - alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) - self.present(alert, animated: true, completion: nil) - handler(true) - }) - .disposed(by: bag) - } - - override func viewDidLayoutSubviews() { - super.viewDidLayoutSubviews() - let originY = UIApplication.shared.statusBarFrame.maxY - wkWebView.frame = CGRect(x: 0, y: originY, width: view.bounds.width, height: view.bounds.height) - } - -} diff --git a/Example/ObservingJSEventViewController.swift b/Example/ObservingJSEventViewController.swift deleted file mode 100644 index d55d1dc..0000000 --- a/Example/ObservingJSEventViewController.swift +++ /dev/null @@ -1,59 +0,0 @@ -// -// ObservingJSEventViewController.swift -// Example -// -// Created by Jesse Hao on 2019/4/1. -// Copyright © 2019 RxSwift Community. All rights reserved. -// - -import UIKit -import WebKit -import RxWebKit -import RxSwift -import RxCocoa - -fileprivate let html = """ - - - - - - -

Click the button to display a confirm box.

- - - -

- - - - - -""" - -class ObservingJSEventViewController : UIViewController { - let bag = DisposeBag() - let webview = WKWebView() - - override func viewDidLoad() { - super.viewDidLoad() - view.addSubview(webview) - webview.configuration.userContentController.rx.scriptMessage(forName: "RxWebKitScriptMessageHandler").bind { [weak self] scriptMessage in - guard let message = scriptMessage.body as? String else { return } - let alert = UIAlertController(title: "JS Event Observed", message: message, preferredStyle: .alert) - alert.addAction(UIAlertAction(title: "OK", style: .cancel)) - self?.present(alert, animated: true) - }.disposed(by: self.bag) - webview.loadHTMLString(html, baseURL: nil) - } - - override func viewDidLayoutSubviews() { - super.viewDidLayoutSubviews() - let originY = UIApplication.shared.statusBarFrame.maxY - webview.frame = CGRect(x: 0, y: originY, width: view.bounds.width, height: view.bounds.height) - } -} diff --git a/Example/OtherRequestViewController.swift b/Example/OtherRequestViewController.swift deleted file mode 100644 index 3e43928..0000000 --- a/Example/OtherRequestViewController.swift +++ /dev/null @@ -1,82 +0,0 @@ -// -// OtherRequestViewController.swift -// Example -// -// Created by Bob Godwin Obi on 10/25/17. -// Copyright © 2017 RxSwift Community. All rights reserved. -// - -import UIKit -import WebKit -import RxWebKit -import RxSwift -import RxCocoa - -class OtherRequestViewController: UIViewController { - - let bag = DisposeBag() - let wkWebView = WKWebView() - - override func viewDidLoad() { - super.viewDidLoad() - view.addSubview(wkWebView) - wkWebView.load(URLRequest(url: URL(string: "https://github.com/ReactiveX/RxSwift")!)) - - wkWebView.rx - .didFinishNavigation - .debug("didFinishNavigation") - .subscribe(onNext: {_ in }) - .disposed(by: bag) - - if #available(iOS 9.0, *) { - wkWebView.rx - .didTerminate - .debug("didTerminate") - .subscribe(onNext: {_ in }) - .disposed(by: bag) - } - - wkWebView.rx - .didCommitNavigation - .debug("didCommitNavigation") - .subscribe(onNext: {_ in }) - .disposed(by: bag) - - wkWebView.rx - .didStartProvisionalNavigation - .debug("didStartProvisionalNavigation") - .subscribe(onNext: {_ in}) - .disposed(by: bag) - - if #available(iOS 10.0, *) { - wkWebView.rx - .commitPreviewing - .debug("commitPreviewing") - .subscribe(onNext:{_ in}) - .disposed(by: bag) - } - - wkWebView.rx - .decidePolicyNavigationResponse - .debug("decidePolicyNavigationResponse") - .subscribe(onNext: {(_, _, handler) in - handler(.allow) - }) - .disposed(by: bag) - - wkWebView.rx - .decidePolicyNavigationAction - .debug("decidePolicyNavigationAction") - .subscribe(onNext: {(_, _, handler) in - handler(.allow) - }) - .disposed(by: bag) - } - - override func viewDidLayoutSubviews() { - super.viewDidLayoutSubviews() - let originY = UIApplication.shared.statusBarFrame.maxY - wkWebView.frame = CGRect(x: 0, y: originY, width: view.bounds.width, height: view.bounds.height) - } -} - diff --git a/Example/RedirectViewController.swift b/Example/RedirectViewController.swift deleted file mode 100644 index cb4600c..0000000 --- a/Example/RedirectViewController.swift +++ /dev/null @@ -1,43 +0,0 @@ -// -// RedirectViewController.swift -// Example -// -// Created by Bob Godwin Obi on 10/25/17. -// Copyright © 2017 RxSwift Community. All rights reserved. -// - -import UIKit -import WebKit -import RxWebKit -import RxSwift -import RxCocoa - -class RedirectViewController: UIViewController { - - let bag = DisposeBag() - let wkWebView = WKWebView() - - override func viewDidLoad() { - super.viewDidLoad() - view.addSubview(wkWebView) - wkWebView.load(URLRequest(url: URL(string: "http://www.webconfs.com/http-header-check.php")!)) - - wkWebView.rx - .didReceiveServerRedirectForProvisionalNavigation - .observeOn(MainScheduler.instance) - .debug("didReceiveServerRedirectForProvisionalNavigation") - .subscribe(onNext: { [weak self] webView, navigation in - guard let self = self else { return } - let alert = UIAlertController(title: "Redirect Navigation", message: "you have bene redirected", preferredStyle: .alert) - alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) - self.present(alert, animated: true, completion: nil) - }) - .disposed(by: bag) - } - - override func viewDidLayoutSubviews() { - super.viewDidLayoutSubviews() - let originY = UIApplication.shared.statusBarFrame.maxY - wkWebView.frame = CGRect(x: 0, y: originY, width: view.bounds.width, height: view.bounds.height) - } -} diff --git a/Example/ViewController.swift b/Example/ViewController.swift deleted file mode 100644 index 65cf2c4..0000000 --- a/Example/ViewController.swift +++ /dev/null @@ -1,105 +0,0 @@ -// -// ViewController.swift -// Example -// -// Created by Daichi Ichihara on 2016/02/06. -// Copyright © 2016年 RxSwift Community. All rights reserved. -// - -import UIKit -import WebKit -import RxWebKit -import RxSwift -import RxCocoa - -class ViewController: UIViewController { - - @IBOutlet weak var toolBar: UIToolbar! - @IBOutlet weak var backButton: UIBarButtonItem! - @IBOutlet weak var forwardButton: UIBarButtonItem! - - var wkWebView = WKWebView() - let disposeBag = DisposeBag() - - override func viewDidLoad() { - super.viewDidLoad() - self.view.addSubview(wkWebView) - let request = URLRequest(url: URL(string: "https://github.com/ReactiveX/RxSwift")!) - wkWebView.load(request) - - observeReadOnlyProperties(wkWebView: wkWebView) - observeToolBarButtonItems() - } - - override func viewDidLayoutSubviews() { - super.viewDidLayoutSubviews() - let originY = UIApplication.shared.statusBarFrame.maxY - wkWebView.frame = CGRect( - x: 0, - y: originY, - width: self.view.bounds.width, - height: toolBar.frame.minY - originY - ) - } - - private func observeReadOnlyProperties(wkWebView: WKWebView) { - wkWebView.rx.title - .share(replay: 1) - .subscribe(onNext: { - print("title: \(String(describing: $0))") - }) - .disposed(by: disposeBag) - - wkWebView.rx.url - .share(replay: 1) - .subscribe(onNext: { - print("URL: \(String(describing: $0))") - }) - .disposed(by: disposeBag) - - wkWebView.rx.estimatedProgress - .share(replay: 1) - .subscribe(onNext: { - print("estimatedProgress: \($0)") - }) - .disposed(by: disposeBag) - - wkWebView.rx.loading - .share(replay: 1) - .subscribe(onNext: { - print("loading: \($0)") - }) - .disposed(by: disposeBag) - - wkWebView.rx.canGoBack - .share(replay: 1) - .subscribe(onNext: { [weak self] in - self?.backButton.isEnabled = $0 - }) - .disposed(by: disposeBag) - - wkWebView.rx.canGoForward - .share(replay: 1) - .subscribe(onNext: { [weak self] in - self?.forwardButton.isEnabled = $0 - }) - .disposed(by: disposeBag) - } - - private func observeToolBarButtonItems() { - backButton.rx.tap - .share(replay: 1) - .subscribe(onNext: { [weak self] in - _ = self?.wkWebView.goBack() - }) - .disposed(by: disposeBag) - - forwardButton.rx.tap - .share(replay: 1) - .subscribe(onNext: { [weak self] in - _ = self?.wkWebView.goForward() - }) - .disposed(by: disposeBag) - } - -} diff --git a/Examples/Podfile b/Examples/Podfile new file mode 100644 index 0000000..a80ff33 --- /dev/null +++ b/Examples/Podfile @@ -0,0 +1,18 @@ +source "https://cdn.cocoapods.org/" +project "RxWebKitDemo.xcodeproj" +use_frameworks! + +def common + pod "RxWebKit", :path => "../" +end + +def common_tests + pod "Quick", "~> 9.0" + pod "Nimble", "~> 3.0" + pod "RxBlocking", "~> 6.0" +end + +target "RxWebKitDemo-iOS" do + platform :ios, "10.0" + common +end diff --git a/Examples/Podfile.lock b/Examples/Podfile.lock new file mode 100644 index 0000000..85f295a --- /dev/null +++ b/Examples/Podfile.lock @@ -0,0 +1,33 @@ +PODS: + - RxCocoa (6.0.0): + - RxRelay (= 6.0.0) + - RxSwift (= 6.0.0) + - RxRelay (6.0.0): + - RxSwift (= 6.0.0) + - RxSwift (6.0.0) + - RxWebKit (1.1.0): + - RxCocoa (~> 6.0) + - RxSwift (~> 6.0) + +DEPENDENCIES: + - RxWebKit (from `../`) + +SPEC REPOS: + trunk: + - RxCocoa + - RxRelay + - RxSwift + +EXTERNAL SOURCES: + RxWebKit: + :path: "../" + +SPEC CHECKSUMS: + RxCocoa: 3f79328fafa3645b34600f37c31e64c73ae3a80e + RxRelay: 8d593be109c06ea850df027351beba614b012ffb + RxSwift: c14e798c59b9f6e9a2df8fd235602e85cc044295 + RxWebKit: b971c1d83fdc0913424ec18ef7fbbad91c3a5c2f + +PODFILE CHECKSUM: 852151a70deb8d90140075b27d0598972dd88792 + +COCOAPODS: 1.10.0 diff --git a/Examples/RxWebKitDemo-iOS/AppDelegate.swift b/Examples/RxWebKitDemo-iOS/AppDelegate.swift new file mode 100644 index 0000000..cb2a363 --- /dev/null +++ b/Examples/RxWebKitDemo-iOS/AppDelegate.swift @@ -0,0 +1,41 @@ +// +// AppDelegate.swift +// Example +// +// Created by Daichi Ichihara on 2016/02/06. +// Copyright © 2016年 RxSwift Community. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + var window: UIWindow? + + private func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } +} diff --git a/Example/Assets.xcassets/AppIcon.appiconset/Contents.json b/Examples/RxWebKitDemo-iOS/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from Example/Assets.xcassets/AppIcon.appiconset/Contents.json rename to Examples/RxWebKitDemo-iOS/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/Examples/RxWebKitDemo-iOS/AuthChallengeViewController.swift b/Examples/RxWebKitDemo-iOS/AuthChallengeViewController.swift new file mode 100644 index 0000000..2687721 --- /dev/null +++ b/Examples/RxWebKitDemo-iOS/AuthChallengeViewController.swift @@ -0,0 +1,52 @@ +// +// AuthChallengeViewController.swift +// Example +// +// Created by Bob Obi on 25.10.17. +// Copyright © 2017 RxSwift Community. All rights reserved. +// + +import RxCocoa +import RxSwift +import RxWebKit +import UIKit +import WebKit + +class AuthChallengeViewController: UIViewController { + let bag = DisposeBag() + let wkWebView = WKWebView() + + override func viewDidLoad() { + super.viewDidLoad() + view.addSubview(wkWebView) + wkWebView.load(URLRequest(url: URL(string: "https://jigsaw.w3.org/HTTP/Basic/")!)) + + wkWebView.rx + .didReceiveChallenge + .debug("didReceiveChallenge") + .subscribe(onNext: { _, challenge, handler in + guard challenge.previousFailureCount == 0 else { + handler(URLSession.AuthChallengeDisposition.performDefaultHandling, nil) + return + } + /* + The correct credentials are: + + user = guest + password = guest + + You might want to start with the invalid credentials to get a sense of how this code works + */ + let credential = URLCredential(user: "bad-user", password: "bad-password", persistence: URLCredential.Persistence.forSession) + challenge.sender?.use(credential, for: challenge) + handler(URLSession.AuthChallengeDisposition.useCredential, credential) + }) + .disposed(by: bag) + } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + let originY = UIApplication.shared.statusBarFrame.maxY + wkWebView.frame = CGRect(x: 0, y: originY, width: view.bounds.width, height: view.bounds.height) + } +} diff --git a/Example/Base.lproj/Base.lproj/LaunchScreen.storyboard b/Examples/RxWebKitDemo-iOS/Base.lproj/LaunchScreen.storyboard similarity index 100% rename from Example/Base.lproj/Base.lproj/LaunchScreen.storyboard rename to Examples/RxWebKitDemo-iOS/Base.lproj/LaunchScreen.storyboard diff --git a/Example/Base.lproj/Base.lproj/Main.storyboard b/Examples/RxWebKitDemo-iOS/Base.lproj/Main.storyboard similarity index 100% rename from Example/Base.lproj/Base.lproj/Main.storyboard rename to Examples/RxWebKitDemo-iOS/Base.lproj/Main.storyboard diff --git a/Examples/RxWebKitDemo-iOS/FailedRequestViewController.swift b/Examples/RxWebKitDemo-iOS/FailedRequestViewController.swift new file mode 100644 index 0000000..e30059a --- /dev/null +++ b/Examples/RxWebKitDemo-iOS/FailedRequestViewController.swift @@ -0,0 +1,41 @@ +// +// FailedRequestViewController.swift +// Example +// +// Created by Bob Godwin Obi on 10/25/17. +// Copyright © 2017 RxSwift Community. All rights reserved. +// +import RxCocoa +import RxSwift +import RxWebKit +import UIKit +import WebKit + +class FailedRequestViewController: UIViewController { + let bag = DisposeBag() + let wkWebView = WKWebView() + + override func viewDidLoad() { + super.viewDidLoad() + view.addSubview(wkWebView) + wkWebView.load(URLRequest(url: URL(string: "https://thiswebsiteisnotexisting.com")!)) + + wkWebView.rx + .didFailProvisionalNavigation + .observe(on: MainScheduler.instance) + .debug("didFailProvisionalNavigation") + .subscribe(onNext: { [weak self] _, _, error in + guard let self = self else { return } + let alert = UIAlertController(title: "FailProvisionalNavigation", message: error.localizedDescription, preferredStyle: .alert) + alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) + self.present(alert, animated: true, completion: nil) + }) + .disposed(by: bag) + } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + let originY = UIApplication.shared.statusBarFrame.maxY + wkWebView.frame = CGRect(x: 0, y: originY, width: view.bounds.width, height: view.bounds.height) + } +} diff --git a/Example/Info.plist b/Examples/RxWebKitDemo-iOS/Info.plist similarity index 91% rename from Example/Info.plist rename to Examples/RxWebKitDemo-iOS/Info.plist index 7d6b864..c6082f6 100644 --- a/Example/Info.plist +++ b/Examples/RxWebKitDemo-iOS/Info.plist @@ -22,6 +22,11 @@ 1 LSRequiresIPhoneOS + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + UILaunchStoryboardName LaunchScreen UIMainStoryboardFile @@ -36,10 +41,5 @@ UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight - NSAppTransportSecurity - - NSAllowsArbitraryLoads - - diff --git a/Examples/RxWebKitDemo-iOS/InvokeJSFunctionViewController.swift b/Examples/RxWebKitDemo-iOS/InvokeJSFunctionViewController.swift new file mode 100644 index 0000000..b2b67d7 --- /dev/null +++ b/Examples/RxWebKitDemo-iOS/InvokeJSFunctionViewController.swift @@ -0,0 +1,62 @@ +// +// InvokeJSFunctionViewController.swift +// Example +// +// Created by Jesse Hao on 2019/4/1. +// Copyright © 2019 RxSwift Community. All rights reserved. +// + +import RxCocoa +import RxSwift +import RxWebKit +import UIKit +import WebKit + +private let html = """ + + + +Invoke Javascript function + + + +

Invoke Javascript function

+

Just Press 'Invoke' at top right corner.

+

After that, pay attention to your console.

+ + + + + + +""" + +class InvokeJSFunctionViewController: UIViewController { + let bag = DisposeBag() + let webview = WKWebView() + + override func viewDidLoad() { + super.viewDidLoad() + view.addSubview(webview) + navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Invoke", style: .plain, target: nil, action: nil) + navigationItem.rightBarButtonItem?.rx.tap.bind { [weak self] in + guard let self = self else { return } + self.webview.rx.evaluateJavaScript("presentAlert()").observe(on: MainScheduler.asyncInstance).subscribe { event in + if case let .next(body) = event, let message = body as? String { + print(message) + } + }.disposed(by: self.bag) + }.disposed(by: bag) + webview.loadHTMLString(html, baseURL: nil) + } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + let originY = UIApplication.shared.statusBarFrame.maxY + webview.frame = CGRect(x: 0, y: originY, width: view.bounds.width, height: view.bounds.height) + } +} diff --git a/Examples/RxWebKitDemo-iOS/JavaScriptAlertPanelViewController.swift b/Examples/RxWebKitDemo-iOS/JavaScriptAlertPanelViewController.swift new file mode 100644 index 0000000..3f9df2e --- /dev/null +++ b/Examples/RxWebKitDemo-iOS/JavaScriptAlertPanelViewController.swift @@ -0,0 +1,42 @@ +// +// JavaScriptAlertPanelViewController.swift +// Example +// +// Created by Bob Obi on 25.10.17. +// Copyright © 2017 RxSwift Community. All rights reserved. +// + +import RxCocoa +import RxSwift +import RxWebKit +import UIKit +import WebKit + +class JavaScriptAlertPanelViewController: UIViewController { + let bag = DisposeBag() + let wkWebView = WKWebView() + + override func viewDidLoad() { + super.viewDidLoad() + view.addSubview(wkWebView) + wkWebView.load(URLRequest(url: URL(string: "https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_alert")!)) + + wkWebView.rx + .javaScriptAlertPanel + .debug("javaScriptAlertPanel") + .subscribe(onNext: { [weak self] _, message, _, handler in + guard let self = self else { return } + let alert = UIAlertController(title: "JavaScriptAlertPanel", message: message, preferredStyle: .alert) + alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) + self.present(alert, animated: true, completion: nil) + handler() + }) + .disposed(by: bag) + } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + let originY = UIApplication.shared.statusBarFrame.maxY + wkWebView.frame = CGRect(x: 0, y: originY, width: view.bounds.width, height: view.bounds.height) + } +} diff --git a/Examples/RxWebKitDemo-iOS/JavaScriptConfirmPanelViewController.swift b/Examples/RxWebKitDemo-iOS/JavaScriptConfirmPanelViewController.swift new file mode 100644 index 0000000..93abe79 --- /dev/null +++ b/Examples/RxWebKitDemo-iOS/JavaScriptConfirmPanelViewController.swift @@ -0,0 +1,42 @@ +// +// JavaScriptConfirmPanelViewController.swift +// Example +// +// Created by Bob Obi on 25.10.17. +// Copyright © 2017 RxSwift Community. All rights reserved. +// + +import RxCocoa +import RxSwift +import RxWebKit +import UIKit +import WebKit + +class JavaScriptConfirmPanelViewController: UIViewController { + let bag = DisposeBag() + let wkWebView = WKWebView() + + override func viewDidLoad() { + super.viewDidLoad() + view.addSubview(wkWebView) + wkWebView.load(URLRequest(url: URL(string: "https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_confirm2")!)) + + wkWebView.rx + .javaScriptConfirmPanel + .debug("javaScriptConfirmPanel") + .subscribe(onNext: { [weak self] _, message, _, handler in + guard let self = self else { return } + let alert = UIAlertController(title: "JavaScriptConfirm", message: message, preferredStyle: .alert) + alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) + self.present(alert, animated: true, completion: nil) + handler(true) + }) + .disposed(by: bag) + } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + let originY = UIApplication.shared.statusBarFrame.maxY + wkWebView.frame = CGRect(x: 0, y: originY, width: view.bounds.width, height: view.bounds.height) + } +} diff --git a/Examples/RxWebKitDemo-iOS/ObservingJSEventViewController.swift b/Examples/RxWebKitDemo-iOS/ObservingJSEventViewController.swift new file mode 100644 index 0000000..794648d --- /dev/null +++ b/Examples/RxWebKitDemo-iOS/ObservingJSEventViewController.swift @@ -0,0 +1,59 @@ +// +// ObservingJSEventViewController.swift +// Example +// +// Created by Jesse Hao on 2019/4/1. +// Copyright © 2019 RxSwift Community. All rights reserved. +// + +import RxCocoa +import RxSwift +import RxWebKit +import UIKit +import WebKit + +private let html = """ + + + + + + +

Click the button to display a confirm box.

+ + + +

+ + + + + +""" + +class ObservingJSEventViewController: UIViewController { + let bag = DisposeBag() + let webview = WKWebView() + + override func viewDidLoad() { + super.viewDidLoad() + view.addSubview(webview) + webview.configuration.userContentController.rx.scriptMessage(forName: "RxWebKitScriptMessageHandler").bind { [weak self] scriptMessage in + guard let message = scriptMessage.body as? String else { return } + let alert = UIAlertController(title: "JS Event Observed", message: message, preferredStyle: .alert) + alert.addAction(UIAlertAction(title: "OK", style: .cancel)) + self?.present(alert, animated: true) + }.disposed(by: bag) + webview.loadHTMLString(html, baseURL: nil) + } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + let originY = UIApplication.shared.statusBarFrame.maxY + webview.frame = CGRect(x: 0, y: originY, width: view.bounds.width, height: view.bounds.height) + } +} diff --git a/Examples/RxWebKitDemo-iOS/OtherRequestViewController.swift b/Examples/RxWebKitDemo-iOS/OtherRequestViewController.swift new file mode 100644 index 0000000..1f43da7 --- /dev/null +++ b/Examples/RxWebKitDemo-iOS/OtherRequestViewController.swift @@ -0,0 +1,80 @@ +// +// OtherRequestViewController.swift +// Example +// +// Created by Bob Godwin Obi on 10/25/17. +// Copyright © 2017 RxSwift Community. All rights reserved. +// + +import RxCocoa +import RxSwift +import RxWebKit +import UIKit +import WebKit + +class OtherRequestViewController: UIViewController { + let bag = DisposeBag() + let wkWebView = WKWebView() + + override func viewDidLoad() { + super.viewDidLoad() + view.addSubview(wkWebView) + wkWebView.load(URLRequest(url: URL(string: "https://github.com/ReactiveX/RxSwift")!)) + + wkWebView.rx + .didFinishNavigation + .debug("didFinishNavigation") + .subscribe(onNext: { _ in }) + .disposed(by: bag) + + if #available(iOS 9.0, *) { + wkWebView.rx + .didTerminate + .debug("didTerminate") + .subscribe(onNext: { _ in }) + .disposed(by: bag) + } + + wkWebView.rx + .didCommitNavigation + .debug("didCommitNavigation") + .subscribe(onNext: { _ in }) + .disposed(by: bag) + + wkWebView.rx + .didStartProvisionalNavigation + .debug("didStartProvisionalNavigation") + .subscribe(onNext: { _ in }) + .disposed(by: bag) + + if #available(iOS 10.0, *) { + wkWebView.rx + .commitPreviewing + .debug("commitPreviewing") + .subscribe(onNext: { _ in }) + .disposed(by: bag) + } + + wkWebView.rx + .decidePolicyNavigationResponse + .debug("decidePolicyNavigationResponse") + .subscribe(onNext: { _, _, handler in + handler(.allow) + }) + .disposed(by: bag) + + wkWebView.rx + .decidePolicyNavigationAction + .debug("decidePolicyNavigationAction") + .subscribe(onNext: { _, _, handler in + handler(.allow) + }) + .disposed(by: bag) + } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + let originY = UIApplication.shared.statusBarFrame.maxY + wkWebView.frame = CGRect(x: 0, y: originY, width: view.bounds.width, height: view.bounds.height) + } +} diff --git a/Examples/RxWebKitDemo-iOS/RedirectViewController.swift b/Examples/RxWebKitDemo-iOS/RedirectViewController.swift new file mode 100644 index 0000000..4888ad9 --- /dev/null +++ b/Examples/RxWebKitDemo-iOS/RedirectViewController.swift @@ -0,0 +1,42 @@ +// +// RedirectViewController.swift +// Example +// +// Created by Bob Godwin Obi on 10/25/17. +// Copyright © 2017 RxSwift Community. All rights reserved. +// + +import RxCocoa +import RxSwift +import RxWebKit +import UIKit +import WebKit + +class RedirectViewController: UIViewController { + let bag = DisposeBag() + let wkWebView = WKWebView() + + override func viewDidLoad() { + super.viewDidLoad() + view.addSubview(wkWebView) + wkWebView.load(URLRequest(url: URL(string: "http://www.webconfs.com/http-header-check.php")!)) + + wkWebView.rx + .didReceiveServerRedirectForProvisionalNavigation + .observe(on: MainScheduler.instance) + .debug("didReceiveServerRedirectForProvisionalNavigation") + .subscribe(onNext: { [weak self] _, _ in + guard let self = self else { return } + let alert = UIAlertController(title: "Redirect Navigation", message: "you have bene redirected", preferredStyle: .alert) + alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) + self.present(alert, animated: true, completion: nil) + }) + .disposed(by: bag) + } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + let originY = UIApplication.shared.statusBarFrame.maxY + wkWebView.frame = CGRect(x: 0, y: originY, width: view.bounds.width, height: view.bounds.height) + } +} diff --git a/Examples/RxWebKitDemo-iOS/ViewController.swift b/Examples/RxWebKitDemo-iOS/ViewController.swift new file mode 100644 index 0000000..5787895 --- /dev/null +++ b/Examples/RxWebKitDemo-iOS/ViewController.swift @@ -0,0 +1,101 @@ +// +// ViewController.swift +// Example +// +// Created by Daichi Ichihara on 2016/02/06. +// Copyright © 2016年 RxSwift Community. All rights reserved. +// + +import RxCocoa +import RxSwift +import RxWebKit +import UIKit +import WebKit + +class ViewController: UIViewController { + @IBOutlet var toolBar: UIToolbar! + @IBOutlet var backButton: UIBarButtonItem! + @IBOutlet var forwardButton: UIBarButtonItem! + + var wkWebView = WKWebView() + let disposeBag = DisposeBag() + + override func viewDidLoad() { + super.viewDidLoad() + view.addSubview(wkWebView) + let request = URLRequest(url: URL(string: "https://github.com/ReactiveX/RxSwift")!) + wkWebView.load(request) + + observeReadOnlyProperties(wkWebView: wkWebView) + observeToolBarButtonItems() + } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + let originY = UIApplication.shared.statusBarFrame.maxY + wkWebView.frame = CGRect(x: 0, + y: originY, + width: view.bounds.width, + height: toolBar.frame.minY - originY) + } + + private func observeReadOnlyProperties(wkWebView: WKWebView) { + wkWebView.rx.title + .share(replay: 1) + .subscribe(onNext: { + print("title: \(String(describing: $0))") + }) + .disposed(by: disposeBag) + + wkWebView.rx.url + .share(replay: 1) + .subscribe(onNext: { + print("URL: \(String(describing: $0))") + }) + .disposed(by: disposeBag) + + wkWebView.rx.estimatedProgress + .share(replay: 1) + .subscribe(onNext: { + print("estimatedProgress: \($0)") + }) + .disposed(by: disposeBag) + + wkWebView.rx.loading + .share(replay: 1) + .subscribe(onNext: { + print("loading: \($0)") + }) + .disposed(by: disposeBag) + + wkWebView.rx.canGoBack + .share(replay: 1) + .subscribe(onNext: { [weak self] in + self?.backButton.isEnabled = $0 + }) + .disposed(by: disposeBag) + + wkWebView.rx.canGoForward + .share(replay: 1) + .subscribe(onNext: { [weak self] in + self?.forwardButton.isEnabled = $0 + }) + .disposed(by: disposeBag) + } + + private func observeToolBarButtonItems() { + backButton.rx.tap + .share(replay: 1) + .subscribe(onNext: { [weak self] in + _ = self?.wkWebView.goBack() + }) + .disposed(by: disposeBag) + + forwardButton.rx.tap + .share(replay: 1) + .subscribe(onNext: { [weak self] in + _ = self?.wkWebView.goForward() + }) + .disposed(by: disposeBag) + } +} diff --git a/Examples/RxWebKitDemo.xcodeproj/project.pbxproj b/Examples/RxWebKitDemo.xcodeproj/project.pbxproj new file mode 100644 index 0000000..8d983d2 --- /dev/null +++ b/Examples/RxWebKitDemo.xcodeproj/project.pbxproj @@ -0,0 +1,447 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 51; + objects = { + +/* Begin PBXBuildFile section */ + 0F4E872DDF4B5E91C5EFC394 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FF8E0502016D50D2B551A44D /* Assets.xcassets */; }; + 0FC13316A2986C738747A958 /* Pods_RxWebKitDemo_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DCDA6ADDCF7DCCF0645E71B /* Pods_RxWebKitDemo_iOS.framework */; }; + 416202851F7D23D42B4E3ACC /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7850E4A3C3EB0584D8C50C8E /* Main.storyboard */; }; + 51A920755D45B1AD33050E13 /* JavaScriptConfirmPanelViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67383D3BB45EAE734EEB0945 /* JavaScriptConfirmPanelViewController.swift */; }; + 5AD904E0EC5D026EEF9AD96E /* InvokeJSFunctionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2CE25375378C51869118038 /* InvokeJSFunctionViewController.swift */; }; + 68AE76C02BE251B948B5971E /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B235C84FC5B15ABF64C02765 /* ViewController.swift */; }; + 69C53DACD5535372DCEEAEA4 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BC808AF814556C74D4B56D3 /* AppDelegate.swift */; }; + 8B0606AC9FF074BDEEB51204 /* RedirectViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02495EC2702A95EFDB62BB83 /* RedirectViewController.swift */; }; + 8F23B93D163F1B1533112204 /* AuthChallengeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F77E0E094CD7B89CC4D9201 /* AuthChallengeViewController.swift */; }; + A681B337A7F787FE5051CEA4 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 42F3D317324CD5D2282E195F /* LaunchScreen.storyboard */; }; + A998C686859864F17D0E108A /* JavaScriptAlertPanelViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF92D7F8ABBEF51FE9CE1848 /* JavaScriptAlertPanelViewController.swift */; }; + AB55E3BE2BD24D1EAE5FAE6E /* OtherRequestViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8993EA87389EBAD2B147FC6E /* OtherRequestViewController.swift */; }; + B8F35BAFFBEC4158BFAF948D /* FailedRequestViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA0CC8F192C63B42223073D9 /* FailedRequestViewController.swift */; }; + D0DE8067F3B6E2394B9CCF14 /* ObservingJSEventViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C5E731711A9A5FA734B1394 /* ObservingJSEventViewController.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 02495EC2702A95EFDB62BB83 /* RedirectViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RedirectViewController.swift; sourceTree = ""; }; + 1DCDA6ADDCF7DCCF0645E71B /* Pods_RxWebKitDemo_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RxWebKitDemo_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 1F77E0E094CD7B89CC4D9201 /* AuthChallengeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthChallengeViewController.swift; sourceTree = ""; }; + 273022E998F5046156C62AE2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 394BA1E5F561FEE3EA7BFBBE /* Pods-RxWebKitDemo-iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxWebKitDemo-iOS.debug.xcconfig"; path = "Target Support Files/Pods-RxWebKitDemo-iOS/Pods-RxWebKitDemo-iOS.debug.xcconfig"; sourceTree = ""; }; + 5454C0A872931E53AD9B57C6 /* Pods-RxWebKitDemo-iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxWebKitDemo-iOS.release.xcconfig"; path = "Target Support Files/Pods-RxWebKitDemo-iOS/Pods-RxWebKitDemo-iOS.release.xcconfig"; sourceTree = ""; }; + 67383D3BB45EAE734EEB0945 /* JavaScriptConfirmPanelViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JavaScriptConfirmPanelViewController.swift; sourceTree = ""; }; + 6BC808AF814556C74D4B56D3 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 6C5E731711A9A5FA734B1394 /* ObservingJSEventViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObservingJSEventViewController.swift; sourceTree = ""; }; + 78B60DDD3224E75ECF52C6FD /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 8993EA87389EBAD2B147FC6E /* OtherRequestViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OtherRequestViewController.swift; sourceTree = ""; }; + AF92D7F8ABBEF51FE9CE1848 /* JavaScriptAlertPanelViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JavaScriptAlertPanelViewController.swift; sourceTree = ""; }; + B235C84FC5B15ABF64C02765 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + BAFD2E936E2CA285EC96A81A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; + BF27E340C8FAB4BBD5ECAB7A /* RxWebKitDemo-iOS.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = "RxWebKitDemo-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + CA0CC8F192C63B42223073D9 /* FailedRequestViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FailedRequestViewController.swift; sourceTree = ""; }; + D2CE25375378C51869118038 /* InvokeJSFunctionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvokeJSFunctionViewController.swift; sourceTree = ""; }; + FF8E0502016D50D2B551A44D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + DA27D96ACD51D793DE041E13 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 0FC13316A2986C738747A958 /* Pods_RxWebKitDemo_iOS.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 34C4EE73D50A17C9C6C7D2D1 /* RxWebKitDemo-iOS */ = { + isa = PBXGroup; + children = ( + 6BC808AF814556C74D4B56D3 /* AppDelegate.swift */, + FF8E0502016D50D2B551A44D /* Assets.xcassets */, + 1F77E0E094CD7B89CC4D9201 /* AuthChallengeViewController.swift */, + CA0CC8F192C63B42223073D9 /* FailedRequestViewController.swift */, + BAFD2E936E2CA285EC96A81A /* Info.plist */, + D2CE25375378C51869118038 /* InvokeJSFunctionViewController.swift */, + AF92D7F8ABBEF51FE9CE1848 /* JavaScriptAlertPanelViewController.swift */, + 67383D3BB45EAE734EEB0945 /* JavaScriptConfirmPanelViewController.swift */, + 42F3D317324CD5D2282E195F /* LaunchScreen.storyboard */, + 7850E4A3C3EB0584D8C50C8E /* Main.storyboard */, + 6C5E731711A9A5FA734B1394 /* ObservingJSEventViewController.swift */, + 8993EA87389EBAD2B147FC6E /* OtherRequestViewController.swift */, + 02495EC2702A95EFDB62BB83 /* RedirectViewController.swift */, + B235C84FC5B15ABF64C02765 /* ViewController.swift */, + ); + path = "RxWebKitDemo-iOS"; + sourceTree = ""; + }; + 371651DACA587BC55A7E7640 = { + isa = PBXGroup; + children = ( + 34C4EE73D50A17C9C6C7D2D1 /* RxWebKitDemo-iOS */, + E74AE23B24B45603B7C1D9EB /* Products */, + 9CDDEB818432BA25027FEFD7 /* Pods */, + 596EEBB07D9B69241826BC8A /* Frameworks */, + ); + indentWidth = 2; + sourceTree = ""; + tabWidth = 2; + usesTabs = 0; + }; + 596EEBB07D9B69241826BC8A /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1DCDA6ADDCF7DCCF0645E71B /* Pods_RxWebKitDemo_iOS.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 9CDDEB818432BA25027FEFD7 /* Pods */ = { + isa = PBXGroup; + children = ( + 394BA1E5F561FEE3EA7BFBBE /* Pods-RxWebKitDemo-iOS.debug.xcconfig */, + 5454C0A872931E53AD9B57C6 /* Pods-RxWebKitDemo-iOS.release.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + E74AE23B24B45603B7C1D9EB /* Products */ = { + isa = PBXGroup; + children = ( + BF27E340C8FAB4BBD5ECAB7A /* RxWebKitDemo-iOS.app */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + E51E3B9703906D101ACE41C3 /* RxWebKitDemo-iOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = 371BF12DBE56FCA7A0782331 /* Build configuration list for PBXNativeTarget "RxWebKitDemo-iOS" */; + buildPhases = ( + 005FEDA3007E886EB6E1D7ED /* [CP] Check Pods Manifest.lock */, + 75BBAB6732D0F007D0B6F829 /* Sources */, + AB2CBEDF5530339FDDF96678 /* Resources */, + DA27D96ACD51D793DE041E13 /* Frameworks */, + 2655EF60EC2F238453D83D3E /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "RxWebKitDemo-iOS"; + productName = "RxWebKitDemo-iOS"; + productReference = BF27E340C8FAB4BBD5ECAB7A /* RxWebKitDemo-iOS.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 061ADB01D8C8FC0D8F6C4F00 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1140; + ORGANIZATIONNAME = RxSwiftCommunity; + }; + buildConfigurationList = EEE0C7A3A904915DCC796A5E /* Build configuration list for PBXProject "RxWebKitDemo" */; + compatibilityVersion = "Xcode 10.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + Base, + en, + ); + mainGroup = 371651DACA587BC55A7E7640; + productRefGroup = E74AE23B24B45603B7C1D9EB /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + E51E3B9703906D101ACE41C3 /* RxWebKitDemo-iOS */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + AB2CBEDF5530339FDDF96678 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0F4E872DDF4B5E91C5EFC394 /* Assets.xcassets in Resources */, + A681B337A7F787FE5051CEA4 /* LaunchScreen.storyboard in Resources */, + 416202851F7D23D42B4E3ACC /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 005FEDA3007E886EB6E1D7ED /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RxWebKitDemo-iOS-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 2655EF60EC2F238453D83D3E /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-RxWebKitDemo-iOS/Pods-RxWebKitDemo-iOS-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-RxWebKitDemo-iOS/Pods-RxWebKitDemo-iOS-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RxWebKitDemo-iOS/Pods-RxWebKitDemo-iOS-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 75BBAB6732D0F007D0B6F829 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 69C53DACD5535372DCEEAEA4 /* AppDelegate.swift in Sources */, + 8F23B93D163F1B1533112204 /* AuthChallengeViewController.swift in Sources */, + B8F35BAFFBEC4158BFAF948D /* FailedRequestViewController.swift in Sources */, + 5AD904E0EC5D026EEF9AD96E /* InvokeJSFunctionViewController.swift in Sources */, + A998C686859864F17D0E108A /* JavaScriptAlertPanelViewController.swift in Sources */, + 51A920755D45B1AD33050E13 /* JavaScriptConfirmPanelViewController.swift in Sources */, + D0DE8067F3B6E2394B9CCF14 /* ObservingJSEventViewController.swift in Sources */, + AB55E3BE2BD24D1EAE5FAE6E /* OtherRequestViewController.swift in Sources */, + 8B0606AC9FF074BDEEB51204 /* RedirectViewController.swift in Sources */, + 68AE76C02BE251B948B5971E /* ViewController.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 42F3D317324CD5D2282E195F /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 78B60DDD3224E75ECF52C6FD /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; + 7850E4A3C3EB0584D8C50C8E /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 273022E998F5046156C62AE2 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 0291B6B23A5DC2BB526297F1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 14C4DB54A739E77D76EABD7D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 394BA1E5F561FEE3EA7BFBBE /* Pods-RxWebKitDemo-iOS.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = "$(APP_ICON_NAME)"; + CODE_SIGN_IDENTITY = "iPhone Developer"; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + INFOPLIST_FILE = "RxWebKitDemo-iOS/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_BUNDLE_IDENTIFIER = RxSwiftCommunity.RxWebKit.iOSDemo; + PRODUCT_NAME = "RxWebKitDemo-iOS"; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 2BEA7C2E3AEE77C4A89899AD /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 5454C0A872931E53AD9B57C6 /* Pods-RxWebKitDemo-iOS.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = "$(APP_ICON_NAME)"; + CODE_SIGN_IDENTITY = "iPhone Developer"; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + INFOPLIST_FILE = "RxWebKitDemo-iOS/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_BUNDLE_IDENTIFIER = RxSwiftCommunity.RxWebKit.iOSDemo; + PRODUCT_NAME = "RxWebKitDemo-iOS"; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + D52540FD1E2A84B9AB1C72A5 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "DEBUG=1", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 371BF12DBE56FCA7A0782331 /* Build configuration list for PBXNativeTarget "RxWebKitDemo-iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 14C4DB54A739E77D76EABD7D /* Debug */, + 2BEA7C2E3AEE77C4A89899AD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + EEE0C7A3A904915DCC796A5E /* Build configuration list for PBXProject "RxWebKitDemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D52540FD1E2A84B9AB1C72A5 /* Debug */, + 0291B6B23A5DC2BB526297F1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 061ADB01D8C8FC0D8F6C4F00 /* Project object */; +} diff --git a/Examples/RxWebKitDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Examples/RxWebKitDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..8704197 --- /dev/null +++ b/Examples/RxWebKitDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/RxWebKit.xcodeproj/xcshareddata/xcschemes/Example.xcscheme b/Examples/RxWebKitDemo.xcodeproj/xcshareddata/xcschemes/RxWebKitDemo-iOS.xcscheme similarity index 62% rename from RxWebKit.xcodeproj/xcshareddata/xcschemes/Example.xcscheme rename to Examples/RxWebKitDemo.xcodeproj/xcshareddata/xcschemes/RxWebKitDemo-iOS.xcscheme index f1331ab..d32ea0c 100644 --- a/RxWebKit.xcodeproj/xcshareddata/xcschemes/Example.xcscheme +++ b/Examples/RxWebKitDemo.xcodeproj/xcshareddata/xcschemes/RxWebKitDemo-iOS.xcscheme @@ -1,6 +1,6 @@ + BlueprintIdentifier = "E51E3B9703906D101ACE41C3" + BuildableName = "RxWebKitDemo-iOS.app" + BlueprintName = "RxWebKitDemo-iOS" + ReferencedContainer = "container:RxWebKitDemo.xcodeproj"> @@ -26,30 +26,19 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + onlyGenerateCoverageForSpecifiedTargets = "NO" shouldUseLaunchSchemeArgsEnv = "YES"> - - - - + BlueprintIdentifier = "E51E3B9703906D101ACE41C3" + BuildableName = "RxWebKitDemo-iOS.app" + BlueprintName = "RxWebKitDemo-iOS" + ReferencedContainer = "container:RxWebKitDemo.xcodeproj"> - - + BlueprintIdentifier = "E51E3B9703906D101ACE41C3" + BuildableName = "RxWebKitDemo-iOS.app" + BlueprintName = "RxWebKitDemo-iOS" + ReferencedContainer = "container:RxWebKitDemo.xcodeproj"> - - + + + BlueprintIdentifier = "E51E3B9703906D101ACE41C3" + BuildableName = "RxWebKitDemo-iOS.app" + BlueprintName = "RxWebKitDemo-iOS" + ReferencedContainer = "container:RxWebKitDemo.xcodeproj"> + + diff --git a/Examples/RxWebKitDemo.xcworkspace/contents.xcworkspacedata b/Examples/RxWebKitDemo.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..915ca08 --- /dev/null +++ b/Examples/RxWebKitDemo.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Examples/RxWebKitDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Examples/RxWebKitDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Examples/RxWebKitDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Examples/pod_install.sh b/Examples/pod_install.sh new file mode 100644 index 0000000..c837640 --- /dev/null +++ b/Examples/pod_install.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +set -eo pipefail +export RELEASE_VERSION="$(git describe --abbrev=0 | tr -d '\n')" +RELEASE_VERSION=${RELEASE_VERSION:1} +xcodegen +pod install --repo-update +open RxWebKitDemo.xcworkspace \ No newline at end of file diff --git a/Examples/project.yml b/Examples/project.yml new file mode 100644 index 0000000..f3685ae --- /dev/null +++ b/Examples/project.yml @@ -0,0 +1,46 @@ +name: RxWebKitDemo +options: + minimumXcodeGenVersion: "2.15.1" + developmentLanguage: en + usesTabs: false + indentWidth: 2 + tabWidth: 2 + xcodeVersion: "1140" + deploymentTarget: + iOS: "10.0" + defaultConfig: "Release" +configs: + Debug: debug + Release: release +attributes: + ORGANIZATIONNAME: RxSwiftCommunity +schemes: + RxWebKitDemo-iOS: + scheme: {} + build: + parallelizeBuild: true + buildImplicitDependencies: true + targets: + RxWebKitDemo-iOS: all + run: + config: Debug + profile: + config: Release + analyze: + config: Debug + archive: + config: Release + revealArchiveInOrganizer: true +targets: + RxWebKitDemo-iOS: + type: application + platform: iOS + deploymentTarget: "10.0" + sources: [RxWebKitDemo-iOS] + settings: + INFOPLIST_FILE: RxWebKitDemo-iOS/Info.plist + PRODUCT_NAME: RxWebKitDemo-iOS + OTHER_LDFLAGS: -ObjC + PRODUCT_BUNDLE_IDENTIFIER: RxSwiftCommunity.RxWebKit.iOSDemo + ASSETCATALOG_COMPILER_APPICON_NAME: $(APP_ICON_NAME) + DEBUG_INFORMATION_FORMAT: dwarf-with-dsym \ No newline at end of file diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..86b85a3 --- /dev/null +++ b/Gemfile @@ -0,0 +1,6 @@ +source 'https://rubygems.org' + +gem 'cocoapods', '~> 1.10' +gem 'danger', '~> 8.0' +gem 'danger-swiftlint', '~> 0.20' +gem 'jazzy', '~> 0.13' \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..8fc1cdb --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,167 @@ +GEM + remote: https://rubygems.org/ + specs: + CFPropertyList (3.0.3) + activesupport (5.2.4.4) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 0.7, < 2) + minitest (~> 5.1) + tzinfo (~> 1.1) + addressable (2.7.0) + public_suffix (>= 2.0.2, < 5.0) + algoliasearch (1.27.5) + httpclient (~> 2.8, >= 2.8.3) + json (>= 1.5.1) + atomos (0.1.3) + claide (1.0.3) + claide-plugins (0.9.2) + cork + nap + open4 (~> 1.3) + cocoapods (1.10.0) + addressable (~> 2.6) + claide (>= 1.0.2, < 2.0) + cocoapods-core (= 1.10.0) + cocoapods-deintegrate (>= 1.0.3, < 2.0) + cocoapods-downloader (>= 1.4.0, < 2.0) + cocoapods-plugins (>= 1.0.0, < 2.0) + cocoapods-search (>= 1.0.0, < 2.0) + cocoapods-trunk (>= 1.4.0, < 2.0) + cocoapods-try (>= 1.1.0, < 2.0) + colored2 (~> 3.1) + escape (~> 0.0.4) + fourflusher (>= 2.3.0, < 3.0) + gh_inspector (~> 1.0) + molinillo (~> 0.6.6) + nap (~> 1.0) + ruby-macho (~> 1.4) + xcodeproj (>= 1.19.0, < 2.0) + cocoapods-core (1.10.0) + activesupport (> 5.0, < 6) + addressable (~> 2.6) + algoliasearch (~> 1.0) + concurrent-ruby (~> 1.1) + fuzzy_match (~> 2.0.4) + nap (~> 1.0) + netrc (~> 0.11) + public_suffix + typhoeus (~> 1.0) + cocoapods-deintegrate (1.0.4) + cocoapods-downloader (1.4.0) + cocoapods-plugins (1.0.0) + nap + cocoapods-search (1.0.0) + cocoapods-trunk (1.5.0) + nap (>= 0.8, < 2.0) + netrc (~> 0.11) + cocoapods-try (1.2.0) + colored2 (3.1.2) + concurrent-ruby (1.1.7) + cork (0.3.0) + colored2 (~> 3.1) + danger (8.2.1) + claide (~> 1.0) + claide-plugins (>= 0.9.2) + colored2 (~> 3.1) + cork (~> 0.1) + faraday (>= 0.9.0, < 2.0) + faraday-http-cache (~> 2.0) + git (~> 1.7) + kramdown (~> 2.3) + kramdown-parser-gfm (~> 1.0) + no_proxy_fix + octokit (~> 4.7) + terminal-table (~> 1) + danger-swiftlint (0.24.5) + danger + rake (> 10) + thor (~> 0.19) + escape (0.0.4) + ethon (0.12.0) + ffi (>= 1.3.0) + faraday (1.3.0) + faraday-net_http (~> 1.0) + multipart-post (>= 1.2, < 3) + ruby2_keywords + faraday-http-cache (2.2.0) + faraday (>= 0.8) + faraday-net_http (1.0.0) + ffi (1.14.2) + fourflusher (2.3.1) + fuzzy_match (2.0.4) + gh_inspector (1.1.3) + git (1.8.1) + rchardet (~> 1.8) + httpclient (2.8.3) + i18n (1.8.6) + concurrent-ruby (~> 1.0) + jazzy (0.13.6) + cocoapods (~> 1.5) + mustache (~> 1.1) + open4 + redcarpet (~> 3.4) + rouge (>= 2.0.6, < 4.0) + sassc (~> 2.1) + sqlite3 (~> 1.3) + xcinvoke (~> 0.3.0) + json (2.5.1) + kramdown (2.3.0) + rexml + kramdown-parser-gfm (1.1.0) + kramdown (~> 2.0) + liferaft (0.0.6) + minitest (5.14.2) + molinillo (0.6.6) + multipart-post (2.1.1) + mustache (1.1.1) + nanaimo (0.3.0) + nap (1.1.0) + netrc (0.11.0) + no_proxy_fix (0.1.2) + octokit (4.20.0) + faraday (>= 0.9) + sawyer (~> 0.8.0, >= 0.5.3) + open4 (1.3.4) + public_suffix (4.0.6) + rake (13.0.3) + rchardet (1.8.0) + redcarpet (3.5.1) + rexml (3.2.4) + rouge (3.26.0) + ruby-macho (1.4.0) + ruby2_keywords (0.0.2) + sassc (2.4.0) + ffi (~> 1.9) + sawyer (0.8.2) + addressable (>= 2.3.5) + faraday (> 0.8, < 2.0) + sqlite3 (1.4.2) + terminal-table (1.8.0) + unicode-display_width (~> 1.1, >= 1.1.1) + thor (0.20.3) + thread_safe (0.3.6) + typhoeus (1.4.0) + ethon (>= 0.9.0) + tzinfo (1.2.9) + thread_safe (~> 0.1) + unicode-display_width (1.7.0) + xcinvoke (0.3.0) + liferaft (~> 0.0.6) + xcodeproj (1.19.0) + CFPropertyList (>= 2.3.3, < 4.0) + atomos (~> 0.1.3) + claide (>= 1.0.2, < 2.0) + colored2 (~> 3.1) + nanaimo (~> 0.3.0) + +PLATFORMS + x86_64-darwin-20 + +DEPENDENCIES + cocoapods (~> 1.10) + danger (~> 8.0) + danger-swiftlint (~> 0.20) + jazzy (~> 0.13) + +BUNDLED WITH + 2.2.4 diff --git a/LICENSE.md b/LICENSE.md index 23269fe..d031fd1 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,9 +1,21 @@ -**The MIT License** -**Copyright © 2016 Daichi Ichihara ** -**All rights reserved.** +The MIT License (MIT) -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2015 Junior B. -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/Package.swift b/Package.swift new file mode 100644 index 0000000..ac01093 --- /dev/null +++ b/Package.swift @@ -0,0 +1,32 @@ +// swift-tools-version:5.0 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package(name: "RxWebKit", + platforms: [ + .macOS(.v10_13), .iOS(.v9) + ], + products: [ + // Products define the executables and libraries produced by a package, and make them visible to other packages. + .library(name: "RxWebKit", + targets: ["RxWebKit"]) + ], + + dependencies: [ + // Dependencies declare other packages that this package depends on. + // Dependencies declare other packages that this package depends on. + .package(url: "https://github.com/ReactiveX/RxSwift.git", .upToNextMajor(from: "6.0.0")), + // Development + .package(url: "https://github.com/Quick/Quick.git", .upToNextMajor(from: "3.0.0")), // dev + .package(url: "https://github.com/Quick/Nimble.git", .upToNextMajor(from: "9.0.0")) // dev + ], + + targets: [ + // Targets are the basic building blocks of a package. A target can define a module or a test suite. + // Targets can depend on other targets in this package, and on products in packages which this package depends on. + .target(name: "RxWebKit", dependencies: ["RxSwift", "RxCocoa"], + path: "Sources"), + .testTarget(name: "RxWebKitTests", dependencies: ["RxWebKit", "Quick", "Nimble", "RxTest"]) // dev + ], + swiftLanguageVersions: [.v5]) diff --git a/README.md b/README.md index 8072486..9c55b6c 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,183 @@ -# RxWebKit +RxWebKit +=== -RxWebKit is a [RxSwift](https://github.com/ReactiveX/RxSwift) wrapper for `WebKit`. +RxWebKit is a [RxSwift](https://github.com/ReactiveX/RxSwift) wrapper around the elegant HTTP networking in Swift [Alamofire](https://github.com/Alamofire/Alamofire). -[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) +![Create release](https://github.com/RxSwiftCommunity/RxWebKit/workflows/Create%20release/badge.svg) [![Version](https://img.shields.io/cocoapods/v/RxWebKit.svg?style=flat)](http://cocoapods.org/pods/RxWebKit) [![License](https://img.shields.io/cocoapods/l/RxWebKit.svg?style=flat)](http://cocoapods.org/pods/RxWebKit) [![Platform](https://img.shields.io/cocoapods/p/RxWebKit.svg?style=flat)](http://cocoapods.org/pods/RxWebKit) +[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) -## Example Usages +## Getting Started -```swift -// MARK: Setup WKWebView +Wrapping RxSwift around Alamofire makes working with network requests a smoother and nicer task. Alamofire is a very powerful framework and RxSwift add the ability to compose responses in a simple and effective way. -let webView = WKWebView(frame: self.view.bounds) -self.view.addSubview(webView) +A basic usage is (considering a simple currency converter): +```swift +let formatter = NSNumberFormatter() +formatter.numberStyle = .currencyStyle +formatter.currencyCode = "USD" +if let fromValue = NSNumberFormatter().numberFromString(self.fromTextField.text!) { + +RxWebKit.requestJSON(.get, sourceStringURL) + .debug() + .subscribe(onNext: { [weak self] (r, json) in + if let dict = json as? [String: AnyObject] { + let valDict = dict["rates"] as! Dictionary + if let conversionRate = valDict["USD"] as? Float { + self?.toTextField.text = formatter + .string(from: NSNumber(value: conversionRate * fromValue)) + } + } + }, onError: { [weak self] (error) in + self?.displayError(error as NSError) + }) + .disposed(by: disposeBag) + +} else { + self.toTextField.text = "Invalid Input!" +} +``` -// MARK: Observing properties +## Example Usages -webView.rx.title - .subscribe(onNext: { - print("title: \($0)") - }) - .disposed(by: disposeBag) +Currently, the library features the following extensions: -webView.rx.url - .subscribe(onNext: { - print("URL: \($0)") - }) - .disposed(by: disposeBag) +```swift +let stringURL = "" + +// MARK: URLSession simple and fast +let session = URLSession.shared() + +_ = session.rx + .response(.get, stringURL) + .observeOn(MainScheduler.instance) + .subscribe { print($0) } + +_ = session.rx + .json(.get, stringURL) + .observeOn(MainScheduler.instance) + .subscribe { print($0) } + +_ = session.rx + .data(.get, stringURL) + .observeOn(MainScheduler.instance) + .subscribe { print($0) } + +// MARK: With Alamofire engine + +_ = json(.get, stringURL) + .observeOn(MainScheduler.instance) + .subscribe { print($0) } + +// validation +_ = request(.get, stringURL) + .validate(statusCode: 200..<300) + .validate(contentType: ["application/json"]) + .responseJSON() + .observeOn(MainScheduler.instance) + .subscribe { print($0) } + +// progress +_ = request(.get, stringURL) + .progress() + .observeOn(MainScheduler.instance) + .subscribe { print($0) } + +// just fire upload and display progress +_ = upload(Data(), urlRequest: try! RxWebKit.urlRequest(.get, stringURL)) + .progress() + .observeOn(MainScheduler.instance) + .subscribe { print($0) } + +// progress and final result +// uploading files with progress showing is processing intensive operation anyway, so +// this doesn't add much overhead +_ = request(.get, stringURL) + .flatMap { request -> Observable<(Data?, RxProgress)> in + let dataPart = request.rx + .data() + .map { d -> Data? in d } + .startWith(nil as Data?) + let progressPart = request.rx.progress() + return Observable.combineLatest(dataPart, progressPart) { ($0, $1) } + } + .observeOn(MainScheduler.instance) + .subscribe { print($0) } + + +// MARK: Alamofire Session +// same methods with any Alamofire Session + +let session = Session.default + +// simple case +_ = session.rx.json(.get, stringURL) + .observeOn(MainScheduler.instance) + .subscribe { print($0) } + +// URLHTTPResponse + JSON +_ = session.rx.responseJSON(.get, stringURL) + .observeOn(MainScheduler.instance) + .subscribe { print($0) } + +// URLHTTPResponse + String +_ = session.rx.responseString(.get, stringURL) + .observeOn(MainScheduler.instance) + .subscribe { print($0) } + +// URLHTTPResponse + Validation + JSON +_ = session.rx.request(.get, stringURL) + .validate(statusCode: 200 ..< 300) + .validate(contentType: ["text/json"]) + .json() + .observeOn(MainScheduler.instance) + .subscribe { print($0) } + +// URLHTTPResponse + Validation + URLHTTPResponse + JSON +_ = session.rx.request(.get, stringURL) + .validate(statusCode: 200 ..< 300) + .validate(contentType: ["text/json"]) + .responseJSON() + .observeOn(MainScheduler.instance) + .subscribe { print($0) } + +// URLHTTPResponse + Validation + URLHTTPResponse + String + Progress +_ = session.rx.request(.get, stringURL) + .validate(statusCode: 200 ..< 300) + .validate(contentType: ["text/something"]) + .flatMap { request -> Observable<(String?, RxProgress)> in + let stringPart = request.rx + .string() + .map { d -> String? in d } + .startWith(nil as String?) + let progressPart = request.rx.progress() + return Observable.combineLatest(stringPart, progressPart) { ($0, $1) } + } + .observeOn(MainScheduler.instance) + .subscribe { print($0) } + +// Interceptor + URLHTTPResponse + Validation + JSON +let adapter = // Some RequestAdapter +let retrier = // Some RequestRetrier +let interceptor = Interceptor(adapter: adapter, retrier: retrier) +_ = session.rx.request(.get, stringURL) + .validate() + .validate(contentType: ["text/json"]) + .responseJSON() + .observeOn(MainScheduler.instance) + .subscribe { print($0) } ``` ## Installation +There are three ways to install RxWebKit + ### CocoaPods -Add to `Podfile`: +Just add to your project's `Podfile`: ``` pod 'RxWebKit' @@ -43,24 +185,48 @@ pod 'RxWebKit' ### Carthage -Add to `Cartfile`: +Add following to `Cartfile`: ``` -github "RxSwiftCommunity/RxWebKit" +github "RxSwiftCommunity/RxWebKit" ~> 6.1 ``` -Run `carthage update --platform iOS` +### Swift Package manager -Add run script build phase `/usr/local/bin/carthage copy-frameworks` with input files being: +Create a `Package.swift` file ``` -$(SRCROOT)/carthage/Build/iOS/RxWebKit.framework +// swift-tools-version:5.0 + +import PackageDescription + +let package = Package( + name: "TestRxWebKit", + + dependencies: [ + .package(url: "https://github.com/RxSwiftCommunity/RxWebKit.git", + from: "6.1.0"), + ], + + targets: [ + .target( + name: "TestRxWebKit", + dependencies: ["RxWebKit"]) + ] +) + ``` +### Manually + +To manual install this extension you should get the `RxWebKit/Source/RxWebKit.swift` imported into your project, alongside RxSwift and Alamofire. + ## Requirements -RxWebKit requires Swift 5.2.2 and dedicated versions of RxSwift 5.1.1 +RxWebKit requires Swift 5.1 and dedicated versions of Alamofire (5.4.1) and RxSwift (6.0.0). + +For the last RxSwift 5.1 support, please use RxWebKit 5.7.1. -## License +For the last Swift 5.0 support, please use RxWebKit 5.1.0. -MIT +For the last Swift 4.2 support, please use RxWebKit 4.5.0. diff --git a/RxWebKit.podspec b/RxWebKit.podspec index 082da4c..e5722ff 100644 --- a/RxWebKit.podspec +++ b/RxWebKit.podspec @@ -1,8 +1,11 @@ Pod::Spec.new do |s| - s.name = "RxWebKit" - s.version = "1.0.2" - s.summary = "RxWebKit is a RxSwift wrapper for WebKit." - s.description = <<-DESC + s.name = "RxWebKit" + # Version to always follow latest tag, with fallback to major + s.version = "1.1.0" + s.license = "MIT" + + s.summary = "RxWebKit is a RxSwift wrapper for WebKit." + s.description = <<-DESC RxWebKit is a RxSwift wrapper for `WebKit`. ```swift @@ -27,18 +30,19 @@ Pod::Spec.new do |s| .disposed(by: disposeBag) ``` DESC + s.homepage = "https://github.com/RxSwiftCommunity/RxWebKit" + s.authors = { "RxSwift Community" => "community@rxswift.org" } + s.source = { :git => "https://github.com/RxSwiftCommunity/RxWebKit.git", :tag => "v" + s.version.to_s } + s.swift_version = "5.1" + + s.ios.deployment_target = "9.0" + s.osx.deployment_target = "10.13" + + s.requires_arc = true + + s.source_files = "Sources/RxWebKit/*.swift" - s.homepage = "https://github.com/RxSwiftCommunity/RxWebKit" - s.license = "MIT" - s.authors = { "mokumoku" => "da1lawmoku2@gmail.com", - "RxSwift Community" => "community@rxswift.org" - } - s.source = { :git => "https://github.com/RxSwiftCommunity/RxWebKit.git", :tag => s.version.to_s } - s.source_files = "RxWebKit/Sources/**/*.{swift}" - s.exclude_files = "RxWebKit/Sources/**/*.{plist}" - s.ios.deployment_target = '8.0' - s.osx.deployment_target = '10.13' - s.swift_version = '5.0' - s.dependency 'RxSwift', '~> 5.0' - s.dependency 'RxCocoa', '~> 5.0' + s.frameworks = "Foundation" + s.dependency "RxSwift", "~> 6.0" + s.dependency "RxCocoa", "~> 6.0" end diff --git a/RxWebKit.xcodeproj/project.pbxproj b/RxWebKit.xcodeproj/project.pbxproj index ef86fbb..a27effa 100644 --- a/RxWebKit.xcodeproj/project.pbxproj +++ b/RxWebKit.xcodeproj/project.pbxproj @@ -3,121 +3,96 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 51; objects = { /* Begin PBXBuildFile section */ - 42F426B61C66223E001FED46 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42F426AD1C66223E001FED46 /* AppDelegate.swift */; }; - 42F426B71C66223E001FED46 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 42F426AE1C66223E001FED46 /* Assets.xcassets */; }; - 42F426B81C66223E001FED46 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 42F426B01C66223E001FED46 /* LaunchScreen.storyboard */; }; - 42F426B91C66223E001FED46 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 42F426B21C66223E001FED46 /* Main.storyboard */; }; - 42F426BA1C66223E001FED46 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42F426B41C66223E001FED46 /* ViewController.swift */; }; - 42F426D11C6623C5001FED46 /* RxWebKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 42F426D01C6623C5001FED46 /* RxWebKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 42F426D61C6623C5001FED46 /* RxWebKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 42F426CE1C6623C5001FED46 /* RxWebKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 42F426DC1C662CF9001FED46 /* Rx+WebKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42F426DB1C662CF9001FED46 /* Rx+WebKit.swift */; }; - C4135FFE22875FBE0061933C /* RxWebKitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CB7D5322874EE700FB8D99 /* RxWebKitTests.swift */; }; - C4136011228764840061933C /* Nimble.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C4D323B3228748A0004B05A5 /* Nimble.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - C4136012228764840061933C /* Quick.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C4D323B2228748A0004B05A5 /* Quick.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - C4136013228764840061933C /* RxTest.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C4D323B4228748A0004B05A5 /* RxTest.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - C4136014228764840061933C /* RxSwift.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 424205831C89E9DF00214DA1 /* RxSwift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - C4136015228764840061933C /* RxCocoa.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 424205841C89E9DF00214DA1 /* RxCocoa.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - C4136018228765250061933C /* RxRelay.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C41360162287651B0061933C /* RxRelay.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - C413601A2288135F0061933C /* HasEventsBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41360192288135F0061933C /* HasEventsBehavior.swift */; }; - C413602522896CC20061933C /* RxSwift.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 424205831C89E9DF00214DA1 /* RxSwift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - C413602622896CC20061933C /* RxCocoa.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 424205841C89E9DF00214DA1 /* RxCocoa.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - C413602722896CE20061933C /* RxRelay.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C41360162287651B0061933C /* RxRelay.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - C4607FD01FA0DAC9002DA12F /* RxWKUIDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4607FCF1FA0DAC9002DA12F /* RxWKUIDelegateProxy.swift */; }; - C4607FD61FA0DC40002DA12F /* RxWKUIDelegateEvents+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4607FD51FA0DC40002DA12F /* RxWKUIDelegateEvents+Rx.swift */; }; - C4607FDB1FA0E68F002DA12F /* JavaScriptAlertPanelViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4607FDA1FA0E68F002DA12F /* JavaScriptAlertPanelViewController.swift */; }; - C4607FDD1FA0F1D3002DA12F /* JavaScriptConfirmPanelViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4607FDC1FA0F1D3002DA12F /* JavaScriptConfirmPanelViewController.swift */; }; - C4607FE11FA0F549002DA12F /* AuthChallengeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4607FE01FA0F549002DA12F /* AuthChallengeViewController.swift */; }; - C4878CD61FA1066C00B12C60 /* FailedRequestViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4878CD51FA1066C00B12C60 /* FailedRequestViewController.swift */; }; - C4878CD81FA117E900B12C60 /* RedirectViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4878CD71FA117E900B12C60 /* RedirectViewController.swift */; }; - C4878CDA1FA11B5A00B12C60 /* OtherRequestViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4878CD91FA11B5A00B12C60 /* OtherRequestViewController.swift */; }; - C48E617E1F9E27A700C6A753 /* RxWKNavigationDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48E617D1F9E27A700C6A753 /* RxWKNavigationDelegateProxy.swift */; }; - C48E61841F9E336000C6A753 /* WKNavigationDelegateEvents+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48E61831F9E336000C6A753 /* WKNavigationDelegateEvents+Rx.swift */; }; - C4CA6B07228AB1680088A7A3 /* ForwardsEventsBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CA6B06228AB1680088A7A3 /* ForwardsEventsBehavior.swift */; }; - EFC27F84246D7E9C0093D8B3 /* RxWebKitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CB7D5322874EE700FB8D99 /* RxWebKitTests.swift */; }; - EFC27F85246D7E9C0093D8B3 /* ForwardsEventsBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CA6B06228AB1680088A7A3 /* ForwardsEventsBehavior.swift */; }; - EFC27F86246D7E9C0093D8B3 /* HasEventsBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41360192288135F0061933C /* HasEventsBehavior.swift */; }; - EFC27F96246D7F160093D8B3 /* Nimble.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = EFC27F95246D7F160093D8B3 /* Nimble.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - EFC27F98246D7F1A0093D8B3 /* Quick.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = EFC27F97246D7F1A0093D8B3 /* Quick.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - EFC27F9A246D7F220093D8B3 /* RxCocoa.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = EFC27F99246D7F220093D8B3 /* RxCocoa.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - EFC27F9C246D7F290093D8B3 /* RxRelay.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = EFC27F9B246D7F290093D8B3 /* RxRelay.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - EFC27F9E246D7F2D0093D8B3 /* RxSwift.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = EFC27F9D246D7F2D0093D8B3 /* RxSwift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - EFC27FA0246D7F310093D8B3 /* RxTest.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = EFC27F9F246D7F300093D8B3 /* RxTest.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - F68CEB9E22521B1D00498607 /* InvokeJSFunctionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F68CEB9D22521B1D00498607 /* InvokeJSFunctionViewController.swift */; }; - F68CEBA022521B2B00498607 /* ObservingJSEventViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F68CEB9F22521B2B00498607 /* ObservingJSEventViewController.swift */; }; - F6D7DD0D224F62860066C90F /* RxWKUserContentController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6D7DD0C224F62860066C90F /* RxWKUserContentController.swift */; }; + 13BC8E7C88228E35510D3162 /* RxSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 58CF5412B93E53D7137FF27B /* RxSwift.framework */; }; + 192D3D9CC58DA01FB9274FB6 /* RxWebKit macOS.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 13122B32F3021413AD6B0854 /* RxWebKit macOS.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 2CBDF41FE20B8E078039D8D5 /* RxCocoa.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 44F513333B9F84351ABD81B7 /* RxCocoa.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 31DF5096D653FAF6BBFE793A /* Quick.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 011783F5AAD7B6E35664233D /* Quick.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 321DBC11D2313E5452301A43 /* RxWKUserContentController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40A006B2AFDD1D19EE3A99EA /* RxWKUserContentController.swift */; }; + 3BB4D88B826A42BE96DCC17B /* ForwardsEventsBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = A15856754C90C3258F46075E /* ForwardsEventsBehavior.swift */; }; + 44C473C9A5144166FDCD456B /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 115051C47EB9B69A7A0D88EE /* Quick.framework */; }; + 511AFF2472A35EEC5FA23434 /* RxWKNavigationDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E7A2FAB2EC7F1AFC6271851 /* RxWKNavigationDelegateProxy.swift */; }; + 5467F62BE4D7118A9384710C /* RxWebKit iOS.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 104F8842AA65F2F67EA630D6 /* RxWebKit iOS.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 5CD575773C96E6E25ABA2FB1 /* HasEventsBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A643B4DBE62DB9EE0BF710F /* HasEventsBehavior.swift */; }; + 606E425837C6564B10F43FC4 /* Quick.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 115051C47EB9B69A7A0D88EE /* Quick.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 6A0E6F28D5360262A07E25E0 /* Nimble.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 0BD44F1BACA8CC1CFEBC4266 /* Nimble.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 6BB38DB8D5689202C115BCF3 /* RxWKUserContentController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40A006B2AFDD1D19EE3A99EA /* RxWKUserContentController.swift */; }; + 77AC7C3DDF89C901B6000208 /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 011783F5AAD7B6E35664233D /* Quick.framework */; }; + 7ABF1104C1AD6835854408C2 /* RxWKUIDelegateEvents+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 881522AB491C5B7504D65BD8 /* RxWKUIDelegateEvents+Rx.swift */; }; + 7C01450607683F8B76614915 /* RxSwift.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3F0130BE67FEA9E851900730 /* RxSwift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 7CDF1FAD925F785675AAF90A /* XCTestManifests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BFA66ACF1416E32792A9ECD /* XCTestManifests.swift */; }; + 869F17A339F489052AAC7BFB /* RxWKNavigationDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E7A2FAB2EC7F1AFC6271851 /* RxWKNavigationDelegateProxy.swift */; }; + 8D6E34A689A57FCDF10A6517 /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F9BE7C55068522A89704DF09 /* Nimble.framework */; }; + 9139715816BAB90AD44FA2EC /* WKNavigationDelegateEvents+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74461C24E18E5B09FD2B1163 /* WKNavigationDelegateEvents+Rx.swift */; }; + 9629B4D4D81C225A04D01959 /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BD44F1BACA8CC1CFEBC4266 /* Nimble.framework */; }; + 986FEA4A8FE5EA72126BD4CC /* RxWKUIDelegateEvents+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 881522AB491C5B7504D65BD8 /* RxWKUIDelegateEvents+Rx.swift */; }; + 9E0963B57B28DF4BE1950177 /* RxWebKitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 540B306B31EAFA631CBB09B8 /* RxWebKitTests.swift */; }; + B1DCADCA5EFA28DE81A243FB /* Nimble.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = F9BE7C55068522A89704DF09 /* Nimble.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + B397D15B802E8E8FD7EDFA24 /* RxWKUIDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBCB556535F6776088EF6F78 /* RxWKUIDelegateProxy.swift */; }; + B468E7E1218D3E6101640691 /* RxWebKitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 540B306B31EAFA631CBB09B8 /* RxWebKitTests.swift */; }; + C11519057009B903E31B59AA /* RxSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3F0130BE67FEA9E851900730 /* RxSwift.framework */; }; + C86EA358EF6F9BFA2BCFB255 /* ForwardsEventsBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = A15856754C90C3258F46075E /* ForwardsEventsBehavior.swift */; }; + C88924DD12296911285DC0C5 /* Rx+WebKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E0215C6D48E0FE5852E682A /* Rx+WebKit.swift */; }; + CD30099828BE47A8E2C0535E /* RxCocoa.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 1903CCB96DEEB82E413E72CB /* RxCocoa.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + D1B720AEE0C42336083B26CB /* RxCocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1903CCB96DEEB82E413E72CB /* RxCocoa.framework */; }; + D1E41EAB4FEC4B461313EB48 /* Rx+WebKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E0215C6D48E0FE5852E682A /* Rx+WebKit.swift */; }; + D2A876401945CD0D3D639AC9 /* RxCocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 44F513333B9F84351ABD81B7 /* RxCocoa.framework */; }; + D924F59E89A7FD62D5D6069B /* RxWebKit macOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 13122B32F3021413AD6B0854 /* RxWebKit macOS.framework */; }; + DA6B655F9F369219FAF61A9C /* RxSwift.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 58CF5412B93E53D7137FF27B /* RxSwift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + E096F44BC540937D5E8610F4 /* XCTestManifests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BFA66ACF1416E32792A9ECD /* XCTestManifests.swift */; }; + E50A50325C002F71582C5CB1 /* WKNavigationDelegateEvents+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74461C24E18E5B09FD2B1163 /* WKNavigationDelegateEvents+Rx.swift */; }; + ED90B3E475AB3C24BC059152 /* RxWebKit iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 104F8842AA65F2F67EA630D6 /* RxWebKit iOS.framework */; }; + EFC1B706FB90B136F7D83835 /* HasEventsBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A643B4DBE62DB9EE0BF710F /* HasEventsBehavior.swift */; }; + FF658485CE2221A08B137D28 /* RxWKUIDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBCB556535F6776088EF6F78 /* RxWKUIDelegateProxy.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 42F426D31C6623C5001FED46 /* PBXContainerItemProxy */ = { + 2F92DBF9B72EFAA3047F3F86 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = 42F4268F1C66200D001FED46 /* Project object */; + containerPortal = 865BBEF49ACC978CE062F291 /* Project object */; proxyType = 1; - remoteGlobalIDString = 42F426CD1C6623C5001FED46; - remoteInfo = RxWebKit; + remoteGlobalIDString = 97506B98C69296A031B89188; + remoteInfo = "RxWebKit iOS"; }; - C4CB7D4922874E5600FB8D99 /* PBXContainerItemProxy */ = { + B452ECFE49AE3B90A31EE2B3 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = 42F4268F1C66200D001FED46 /* Project object */; + containerPortal = 865BBEF49ACC978CE062F291 /* Project object */; proxyType = 1; - remoteGlobalIDString = 42F426CD1C6623C5001FED46; - remoteInfo = RxWebKit; - }; - EFC27F82246D7E9C0093D8B3 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 42F4268F1C66200D001FED46 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 42F426CD1C6623C5001FED46; - remoteInfo = RxWebKit; + remoteGlobalIDString = D9E0F0A0F8B2C599B1A60698; + remoteInfo = "RxWebKit macOS"; }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ - 42F426DA1C6623C5001FED46 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 42F426D61C6623C5001FED46 /* RxWebKit.framework in Embed Frameworks */, - C413602522896CC20061933C /* RxSwift.framework in Embed Frameworks */, - C413602622896CC20061933C /* RxCocoa.framework in Embed Frameworks */, - C413602722896CE20061933C /* RxRelay.framework in Embed Frameworks */, - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; - C41360102287644B0061933C /* Embed Frameworks */ = { + 1C13FBE97DA129D3DB8941B4 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 10; files = ( - C4136011228764840061933C /* Nimble.framework in Embed Frameworks */, - C4136012228764840061933C /* Quick.framework in Embed Frameworks */, - C4136013228764840061933C /* RxTest.framework in Embed Frameworks */, - C4136014228764840061933C /* RxSwift.framework in Embed Frameworks */, - C4136015228764840061933C /* RxCocoa.framework in Embed Frameworks */, - C4136018228765250061933C /* RxRelay.framework in Embed Frameworks */, + 192D3D9CC58DA01FB9274FB6 /* RxWebKit macOS.framework in Embed Frameworks */, + B1DCADCA5EFA28DE81A243FB /* Nimble.framework in Embed Frameworks */, + 31DF5096D653FAF6BBFE793A /* Quick.framework in Embed Frameworks */, + CD30099828BE47A8E2C0535E /* RxCocoa.framework in Embed Frameworks */, + DA6B655F9F369219FAF61A9C /* RxSwift.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; }; - EFC27F89246D7E9C0093D8B3 /* Embed Frameworks */ = { + E17301C95FC91939AB15FDB3 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 10; files = ( - EFC27FA0246D7F310093D8B3 /* RxTest.framework in Embed Frameworks */, - EFC27F9E246D7F2D0093D8B3 /* RxSwift.framework in Embed Frameworks */, - EFC27F9C246D7F290093D8B3 /* RxRelay.framework in Embed Frameworks */, - EFC27F96246D7F160093D8B3 /* Nimble.framework in Embed Frameworks */, - EFC27F98246D7F1A0093D8B3 /* Quick.framework in Embed Frameworks */, - EFC27F9A246D7F220093D8B3 /* RxCocoa.framework in Embed Frameworks */, + 5467F62BE4D7118A9384710C /* RxWebKit iOS.framework in Embed Frameworks */, + 6A0E6F28D5360262A07E25E0 /* Nimble.framework in Embed Frameworks */, + 606E425837C6564B10F43FC4 /* Quick.framework in Embed Frameworks */, + 2CBDF41FE20B8E078039D8D5 /* RxCocoa.framework in Embed Frameworks */, + 7C01450607683F8B76614915 /* RxSwift.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -125,479 +100,464 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 424205831C89E9DF00214DA1 /* RxSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxSwift.framework; path = Carthage/Build/iOS/RxSwift.framework; sourceTree = ""; }; - 424205841C89E9DF00214DA1 /* RxCocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxCocoa.framework; path = Carthage/Build/iOS/RxCocoa.framework; sourceTree = ""; }; - 42F426971C66200D001FED46 /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 42F426AC1C66223E001FED46 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 42F426AD1C66223E001FED46 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 42F426AE1C66223E001FED46 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 42F426B11C66223E001FED46 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 42F426B31C66223E001FED46 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 42F426B41C66223E001FED46 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; - 42F426CE1C6623C5001FED46 /* RxWebKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RxWebKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 42F426D01C6623C5001FED46 /* RxWebKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RxWebKit.h; sourceTree = ""; }; - 42F426D21C6623C5001FED46 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 42F426DB1C662CF9001FED46 /* Rx+WebKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Rx+WebKit.swift"; sourceTree = ""; }; - C41360162287651B0061933C /* RxRelay.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxRelay.framework; path = Carthage/Build/iOS/RxRelay.framework; sourceTree = ""; }; - C41360192288135F0061933C /* HasEventsBehavior.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HasEventsBehavior.swift; sourceTree = ""; }; - C4607FCF1FA0DAC9002DA12F /* RxWKUIDelegateProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RxWKUIDelegateProxy.swift; sourceTree = ""; }; - C4607FD51FA0DC40002DA12F /* RxWKUIDelegateEvents+Rx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RxWKUIDelegateEvents+Rx.swift"; sourceTree = ""; }; - C4607FDA1FA0E68F002DA12F /* JavaScriptAlertPanelViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JavaScriptAlertPanelViewController.swift; sourceTree = ""; }; - C4607FDC1FA0F1D3002DA12F /* JavaScriptConfirmPanelViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JavaScriptConfirmPanelViewController.swift; sourceTree = ""; }; - C4607FE01FA0F549002DA12F /* AuthChallengeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthChallengeViewController.swift; sourceTree = ""; }; - C4878CD51FA1066C00B12C60 /* FailedRequestViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FailedRequestViewController.swift; sourceTree = ""; }; - C4878CD71FA117E900B12C60 /* RedirectViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RedirectViewController.swift; sourceTree = ""; }; - C4878CD91FA11B5A00B12C60 /* OtherRequestViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OtherRequestViewController.swift; sourceTree = ""; }; - C48E617D1F9E27A700C6A753 /* RxWKNavigationDelegateProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RxWKNavigationDelegateProxy.swift; sourceTree = ""; }; - C48E61831F9E336000C6A753 /* WKNavigationDelegateEvents+Rx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WKNavigationDelegateEvents+Rx.swift"; sourceTree = ""; }; - C4A50F9E229AF3EF0037E608 /* config.yml */ = {isa = PBXFileReference; lastKnownFileType = text; name = config.yml; path = .circleci/config.yml; sourceTree = SOURCE_ROOT; }; - C4CA6B06228AB1680088A7A3 /* ForwardsEventsBehavior.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForwardsEventsBehavior.swift; sourceTree = ""; }; - C4CA6B15228D752C0088A7A3 /* RxWebKit.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = RxWebKit.podspec; sourceTree = SOURCE_ROOT; }; - C4CA6B16228D75410088A7A3 /* Cartfile.private */ = {isa = PBXFileReference; lastKnownFileType = text; path = Cartfile.private; sourceTree = SOURCE_ROOT; }; - C4CA6B17228D75420088A7A3 /* Cartfile.resolved */ = {isa = PBXFileReference; lastKnownFileType = text; path = Cartfile.resolved; sourceTree = SOURCE_ROOT; }; - C4CA6B18228D75420088A7A3 /* Cartfile */ = {isa = PBXFileReference; lastKnownFileType = text; path = Cartfile; sourceTree = SOURCE_ROOT; }; - C4CB7D4322874E5600FB8D99 /* RxWebKitTests-iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "RxWebKitTests-iOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; - C4CB7D4722874E5600FB8D99 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - C4CB7D5322874EE700FB8D99 /* RxWebKitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RxWebKitTests.swift; sourceTree = ""; }; - C4D323B2228748A0004B05A5 /* Quick.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Quick.framework; path = Carthage/Build/iOS/Quick.framework; sourceTree = ""; }; - C4D323B3228748A0004B05A5 /* Nimble.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Nimble.framework; path = Carthage/Build/iOS/Nimble.framework; sourceTree = ""; }; - C4D323B4228748A0004B05A5 /* RxTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxTest.framework; path = Carthage/Build/iOS/RxTest.framework; sourceTree = ""; }; - EFC27F93246D7E9C0093D8B3 /* RxWebKitTests-macOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "RxWebKitTests-macOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; - EFC27F95246D7F160093D8B3 /* Nimble.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Nimble.framework; path = Carthage/Build/Mac/Nimble.framework; sourceTree = ""; }; - EFC27F97246D7F1A0093D8B3 /* Quick.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Quick.framework; path = Carthage/Build/Mac/Quick.framework; sourceTree = ""; }; - EFC27F99246D7F220093D8B3 /* RxCocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxCocoa.framework; path = Carthage/Build/Mac/RxCocoa.framework; sourceTree = ""; }; - EFC27F9B246D7F290093D8B3 /* RxRelay.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxRelay.framework; path = Carthage/Build/Mac/RxRelay.framework; sourceTree = ""; }; - EFC27F9D246D7F2D0093D8B3 /* RxSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxSwift.framework; path = Carthage/Build/Mac/RxSwift.framework; sourceTree = ""; }; - EFC27F9F246D7F300093D8B3 /* RxTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxTest.framework; path = Carthage/Build/Mac/RxTest.framework; sourceTree = ""; }; - F68CEB9D22521B1D00498607 /* InvokeJSFunctionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvokeJSFunctionViewController.swift; sourceTree = ""; }; - F68CEB9F22521B2B00498607 /* ObservingJSEventViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObservingJSEventViewController.swift; sourceTree = ""; }; - F6D7DD0C224F62860066C90F /* RxWKUserContentController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RxWKUserContentController.swift; sourceTree = ""; }; + 011783F5AAD7B6E35664233D /* Quick.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Quick.framework; sourceTree = ""; }; + 0BD44F1BACA8CC1CFEBC4266 /* Nimble.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Nimble.framework; sourceTree = ""; }; + 0BFA66ACF1416E32792A9ECD /* XCTestManifests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTestManifests.swift; sourceTree = ""; }; + 104F8842AA65F2F67EA630D6 /* RxWebKit iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = "RxWebKit iOS.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; + 115051C47EB9B69A7A0D88EE /* Quick.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Quick.framework; sourceTree = ""; }; + 13122B32F3021413AD6B0854 /* RxWebKit macOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = "RxWebKit macOS.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1903CCB96DEEB82E413E72CB /* RxCocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = RxCocoa.framework; sourceTree = ""; }; + 3309B6246AB73F9BCA6E00A5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; + 3E0215C6D48E0FE5852E682A /* Rx+WebKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Rx+WebKit.swift"; sourceTree = ""; }; + 3E7A2FAB2EC7F1AFC6271851 /* RxWKNavigationDelegateProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RxWKNavigationDelegateProxy.swift; sourceTree = ""; }; + 3F0130BE67FEA9E851900730 /* RxSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = RxSwift.framework; sourceTree = ""; }; + 40A006B2AFDD1D19EE3A99EA /* RxWKUserContentController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RxWKUserContentController.swift; sourceTree = ""; }; + 44F513333B9F84351ABD81B7 /* RxCocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = RxCocoa.framework; sourceTree = ""; }; + 540B306B31EAFA631CBB09B8 /* RxWebKitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RxWebKitTests.swift; sourceTree = ""; }; + 58CF5412B93E53D7137FF27B /* RxSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = RxSwift.framework; sourceTree = ""; }; + 74461C24E18E5B09FD2B1163 /* WKNavigationDelegateEvents+Rx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WKNavigationDelegateEvents+Rx.swift"; sourceTree = ""; }; + 8562B86DD7C082CE38845B28 /* RxWebKitTests macOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "RxWebKitTests macOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 881522AB491C5B7504D65BD8 /* RxWKUIDelegateEvents+Rx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RxWKUIDelegateEvents+Rx.swift"; sourceTree = ""; }; + 8A643B4DBE62DB9EE0BF710F /* HasEventsBehavior.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HasEventsBehavior.swift; sourceTree = ""; }; + A15856754C90C3258F46075E /* ForwardsEventsBehavior.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForwardsEventsBehavior.swift; sourceTree = ""; }; + B4D19347351B3D55E3F578F4 /* RxWebKitTests iOS.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = "RxWebKitTests iOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + EBCB556535F6776088EF6F78 /* RxWKUIDelegateProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RxWKUIDelegateProxy.swift; sourceTree = ""; }; + F9BE7C55068522A89704DF09 /* Nimble.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Nimble.framework; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 42F426941C66200D001FED46 /* Frameworks */ = { + 4E0F95D8F4ED407A308DAC3C /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + D924F59E89A7FD62D5D6069B /* RxWebKit macOS.framework in Frameworks */, + 8D6E34A689A57FCDF10A6517 /* Nimble.framework in Frameworks */, + 77AC7C3DDF89C901B6000208 /* Quick.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 42F426CA1C6623C5001FED46 /* Frameworks */ = { + 5E293061860E41B5443273D1 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + D2A876401945CD0D3D639AC9 /* RxCocoa.framework in Frameworks */, + C11519057009B903E31B59AA /* RxSwift.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - C4CB7D4022874E5600FB8D99 /* Frameworks */ = { + 7C7DC1BC90D90937BFEAC4D9 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + D1B720AEE0C42336083B26CB /* RxCocoa.framework in Frameworks */, + 13BC8E7C88228E35510D3162 /* RxSwift.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - EFC27F87246D7E9C0093D8B3 /* Frameworks */ = { + BAC6DE5BE2CF28E854236851 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + ED90B3E475AB3C24BC059152 /* RxWebKit iOS.framework in Frameworks */, + 9629B4D4D81C225A04D01959 /* Nimble.framework in Frameworks */, + 44C473C9A5144166FDCD456B /* Quick.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 42B12EFB1C6DFC7600C280BD /* Sources */ = { + 170106FAB5D2D92BE11C7A3B /* RxWebKit */ = { isa = PBXGroup; children = ( - 42F426DB1C662CF9001FED46 /* Rx+WebKit.swift */, - C48E61831F9E336000C6A753 /* WKNavigationDelegateEvents+Rx.swift */, - C48E617D1F9E27A700C6A753 /* RxWKNavigationDelegateProxy.swift */, - C4607FCF1FA0DAC9002DA12F /* RxWKUIDelegateProxy.swift */, - C4607FD51FA0DC40002DA12F /* RxWKUIDelegateEvents+Rx.swift */, - F6D7DD0C224F62860066C90F /* RxWKUserContentController.swift */, - ); - path = Sources; + 3309B6246AB73F9BCA6E00A5 /* Info.plist */, + 3E0215C6D48E0FE5852E682A /* Rx+WebKit.swift */, + 3E7A2FAB2EC7F1AFC6271851 /* RxWKNavigationDelegateProxy.swift */, + 881522AB491C5B7504D65BD8 /* RxWKUIDelegateEvents+Rx.swift */, + EBCB556535F6776088EF6F78 /* RxWKUIDelegateProxy.swift */, + 40A006B2AFDD1D19EE3A99EA /* RxWKUserContentController.swift */, + 74461C24E18E5B09FD2B1163 /* WKNavigationDelegateEvents+Rx.swift */, + ); + name = RxWebKit; + path = Sources/RxWebKit; sourceTree = ""; }; - 42F4268E1C66200D001FED46 = { + 2824985CC167DCF017C74DE0 = { isa = PBXGroup; children = ( - EFC27F9F246D7F300093D8B3 /* RxTest.framework */, - EFC27F9D246D7F2D0093D8B3 /* RxSwift.framework */, - EFC27F9B246D7F290093D8B3 /* RxRelay.framework */, - EFC27F99246D7F220093D8B3 /* RxCocoa.framework */, - EFC27F97246D7F1A0093D8B3 /* Quick.framework */, - EFC27F95246D7F160093D8B3 /* Nimble.framework */, - 42F426991C66200D001FED46 /* Example */, - 733B51F3D0F2B4B1E9A99FDC /* Frameworks */, - 42F426981C66200D001FED46 /* Products */, - 42F426CF1C6623C5001FED46 /* RxWebKit */, - C4CB7D4422874E5600FB8D99 /* RxWebKitTests */, + 170106FAB5D2D92BE11C7A3B /* RxWebKit */, + 5536841C177453F47C933493 /* RxWebKitTests */, + 3BEE572574144F2A97612AC0 /* Frameworks */, + 3E3C20F64D85412F11F4F815 /* Products */, ); + indentWidth = 2; sourceTree = ""; + tabWidth = 2; + usesTabs = 0; }; - 42F426981C66200D001FED46 /* Products */ = { + 3BEE572574144F2A97612AC0 /* Frameworks */ = { isa = PBXGroup; children = ( - 42F426971C66200D001FED46 /* Example.app */, - 42F426CE1C6623C5001FED46 /* RxWebKit.framework */, - C4CB7D4322874E5600FB8D99 /* RxWebKitTests-iOS.xctest */, - EFC27F93246D7E9C0093D8B3 /* RxWebKitTests-macOS.xctest */, + 6BE211B87FD5A4CC3304C189 /* Carthage */, ); - name = Products; + name = Frameworks; sourceTree = ""; }; - 42F426991C66200D001FED46 /* Example */ = { + 3E3C20F64D85412F11F4F815 /* Products */ = { isa = PBXGroup; children = ( - 42F426AF1C66223E001FED46 /* Base.lproj */, - 42F426AD1C66223E001FED46 /* AppDelegate.swift */, - 42F426AE1C66223E001FED46 /* Assets.xcassets */, - 42F426AC1C66223E001FED46 /* Info.plist */, - 42F426B41C66223E001FED46 /* ViewController.swift */, - C4607FDA1FA0E68F002DA12F /* JavaScriptAlertPanelViewController.swift */, - C4607FDC1FA0F1D3002DA12F /* JavaScriptConfirmPanelViewController.swift */, - C4607FE01FA0F549002DA12F /* AuthChallengeViewController.swift */, - C4878CD51FA1066C00B12C60 /* FailedRequestViewController.swift */, - C4878CD71FA117E900B12C60 /* RedirectViewController.swift */, - C4878CD91FA11B5A00B12C60 /* OtherRequestViewController.swift */, - F68CEB9D22521B1D00498607 /* InvokeJSFunctionViewController.swift */, - F68CEB9F22521B2B00498607 /* ObservingJSEventViewController.swift */, - ); - path = Example; + 104F8842AA65F2F67EA630D6 /* RxWebKit iOS.framework */, + 13122B32F3021413AD6B0854 /* RxWebKit macOS.framework */, + B4D19347351B3D55E3F578F4 /* RxWebKitTests iOS.xctest */, + 8562B86DD7C082CE38845B28 /* RxWebKitTests macOS.xctest */, + ); + name = Products; sourceTree = ""; }; - 42F426AF1C66223E001FED46 /* Base.lproj */ = { + 5387D4BD610F8FCE1A412A1F /* Mac */ = { isa = PBXGroup; children = ( - 42F426B01C66223E001FED46 /* LaunchScreen.storyboard */, - 42F426B21C66223E001FED46 /* Main.storyboard */, + F9BE7C55068522A89704DF09 /* Nimble.framework */, + 011783F5AAD7B6E35664233D /* Quick.framework */, + 1903CCB96DEEB82E413E72CB /* RxCocoa.framework */, + 58CF5412B93E53D7137FF27B /* RxSwift.framework */, ); - path = Base.lproj; + path = Mac; sourceTree = ""; }; - 42F426CF1C6623C5001FED46 /* RxWebKit */ = { + 5536841C177453F47C933493 /* RxWebKitTests */ = { isa = PBXGroup; children = ( - C4CA6B15228D752C0088A7A3 /* RxWebKit.podspec */, - C4CA6B18228D75420088A7A3 /* Cartfile */, - C4CA6B16228D75410088A7A3 /* Cartfile.private */, - C4CA6B17228D75420088A7A3 /* Cartfile.resolved */, - C4A50F9E229AF3EF0037E608 /* config.yml */, - 42B12EFB1C6DFC7600C280BD /* Sources */, - 42F426D21C6623C5001FED46 /* Info.plist */, - 42F426D01C6623C5001FED46 /* RxWebKit.h */, - ); - path = RxWebKit; + A15856754C90C3258F46075E /* ForwardsEventsBehavior.swift */, + 8A643B4DBE62DB9EE0BF710F /* HasEventsBehavior.swift */, + 540B306B31EAFA631CBB09B8 /* RxWebKitTests.swift */, + 0BFA66ACF1416E32792A9ECD /* XCTestManifests.swift */, + ); + name = RxWebKitTests; + path = Tests/RxWebKitTests; sourceTree = ""; }; - 733B51F3D0F2B4B1E9A99FDC /* Frameworks */ = { + 6BE211B87FD5A4CC3304C189 /* Carthage */ = { isa = PBXGroup; children = ( - C41360162287651B0061933C /* RxRelay.framework */, - C4D323B3228748A0004B05A5 /* Nimble.framework */, - C4D323B2228748A0004B05A5 /* Quick.framework */, - C4D323B4228748A0004B05A5 /* RxTest.framework */, - 424205831C89E9DF00214DA1 /* RxSwift.framework */, - 424205841C89E9DF00214DA1 /* RxCocoa.framework */, + CDB1648C573B4309EF65AA4F /* iOS */, + 5387D4BD610F8FCE1A412A1F /* Mac */, ); - name = Frameworks; + name = Carthage; + path = Carthage/Build; sourceTree = ""; }; - C4CB7D4422874E5600FB8D99 /* RxWebKitTests */ = { + CDB1648C573B4309EF65AA4F /* iOS */ = { isa = PBXGroup; children = ( - C4CB7D5322874EE700FB8D99 /* RxWebKitTests.swift */, - C41360192288135F0061933C /* HasEventsBehavior.swift */, - C4CA6B06228AB1680088A7A3 /* ForwardsEventsBehavior.swift */, - C4CB7D4722874E5600FB8D99 /* Info.plist */, + 0BD44F1BACA8CC1CFEBC4266 /* Nimble.framework */, + 115051C47EB9B69A7A0D88EE /* Quick.framework */, + 44F513333B9F84351ABD81B7 /* RxCocoa.framework */, + 3F0130BE67FEA9E851900730 /* RxSwift.framework */, ); - path = RxWebKitTests; + path = iOS; sourceTree = ""; }; /* End PBXGroup section */ -/* Begin PBXHeadersBuildPhase section */ - 42F426CB1C6623C5001FED46 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 42F426D11C6623C5001FED46 /* RxWebKit.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - /* Begin PBXNativeTarget section */ - 42F426961C66200D001FED46 /* Example */ = { + 01F501248CDF2703470394D7 /* RxWebKitTests macOS */ = { isa = PBXNativeTarget; - buildConfigurationList = 42F426A91C66200D001FED46 /* Build configuration list for PBXNativeTarget "Example" */; + buildConfigurationList = FC19328CC031D0C2347862B3 /* Build configuration list for PBXNativeTarget "RxWebKitTests macOS" */; buildPhases = ( - 42F426931C66200D001FED46 /* Sources */, - 42F426941C66200D001FED46 /* Frameworks */, - 42F426951C66200D001FED46 /* Resources */, - 42F426DA1C6623C5001FED46 /* Embed Frameworks */, + 83E9980988F20E8B0B629BA6 /* Sources */, + 4E0F95D8F4ED407A308DAC3C /* Frameworks */, + 1C13FBE97DA129D3DB8941B4 /* Embed Frameworks */, ); buildRules = ( ); dependencies = ( - 42F426D41C6623C5001FED46 /* PBXTargetDependency */, + 52080388F03EB4880C5BC4A7 /* PBXTargetDependency */, ); - name = Example; - productName = RxWebKit; - productReference = 42F426971C66200D001FED46 /* Example.app */; - productType = "com.apple.product-type.application"; + name = "RxWebKitTests macOS"; + productName = "RxWebKitTests macOS"; + productReference = 8562B86DD7C082CE38845B28 /* RxWebKitTests macOS.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; }; - 42F426CD1C6623C5001FED46 /* RxWebKit */ = { + 6D6C1601C887F2B8C7777AD2 /* RxWebKitTests iOS */ = { isa = PBXNativeTarget; - buildConfigurationList = 42F426D71C6623C5001FED46 /* Build configuration list for PBXNativeTarget "RxWebKit" */; + buildConfigurationList = 17913BB7275236E4931500D8 /* Build configuration list for PBXNativeTarget "RxWebKitTests iOS" */; buildPhases = ( - 42F426C91C6623C5001FED46 /* Sources */, - 42F426CA1C6623C5001FED46 /* Frameworks */, - 42F426CB1C6623C5001FED46 /* Headers */, - 42F426CC1C6623C5001FED46 /* Resources */, + ED9485E33C77940C3A0697FB /* Sources */, + BAC6DE5BE2CF28E854236851 /* Frameworks */, + E17301C95FC91939AB15FDB3 /* Embed Frameworks */, ); buildRules = ( ); dependencies = ( + 9E8AB03710ABD6043D6F43A0 /* PBXTargetDependency */, ); - name = RxWebKit; - productName = RxWebKit; - productReference = 42F426CE1C6623C5001FED46 /* RxWebKit.framework */; - productType = "com.apple.product-type.framework"; + name = "RxWebKitTests iOS"; + productName = "RxWebKitTests iOS"; + productReference = B4D19347351B3D55E3F578F4 /* RxWebKitTests iOS.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; }; - C4CB7D4222874E5600FB8D99 /* RxWebKitTests-iOS */ = { + 97506B98C69296A031B89188 /* RxWebKit iOS */ = { isa = PBXNativeTarget; - buildConfigurationList = C4CB7D4B22874E5600FB8D99 /* Build configuration list for PBXNativeTarget "RxWebKitTests-iOS" */; + buildConfigurationList = CF90D785D3B39DAC831D228E /* Build configuration list for PBXNativeTarget "RxWebKit iOS" */; buildPhases = ( - C4CB7D3F22874E5600FB8D99 /* Sources */, - C4CB7D4022874E5600FB8D99 /* Frameworks */, - C4CB7D4122874E5600FB8D99 /* Resources */, - C41360102287644B0061933C /* Embed Frameworks */, + 596FB0B499E33066DFD5B580 /* Sources */, + 5E293061860E41B5443273D1 /* Frameworks */, ); buildRules = ( ); dependencies = ( - C4CB7D4A22874E5600FB8D99 /* PBXTargetDependency */, ); - name = "RxWebKitTests-iOS"; - productName = RxWebKitTests; - productReference = C4CB7D4322874E5600FB8D99 /* RxWebKitTests-iOS.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; + name = "RxWebKit iOS"; + productName = "RxWebKit iOS"; + productReference = 104F8842AA65F2F67EA630D6 /* RxWebKit iOS.framework */; + productType = "com.apple.product-type.framework"; }; - EFC27F80246D7E9C0093D8B3 /* RxWebKitTests-macOS */ = { + D9E0F0A0F8B2C599B1A60698 /* RxWebKit macOS */ = { isa = PBXNativeTarget; - buildConfigurationList = EFC27F90246D7E9C0093D8B3 /* Build configuration list for PBXNativeTarget "RxWebKitTests-macOS" */; + buildConfigurationList = 681329872F44E9CD297DA311 /* Build configuration list for PBXNativeTarget "RxWebKit macOS" */; buildPhases = ( - EFC27F83246D7E9C0093D8B3 /* Sources */, - EFC27F87246D7E9C0093D8B3 /* Frameworks */, - EFC27F88246D7E9C0093D8B3 /* Resources */, - EFC27F89246D7E9C0093D8B3 /* Embed Frameworks */, + BEAF20BA1D39563A8B95467B /* Sources */, + 7C7DC1BC90D90937BFEAC4D9 /* Frameworks */, ); buildRules = ( ); dependencies = ( - EFC27F81246D7E9C0093D8B3 /* PBXTargetDependency */, ); - name = "RxWebKitTests-macOS"; - productName = RxWebKitTests; - productReference = EFC27F93246D7E9C0093D8B3 /* RxWebKitTests-macOS.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; + name = "RxWebKit macOS"; + productName = "RxWebKit macOS"; + productReference = 13122B32F3021413AD6B0854 /* RxWebKit macOS.framework */; + productType = "com.apple.product-type.framework"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ - 42F4268F1C66200D001FED46 /* Project object */ = { + 865BBEF49ACC978CE062F291 /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 1020; - LastUpgradeCheck = 1020; - ORGANIZATIONNAME = MokuMokuCloud; + LastUpgradeCheck = 1230; + ORGANIZATIONNAME = RxSwiftCommunity; TargetAttributes = { - 42F426961C66200D001FED46 = { - CreatedOnToolsVersion = 7.2; - DevelopmentTeamName = "Daichi Ichihara (Personal Team)"; - LastSwiftMigration = 0800; - }; - 42F426CD1C6623C5001FED46 = { - CreatedOnToolsVersion = 7.2; - DevelopmentTeam = 6XJDQ2F5E3; - DevelopmentTeamName = "Daichi Ichihara (Personal Team)"; - LastSwiftMigration = 1020; - }; - C4CB7D4222874E5600FB8D99 = { - CreatedOnToolsVersion = 10.2.1; - ProvisioningStyle = Manual; - }; - EFC27F80246D7E9C0093D8B3 = { - ProvisioningStyle = Manual; - }; }; }; - buildConfigurationList = 42F426921C66200D001FED46 /* Build configuration list for PBXProject "RxWebKit" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + buildConfigurationList = 4943091B8B465B2827C5729C /* Build configuration list for PBXProject "RxWebKit" */; + compatibilityVersion = "Xcode 10.0"; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( - English, - en, Base, + en, ); - mainGroup = 42F4268E1C66200D001FED46; - productRefGroup = 42F426981C66200D001FED46 /* Products */; + mainGroup = 2824985CC167DCF017C74DE0; projectDirPath = ""; projectRoot = ""; targets = ( - 42F426961C66200D001FED46 /* Example */, - 42F426CD1C6623C5001FED46 /* RxWebKit */, - C4CB7D4222874E5600FB8D99 /* RxWebKitTests-iOS */, - EFC27F80246D7E9C0093D8B3 /* RxWebKitTests-macOS */, + 97506B98C69296A031B89188 /* RxWebKit iOS */, + D9E0F0A0F8B2C599B1A60698 /* RxWebKit macOS */, + 6D6C1601C887F2B8C7777AD2 /* RxWebKitTests iOS */, + 01F501248CDF2703470394D7 /* RxWebKitTests macOS */, ); }; /* End PBXProject section */ -/* Begin PBXResourcesBuildPhase section */ - 42F426951C66200D001FED46 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 42F426B81C66223E001FED46 /* LaunchScreen.storyboard in Resources */, - 42F426B71C66223E001FED46 /* Assets.xcassets in Resources */, - 42F426B91C66223E001FED46 /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 42F426CC1C6623C5001FED46 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - C4CB7D4122874E5600FB8D99 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - EFC27F88246D7E9C0093D8B3 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - /* Begin PBXSourcesBuildPhase section */ - 42F426931C66200D001FED46 /* Sources */ = { + 596FB0B499E33066DFD5B580 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - C4607FE11FA0F549002DA12F /* AuthChallengeViewController.swift in Sources */, - F68CEB9E22521B1D00498607 /* InvokeJSFunctionViewController.swift in Sources */, - 42F426BA1C66223E001FED46 /* ViewController.swift in Sources */, - C4878CDA1FA11B5A00B12C60 /* OtherRequestViewController.swift in Sources */, - F68CEBA022521B2B00498607 /* ObservingJSEventViewController.swift in Sources */, - C4878CD81FA117E900B12C60 /* RedirectViewController.swift in Sources */, - C4607FDD1FA0F1D3002DA12F /* JavaScriptConfirmPanelViewController.swift in Sources */, - C4878CD61FA1066C00B12C60 /* FailedRequestViewController.swift in Sources */, - 42F426B61C66223E001FED46 /* AppDelegate.swift in Sources */, - C4607FDB1FA0E68F002DA12F /* JavaScriptAlertPanelViewController.swift in Sources */, + C88924DD12296911285DC0C5 /* Rx+WebKit.swift in Sources */, + 869F17A339F489052AAC7BFB /* RxWKNavigationDelegateProxy.swift in Sources */, + 7ABF1104C1AD6835854408C2 /* RxWKUIDelegateEvents+Rx.swift in Sources */, + FF658485CE2221A08B137D28 /* RxWKUIDelegateProxy.swift in Sources */, + 321DBC11D2313E5452301A43 /* RxWKUserContentController.swift in Sources */, + E50A50325C002F71582C5CB1 /* WKNavigationDelegateEvents+Rx.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 42F426C91C6623C5001FED46 /* Sources */ = { + 83E9980988F20E8B0B629BA6 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 42F426DC1C662CF9001FED46 /* Rx+WebKit.swift in Sources */, - C48E61841F9E336000C6A753 /* WKNavigationDelegateEvents+Rx.swift in Sources */, - C48E617E1F9E27A700C6A753 /* RxWKNavigationDelegateProxy.swift in Sources */, - C4607FD01FA0DAC9002DA12F /* RxWKUIDelegateProxy.swift in Sources */, - F6D7DD0D224F62860066C90F /* RxWKUserContentController.swift in Sources */, - C4607FD61FA0DC40002DA12F /* RxWKUIDelegateEvents+Rx.swift in Sources */, + 3BB4D88B826A42BE96DCC17B /* ForwardsEventsBehavior.swift in Sources */, + 5CD575773C96E6E25ABA2FB1 /* HasEventsBehavior.swift in Sources */, + B468E7E1218D3E6101640691 /* RxWebKitTests.swift in Sources */, + E096F44BC540937D5E8610F4 /* XCTestManifests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - C4CB7D3F22874E5600FB8D99 /* Sources */ = { + BEAF20BA1D39563A8B95467B /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - C4135FFE22875FBE0061933C /* RxWebKitTests.swift in Sources */, - C4CA6B07228AB1680088A7A3 /* ForwardsEventsBehavior.swift in Sources */, - C413601A2288135F0061933C /* HasEventsBehavior.swift in Sources */, + D1E41EAB4FEC4B461313EB48 /* Rx+WebKit.swift in Sources */, + 511AFF2472A35EEC5FA23434 /* RxWKNavigationDelegateProxy.swift in Sources */, + 986FEA4A8FE5EA72126BD4CC /* RxWKUIDelegateEvents+Rx.swift in Sources */, + B397D15B802E8E8FD7EDFA24 /* RxWKUIDelegateProxy.swift in Sources */, + 6BB38DB8D5689202C115BCF3 /* RxWKUserContentController.swift in Sources */, + 9139715816BAB90AD44FA2EC /* WKNavigationDelegateEvents+Rx.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - EFC27F83246D7E9C0093D8B3 /* Sources */ = { + ED9485E33C77940C3A0697FB /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - EFC27F84246D7E9C0093D8B3 /* RxWebKitTests.swift in Sources */, - EFC27F85246D7E9C0093D8B3 /* ForwardsEventsBehavior.swift in Sources */, - EFC27F86246D7E9C0093D8B3 /* HasEventsBehavior.swift in Sources */, + C86EA358EF6F9BFA2BCFB255 /* ForwardsEventsBehavior.swift in Sources */, + EFC1B706FB90B136F7D83835 /* HasEventsBehavior.swift in Sources */, + 9E0963B57B28DF4BE1950177 /* RxWebKitTests.swift in Sources */, + 7CDF1FAD925F785675AAF90A /* XCTestManifests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 42F426D41C6623C5001FED46 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 42F426CD1C6623C5001FED46 /* RxWebKit */; - targetProxy = 42F426D31C6623C5001FED46 /* PBXContainerItemProxy */; - }; - C4CB7D4A22874E5600FB8D99 /* PBXTargetDependency */ = { + 52080388F03EB4880C5BC4A7 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 42F426CD1C6623C5001FED46 /* RxWebKit */; - targetProxy = C4CB7D4922874E5600FB8D99 /* PBXContainerItemProxy */; + target = D9E0F0A0F8B2C599B1A60698 /* RxWebKit macOS */; + targetProxy = B452ECFE49AE3B90A31EE2B3 /* PBXContainerItemProxy */; }; - EFC27F81246D7E9C0093D8B3 /* PBXTargetDependency */ = { + 9E8AB03710ABD6043D6F43A0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 42F426CD1C6623C5001FED46 /* RxWebKit */; - targetProxy = EFC27F82246D7E9C0093D8B3 /* PBXContainerItemProxy */; + target = 97506B98C69296A031B89188 /* RxWebKit iOS */; + targetProxy = 2F92DBF9B72EFAA3047F3F86 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ -/* Begin PBXVariantGroup section */ - 42F426B01C66223E001FED46 /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 42F426B11C66223E001FED46 /* Base */, - ); - name = LaunchScreen.storyboard; - path = .; - sourceTree = ""; +/* Begin XCBuildConfiguration section */ + 0D82ACE9318862AB0239848B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; + CODE_SIGN_IDENTITY = ""; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/Mac", + ); + INFOPLIST_FILE = Sources/RxWebKit/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "RxSwiftCommunity.RxWebKit.RxWebKit-macOS"; + PRODUCT_NAME = RxWebKit; + SDKROOT = macosx; + SKIP_INSTALL = NO; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; }; - 42F426B21C66223E001FED46 /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 42F426B31C66223E001FED46 /* Base */, - ); - name = Main.storyboard; - path = .; - sourceTree = ""; + 57400FB31312F208BFCD28A4 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_IDENTITY = ""; + COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/Mac", + ); + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/../Frameworks", + ); + SDKROOT = macosx; + }; + name = Release; }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 42F426A71C66200D001FED46 /* Debug */ = { + 87252B4ACF9FEE1ED60C28CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); + INFOPLIST_FILE = Sources/RxWebKit/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "RxSwiftCommunity.RxWebKit.RxWebKit-iOS"; + PRODUCT_NAME = RxWebKit; + SDKROOT = iphoneos; + SKIP_INSTALL = NO; + SUPPORTS_MACCATALYST = NO; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; + 8C1FF5D3A087B40A0965A8AE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_IDENTITY = ""; + COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/Mac", + ); + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/../Frameworks", + ); + SDKROOT = macosx; + }; + name = Debug; + }; + A2E61369316EA25960EFEF9E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + B78231580C39DC706AC94CD9 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; @@ -606,35 +566,24 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; - "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*]" = ( - "$(SRCROOT)/Carthage/Build/iOS", - "$(inherited)", - ); - "FRAMEWORK_SEARCH_PATHS[sdk=iphonesimulator*]" = ( - "$(SRCROOT)/Carthage/Build/iOS", - "$(inherited)", - ); - "FRAMEWORK_SEARCH_PATHS[sdk=macosx*]" = ( - "$(SRCROOT)/Carthage/Build/Mac", - "$(inherited)", - ); - GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", "$(inherited)", + "DEBUG=1", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; @@ -642,32 +591,36 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MACOSX_DEPLOYMENT_TARGET = 10.13; - MTL_ENABLE_DEBUG_INFO = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; - SDKROOT = ""; - SUPPORTED_PLATFORMS = "iphonesimulator iphoneos macosx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; }; name = Debug; }; - 42F426A81C66200D001FED46 /* Release */ = { + CAB912EEA2287EB9739361FF /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; @@ -676,29 +629,18 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*]" = ( - "$(SRCROOT)/Carthage/Build/iOS", - "$(inherited)", - ); - "FRAMEWORK_SEARCH_PATHS[sdk=iphonesimulator*]" = ( - "$(SRCROOT)/Carthage/Build/iOS", - "$(inherited)", - ); - "FRAMEWORK_SEARCH_PATHS[sdk=macosx*]" = ( - "$(SRCROOT)/Carthage/Build/Mac", - "$(inherited)", - ); - GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; @@ -706,263 +648,143 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = ""; - SUPPORTED_PLATFORMS = "iphonesimulator iphoneos macosx"; - SWIFT_VERSION = 5.0; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 42F426AA1C66200D001FED46 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_MODULES = YES; - DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = "$(SRCROOT)/Example/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = mokumoku.Example; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = iphoneos; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - }; - name = Debug; - }; - 42F426AB1C66200D001FED46 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_MODULES = YES; - DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = "$(SRCROOT)/Example/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = mokumoku.Example; + MTL_FAST_MATH = YES; PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = iphoneos; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; SWIFT_VERSION = 5.0; }; name = Release; }; - 42F426D81C6623C5001FED46 /* Debug */ = { + D8579BABF3231706F12634A3 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_ENABLE_MODULES = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; + CODE_SIGN_IDENTITY = ""; + COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "$(SRCROOT)/RxWebKit/Info.plist"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/Mac", + ); + INFOPLIST_FILE = Sources/RxWebKit/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = mokumoku.RxWebKit; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "RxSwiftCommunity.RxWebKit.RxWebKit-macOS"; + PRODUCT_NAME = RxWebKit; + SDKROOT = macosx; + SKIP_INSTALL = NO; VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; }; name = Debug; }; - 42F426D91C6623C5001FED46 /* Release */ = { + E4AA37EB8FC074D5EA73A6B0 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_ENABLE_MODULES = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + BUNDLE_LOADER = "$(TEST_HOST)"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + F01704DC65F050321DBFFB7E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; + CODE_SIGN_IDENTITY = ""; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "$(SRCROOT)/RxWebKit/Info.plist"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); + INFOPLIST_FILE = Sources/RxWebKit/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = mokumoku.RxWebKit; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 5.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "RxSwiftCommunity.RxWebKit.RxWebKit-iOS"; + PRODUCT_NAME = RxWebKit; + SDKROOT = iphoneos; + SKIP_INSTALL = NO; + SUPPORTS_MACCATALYST = NO; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - C4CB7D4C22874E5600FB8D99 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; - CODE_SIGN_STYLE = Manual; - DEVELOPMENT_TEAM = ""; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = RxWebKitTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.2; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks @loader_path/../Frameworks"; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = bobgodwinx.RxWebKitTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - C4CB7D4D22874E5600FB8D99 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; - CODE_SIGN_STYLE = Manual; - DEVELOPMENT_TEAM = ""; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = RxWebKitTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.2; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks @loader_path/../Frameworks"; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = bobgodwinx.RxWebKitTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; - EFC27F91246D7E9C0093D8B3 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "-"; - CODE_SIGN_STYLE = Manual; - DEVELOPMENT_TEAM = ""; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = RxWebKitTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.2; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks @loader_path/../Frameworks"; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = bobgodwinx.RxWebKitTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - SDKROOT = macosx; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - EFC27F92246D7E9C0093D8B3 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "-"; - CODE_SIGN_STYLE = Manual; - DEVELOPMENT_TEAM = ""; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = RxWebKitTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.2; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks @loader_path/../Frameworks"; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = bobgodwinx.RxWebKitTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - SDKROOT = macosx; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 42F426921C66200D001FED46 /* Build configuration list for PBXProject "RxWebKit" */ = { + 17913BB7275236E4931500D8 /* Build configuration list for PBXNativeTarget "RxWebKitTests iOS" */ = { isa = XCConfigurationList; buildConfigurations = ( - 42F426A71C66200D001FED46 /* Debug */, - 42F426A81C66200D001FED46 /* Release */, + A2E61369316EA25960EFEF9E /* Debug */, + E4AA37EB8FC074D5EA73A6B0 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 42F426A91C66200D001FED46 /* Build configuration list for PBXNativeTarget "Example" */ = { + 4943091B8B465B2827C5729C /* Build configuration list for PBXProject "RxWebKit" */ = { isa = XCConfigurationList; buildConfigurations = ( - 42F426AA1C66200D001FED46 /* Debug */, - 42F426AB1C66200D001FED46 /* Release */, + B78231580C39DC706AC94CD9 /* Debug */, + CAB912EEA2287EB9739361FF /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 42F426D71C6623C5001FED46 /* Build configuration list for PBXNativeTarget "RxWebKit" */ = { + 681329872F44E9CD297DA311 /* Build configuration list for PBXNativeTarget "RxWebKit macOS" */ = { isa = XCConfigurationList; buildConfigurations = ( - 42F426D81C6623C5001FED46 /* Debug */, - 42F426D91C6623C5001FED46 /* Release */, + D8579BABF3231706F12634A3 /* Debug */, + 0D82ACE9318862AB0239848B /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - C4CB7D4B22874E5600FB8D99 /* Build configuration list for PBXNativeTarget "RxWebKitTests-iOS" */ = { + CF90D785D3B39DAC831D228E /* Build configuration list for PBXNativeTarget "RxWebKit iOS" */ = { isa = XCConfigurationList; buildConfigurations = ( - C4CB7D4C22874E5600FB8D99 /* Debug */, - C4CB7D4D22874E5600FB8D99 /* Release */, + F01704DC65F050321DBFFB7E /* Debug */, + 87252B4ACF9FEE1ED60C28CD /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - EFC27F90246D7E9C0093D8B3 /* Build configuration list for PBXNativeTarget "RxWebKitTests-macOS" */ = { + FC19328CC031D0C2347862B3 /* Build configuration list for PBXNativeTarget "RxWebKitTests macOS" */ = { isa = XCConfigurationList; buildConfigurations = ( - EFC27F91246D7E9C0093D8B3 /* Debug */, - EFC27F92246D7E9C0093D8B3 /* Release */, + 8C1FF5D3A087B40A0965A8AE /* Debug */, + 57400FB31312F208BFCD28A4 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; - rootObject = 42F4268F1C66200D001FED46 /* Project object */; + rootObject = 865BBEF49ACC978CE062F291 /* Project object */; } diff --git a/RxWebKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/RxWebKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..37b4946 --- /dev/null +++ b/RxWebKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/RxWebKit.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/RxWebKit.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/RxWebKit.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/RxWebKit.xcodeproj/xcshareddata/xcschemes/RxWebKit.xcscheme b/RxWebKit.xcodeproj/xcshareddata/xcschemes/RxWebKit iOS.xcscheme similarity index 54% rename from RxWebKit.xcodeproj/xcshareddata/xcschemes/RxWebKit.xcscheme rename to RxWebKit.xcodeproj/xcshareddata/xcschemes/RxWebKit iOS.xcscheme index 8a4801e..c34520c 100644 --- a/RxWebKit.xcodeproj/xcshareddata/xcschemes/RxWebKit.xcscheme +++ b/RxWebKit.xcodeproj/xcshareddata/xcschemes/RxWebKit iOS.xcscheme @@ -1,6 +1,6 @@ + + + + @@ -26,18 +40,32 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + codeCoverageEnabled = "YES" + onlyGenerateCoverageForSpecifiedTargets = "NO" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + + + - - + + + + - + - + + + diff --git a/RxWebKit.xcodeproj/xcshareddata/xcschemes/RxWebKit macOS.xcscheme b/RxWebKit.xcodeproj/xcshareddata/xcschemes/RxWebKit macOS.xcscheme new file mode 100644 index 0000000..7342de2 --- /dev/null +++ b/RxWebKit.xcodeproj/xcshareddata/xcschemes/RxWebKit macOS.xcscheme @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RxWebKit.xcodeproj/xcshareddata/xcschemes/RxWebKitTests-iOS.xcscheme b/RxWebKit.xcodeproj/xcshareddata/xcschemes/RxWebKitTests-iOS.xcscheme deleted file mode 100644 index 6af5edb..0000000 --- a/RxWebKit.xcodeproj/xcshareddata/xcschemes/RxWebKitTests-iOS.xcscheme +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/RxWebKit.xcodeproj/xcshareddata/xcschemes/RxWebKitTests-macOS.xcscheme b/RxWebKit.xcodeproj/xcshareddata/xcschemes/RxWebKitTests-macOS.xcscheme deleted file mode 100644 index 93914ea..0000000 --- a/RxWebKit.xcodeproj/xcshareddata/xcschemes/RxWebKitTests-macOS.xcscheme +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/RxWebKit/Info.plist b/RxWebKit/Info.plist deleted file mode 100644 index 9d45612..0000000 --- a/RxWebKit/Info.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - FMWK - CFBundleShortVersionString - 0.3 - CFBundleSignature - ???? - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - NSPrincipalClass - - - diff --git a/RxWebKit/RxWebKit.h b/RxWebKit/RxWebKit.h deleted file mode 100644 index a3aded6..0000000 --- a/RxWebKit/RxWebKit.h +++ /dev/null @@ -1,21 +0,0 @@ -// -// RxWebKit.h -// RxWebKit -// -// Created by Daichi Ichihara on 2016/02/06. -// Copyright © 2016年 RxSwift Community. All rights reserved. -// - -#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR -#import -#elseif TARGET_OS_MAC -#endif -//! Project version number for RxWebKit. -extern double RxWebKitVersionNumber; - -//! Project version string for RxWebKit. -extern const unsigned char RxWebKitVersionString[]; - -// In this header, you should import all the public headers of your framework using statements like #import - - diff --git a/RxWebKit/Sources/Rx+WebKit.swift b/RxWebKit/Sources/Rx+WebKit.swift deleted file mode 100644 index bb9e73d..0000000 --- a/RxWebKit/Sources/Rx+WebKit.swift +++ /dev/null @@ -1,80 +0,0 @@ -// -// Rx+WebKit.swift -// RxWebKit -// -// Created by Daichi Ichihara on 2016/02/06. -// Copyright © 2016年 RxSwift Community. All rights reserved. -// - -import Foundation -import WebKit -import RxSwift -import RxCocoa - -extension Reactive where Base: WKWebView { - /** - Reactive wrapper for `title` property - */ - public var title: Observable { - return self.observeWeakly(String.self, "title") - } - - /** - Reactive wrapper for `loading` property. - */ - public var loading: Observable { - return self.observeWeakly(Bool.self, "loading") - .map { $0 ?? false } - } - - /** - Reactive wrapper for `estimatedProgress` property. - */ - public var estimatedProgress: Observable { - return self.observeWeakly(Double.self, "estimatedProgress") - .map { $0 ?? 0.0 } - } - - /** - Reactive wrapper for `url` property. - */ - public var url: Observable { - return self.observeWeakly(URL.self, "URL") - } - - - /** - Reactive wrapper for `canGoBack` property. - */ - public var canGoBack: Observable { - return self.observeWeakly(Bool.self, "canGoBack") - .map { $0 ?? false } - } - - /** - Reactive wrapper for `canGoForward` property. - */ - public var canGoForward: Observable { - return self.observeWeakly(Bool.self, "canGoForward") - .map { $0 ?? false } - } - - - /// Reactive wrapper for `evaluateJavaScript(_:completionHandler:)` method. - /// - /// - Parameter javaScriptString: The JavaScript string to evaluate. - /// - Returns: Observable sequence of result of the script evaluation. - public func evaluateJavaScript(_ javaScriptString:String) -> Observable { - return Observable.create { [weak base] observer in - base?.evaluateJavaScript(javaScriptString) { value, error in - if let error = error { - observer.onError(error) - } else { - observer.onNext(value) - observer.onCompleted() - } - } - return Disposables.create() - } - } -} diff --git a/RxWebKit/Sources/RxWKNavigationDelegateProxy.swift b/RxWebKit/Sources/RxWKNavigationDelegateProxy.swift deleted file mode 100644 index 0853906..0000000 --- a/RxWebKit/Sources/RxWKNavigationDelegateProxy.swift +++ /dev/null @@ -1,44 +0,0 @@ -// -// RxWKNavigationDelegateProxy.swift -// RxWebKit -// -// Created by Bob Obi on 23.10.17. -// Copyright © 2017 RxSwift Community. All rights reserved. -// - -import WebKit -#if !RX_NO_MODULE - import RxSwift - import RxCocoa -#endif - -public typealias RxWKNavigationDelegate = DelegateProxy - -open class RxWKNavigationDelegateProxy: RxWKNavigationDelegate, DelegateProxyType, WKNavigationDelegate { - - /// Type of parent object - public weak private(set) var webView: WKWebView? - - /// Init with ParentObject - public init(parentObject: ParentObject) { - webView = parentObject - super.init(parentObject: parentObject, delegateProxy: RxWKNavigationDelegateProxy.self) - } - - /// Register self to known implementations - public static func registerKnownImplementations() { - self.register { parent -> RxWKNavigationDelegateProxy in - RxWKNavigationDelegateProxy(parentObject: parent) - } - } - - /// Gets the current `WKNavigationDelegate` on `WKWebView` - open class func currentDelegate(for object: ParentObject) -> WKNavigationDelegate? { - return object.navigationDelegate - } - - /// Set the navigationDelegate for `WKWebView` - open class func setCurrentDelegate(_ delegate: WKNavigationDelegate?, to object: ParentObject) { - object.navigationDelegate = delegate - } -} diff --git a/RxWebKit/Sources/RxWKUIDelegateEvents+Rx.swift b/RxWebKit/Sources/RxWKUIDelegateEvents+Rx.swift deleted file mode 100644 index 862c69d..0000000 --- a/RxWebKit/Sources/RxWKUIDelegateEvents+Rx.swift +++ /dev/null @@ -1,95 +0,0 @@ -// -// RxWKUIDelegateEvents+Rx.swift -// RxWebKit -// -// Created by Bob Obi on 25.10.17. -// Copyright © 2017 RxSwift Community. All rights reserved. -// - -#if !RX_NO_MODULE - import RxSwift - import RxCocoa -#endif - -import WebKit - -extension Reactive where Base: WKWebView { - public typealias JSAlertEvent = (webView: WKWebView, message: String, frame: WKFrameInfo, handler: () -> ()) - public typealias JSConfirmEvent = (webView: WKWebView, message: String, frame: WKFrameInfo, handler: (Bool) -> ()) - #if os(iOS) - public typealias CommitPreviewEvent = (webView: WKWebView, controller: UIViewController) - #endif - - /// Reactive wrapper for `navigationDelegate`. - public var uiDelegate: DelegateProxy { - return RxWKUIDelegateProxy.proxy(for: base) - } - - /// Reactive wrapper for `func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Swift.Void)` - public var javaScriptAlertPanel: ControlEvent { - typealias __CompletionHandler = @convention(block) () -> () - let source:Observable = uiDelegate - .methodInvoked(.jsAlert).map { args in - let view = try castOrThrow(WKWebView.self, args[0]) - let message = try castOrThrow(String.self, args[1]) - let frame = try castOrThrow(WKFrameInfo.self, args[2]) - var closureObject: AnyObject? = nil - var mutableArgs = args - mutableArgs.withUnsafeMutableBufferPointer { ptr in - closureObject = ptr[3] as AnyObject - } - let __completionBlockPtr = UnsafeRawPointer(Unmanaged.passUnretained(closureObject as AnyObject).toOpaque()) - let handler = unsafeBitCast(__completionBlockPtr, to: __CompletionHandler.self) - return (view, message, frame, handler) - } - - return ControlEvent(events: source) - } - - /// Reactive wrapper for `func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Swift.Void)` - public var javaScriptConfirmPanel: ControlEvent { - typealias __ConfirmHandler = @convention(block) (Bool) -> () - let source:Observable = uiDelegate - .methodInvoked(.jsConfirm).map { args in - let view = try castOrThrow(WKWebView.self, args[0]) - let message = try castOrThrow(String.self, args[1]) - let frame = try castOrThrow(WKFrameInfo.self, args[2]) - var closureObject: AnyObject? = nil - var mutableArgs = args - mutableArgs.withUnsafeMutableBufferPointer { ptr in - closureObject = ptr[3] as AnyObject - } - let __confirmBlockPtr = UnsafeRawPointer(Unmanaged.passUnretained(closureObject as AnyObject).toOpaque()) - let handler = unsafeBitCast(__confirmBlockPtr, to: __ConfirmHandler.self) - return (view, message, frame, handler) - } - - return ControlEvent(events: source) - } - - #if os(iOS) - /// Reactive wrappper for `func webView(_ webView: WKWebView, commitPreviewingViewController previewingViewController: UIViewController)` - @available(iOS 10.0, *) - public var commitPreviewing: ControlEvent { - let source: Observable = uiDelegate - .methodInvoked(.commitPreviewing) - .map { args in - let view = try castOrThrow(WKWebView.self, args[0]) - let controller = try castOrThrow(UIViewController.self, args[1]) - return (view, controller) - } - - return ControlEvent(events: source) - } - #endif -} - -fileprivate extension Selector { - static let jsAlert = #selector(WKUIDelegate.webView(_:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:)) - static let jsConfirm = #selector(WKUIDelegate.webView(_:runJavaScriptConfirmPanelWithMessage:initiatedByFrame:completionHandler:)) - - #if os(iOS) - @available(iOS 10.0, *) - static let commitPreviewing = #selector(WKUIDelegate.webView(_:commitPreviewingViewController:)) - #endif -} diff --git a/RxWebKit/Sources/RxWKUIDelegateProxy.swift b/RxWebKit/Sources/RxWKUIDelegateProxy.swift deleted file mode 100644 index ad2d278..0000000 --- a/RxWebKit/Sources/RxWKUIDelegateProxy.swift +++ /dev/null @@ -1,45 +0,0 @@ -// -// RxWKUIDelegateProxy.swift -// RxWebKit -// -// Created by Bob Obi on 25.10.17. -// Copyright © 2017 RxSwift Community. All rights reserved. -// - -import WebKit -#if !RX_NO_MODULE - import RxSwift - import RxCocoa -#endif - -public typealias RxWKUIDelegate = DelegateProxy - -open class RxWKUIDelegateProxy: RxWKUIDelegate, DelegateProxyType, WKUIDelegate { - - /// Type of parent object - /// must be WKWebView! - public weak private(set) var webView: WKWebView? - - /// Init with ParentObject - public init(parentObject: ParentObject) { - webView = parentObject - super.init(parentObject: parentObject, delegateProxy: RxWKUIDelegateProxy.self) - } - - /// Register self to known implementations - public static func registerKnownImplementations() { - self.register { parent -> RxWKUIDelegateProxy in - RxWKUIDelegateProxy(parentObject: parent) - } - } - - /// Gets the current `WKUIDelegate` on `WKWebView` - open class func currentDelegate(for object: ParentObject) -> WKUIDelegate? { - return object.uiDelegate - } - - /// Set the uiDelegate for `WKWebView` - open class func setCurrentDelegate(_ delegate: WKUIDelegate?, to object: ParentObject) { - object.uiDelegate = delegate - } -} diff --git a/RxWebKit/Sources/RxWKUserContentController.swift b/RxWebKit/Sources/RxWKUserContentController.swift deleted file mode 100644 index cdb6e88..0000000 --- a/RxWebKit/Sources/RxWKUserContentController.swift +++ /dev/null @@ -1,47 +0,0 @@ -// -// RxWKUserContentController.swift -// RxWebKit -// -// Created by Jesse Hao on 2019/3/30. -// Copyright © 2019 RxSwift Community. All rights reserved. -// - -import WebKit -#if !RX_NO_MODULE - import RxSwift - import RxCocoa -#endif - -extension WKUserContentController { - fileprivate class MessageHandler : NSObject, WKScriptMessageHandler { - typealias MessageReceiveHandler = (WKScriptMessage) -> Void - private var messageReceiveHandler:MessageReceiveHandler? - - func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { - self.messageReceiveHandler?(message) - } - - func onReceive(_ handler:@escaping MessageReceiveHandler) { - self.messageReceiveHandler = handler - } - } -} - -public extension Reactive where Base : WKUserContentController { - /// Observable sequence of script message. - /// - /// - Parameter name: The name of the message handler - /// - Returns: Observable sequence of script message. - func scriptMessage(forName name:String) -> ControlEvent { - return ControlEvent(events: Observable.create { [weak base] observer in - let handler = WKUserContentController.MessageHandler() - base?.add(handler, name: name) - handler.onReceive { - observer.onNext($0) - } - return Disposables.create { - base?.removeScriptMessageHandler(forName: name) - } - }) - } -} diff --git a/RxWebKit/Sources/WKNavigationDelegateEvents+Rx.swift b/RxWebKit/Sources/WKNavigationDelegateEvents+Rx.swift deleted file mode 100644 index 878c1d9..0000000 --- a/RxWebKit/Sources/WKNavigationDelegateEvents+Rx.swift +++ /dev/null @@ -1,264 +0,0 @@ -// -// WKNavigationDelegateEvents+Rx.swift -// RxWebKit -// -// Created by Bob Obi on 23.10.17. -// Copyright © 2017 RxSwift Community. All rights reserved. -// - -#if !RX_NO_MODULE - import RxSwift - import RxCocoa -#endif - -import WebKit - -func castOrThrow(_ resultType: T.Type, _ object: Any) throws -> T { - guard let returnValue = object as? T else { - throw RxCocoaError.castingError(object: object, targetType: resultType) - } - return returnValue -} - -extension Reactive where Base: WKWebView { - /// WKNavigationEvent emits a tuple that contains both - /// WKWebView + WKNavigation - public typealias WKNavigationEvent = (webView: WKWebView, navigation: WKNavigation) - - /// WKNavigationFailedEvent emits a tuple that contains both - /// WKWebView + WKNavigation + Swift.Error - public typealias WKNavigationFailEvent = (webView: WKWebView, navigation: WKNavigation, error: Error) - - /// ChallengeHandler this is exposed to the user on subscription - public typealias ChallengeHandler = (URLSession.AuthChallengeDisposition, URLCredential?) -> Void - /// WKNavigationChallengeEvent emits a tuple event of WKWebView + challenge + ChallengeHandler - public typealias WKNavigationChallengeEvent = (webView: WKWebView, challenge: URLAuthenticationChallenge, handler: ChallengeHandler) - - /// DecisionHandler this is the block exposed to the user on subscription - public typealias DecisionHandler = (WKNavigationResponsePolicy) -> Void - /// WKNavigationResponsePolicyEvent emits a tuple event of WKWebView + WKNavigationResponse + DecisionHandler - public typealias WKNavigationResponsePolicyEvent = ( webView: WKWebView, reponse: WKNavigationResponse, handler: DecisionHandler) - /// ActionHandler this is the block exposed to the user on subscription - public typealias ActionHandler = (WKNavigationActionPolicy) -> Void - /// WKNavigationActionPolicyEvent emits a tuple event of WKWebView + WKNavigationAction + ActionHandler - public typealias WKNavigationActionPolicyEvent = ( webView: WKWebView, action: WKNavigationAction, handler: ActionHandler) - - /// Reactive wrapper for `navigationDelegate`. - public var delegate: DelegateProxy { - return RxWKNavigationDelegateProxy.proxy(for: base) - } - - /// Reactive wrapper for delegate method `webView(_ webView: WKWebView, didCommit navigation: WKNavigation!)`. - public var didCommitNavigation: ControlEvent { - let source: Observable = delegate - .methodInvoked(.didCommitNavigation) - .map { arg in - let view = try castOrThrow(WKWebView.self, arg[0]) - let nav = try castOrThrow(WKNavigation.self, arg[1]) - return (view, nav) - } - return ControlEvent(events: source) - } - - /// Reactive wrapper for delegate method `webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!)`. - public var didStartProvisionalNavigation: ControlEvent { - let source: Observable = delegate - .methodInvoked(.didStartProvisionalNavigation) - .map { arg in - let view = try castOrThrow(WKWebView.self, arg[0]) - let nav = try castOrThrow(WKNavigation.self, arg[1]) - return (view, nav) - } - return ControlEvent(events: source) - } - - /// Reactive wrapper for delegate method `webView(_ webView: WKWebView, didFinish navigation: WKNavigation!)` - public var didFinishNavigation: ControlEvent { - let source: Observable = delegate - .methodInvoked(.didFinishNavigation) - .map { arg in - let view = try castOrThrow(WKWebView.self, arg[0]) - let nav = try castOrThrow(WKNavigation.self, arg[1]) - return (view, nav) - } - return ControlEvent(events: source) - } - - /// Reactive wrapper for delegate method `webViewWebContentProcessDidTerminate(_ webView: WKWebView)`. - @available(iOS 9.0, *) - public var didTerminate: ControlEvent { - let source: Observable = delegate - .methodInvoked(.didTerminate) - .map { try castOrThrow(WKWebView.self, $0[0]) } - return ControlEvent(events: source) - } - - /// Reactive wrapper for delegate method `webView(_ webView: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!)`. - public var didReceiveServerRedirectForProvisionalNavigation: ControlEvent { - let source: Observable = delegate - .methodInvoked(.didReceiveServerRedirectForProvisionalNavigation) - .map { arg in - let view = try castOrThrow(WKWebView.self, arg[0]) - let nav = try castOrThrow(WKNavigation.self, arg[1]) - return (view, nav) - } - return ControlEvent(events: source) - } - - /// Reactive wrapper for delegate method `webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error)`. - public var didFailNavigation: ControlEvent { - let source: Observable = delegate - .methodInvoked(.didFailNavigation) - .map { arg in - let view = try castOrThrow(WKWebView.self, arg[0]) - let nav = try castOrThrow(WKNavigation.self, arg[1]) - let error = try castOrThrow(Swift.Error.self, arg[2]) - return (view, nav, error) - } - return ControlEvent(events: source) - } - - /// Reactive wrapper for delegate method `webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error)`. - public var didFailProvisionalNavigation: ControlEvent { - let source: Observable = delegate - .methodInvoked(.didFailProvisionalNavigation) - .map { arg in - let view = try castOrThrow(WKWebView.self, arg[0]) - let nav = try castOrThrow(WKNavigation.self, arg[1]) - let error = try castOrThrow(Swift.Error.self, arg[2]) - return (view, nav, error) - } - return ControlEvent(events: source) - } - - /// Reactive wrapper for delegate method `webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)` - public var didReceiveChallenge: ControlEvent { - /// __ChallengeHandler is same as ChallengeHandler - /// They are interchangeable, __ChallengeHandler is for internal use. - /// ChallengeHandler is exposed to the user on subscription. - /// @convention attribute makes the swift closure compatible with Objc blocks - typealias __ChallengeHandler = @convention(block) (URLSession.AuthChallengeDisposition, URLCredential?) -> Void - /*! @abstract Invoked when the web view needs to respond to an authentication challenge. - @param webView The web view that received the authentication challenge. - @param challenge The authentication challenge. - @param completionHandler The completion handler you must invoke to respond to the challenge. The - disposition argument is one of the constants of the enumerated type - NSURLSessionAuthChallengeDisposition. When disposition is NSURLSessionAuthChallengeUseCredential, - the credential argument is the credential to use, or nil to indicate continuing without a - credential. - @discussion If you do not implement this method, the web view will respond to the authentication challenge with the NSURLSessionAuthChallengeRejectProtectionSpace disposition. - */ - let source: Observable = delegate - .sentMessage(.didReceiveChallenge) - .map { arg in - /// Extracting the WKWebView from the array at index zero - /// which is the first argument of the function signature - let view = try castOrThrow(WKWebView.self, arg[0]) - /// Extracting the URLAuthenticationChallenge from the array at index one - /// which is the second argument of the function signature - let challenge = try castOrThrow(URLAuthenticationChallenge.self, arg[1]) - /// Now you `Can't` transform closure easily because they are excuted - /// in the stack if try it you will get the famous error - /// `Could not cast value of type '__NSStackBlock__' (0x12327d1a8) to` - /// this is because closures are transformed into a system type which is `__NSStackBlock__` - /// the above mentioned type is not exposed to `developer`. So everytime - /// you execute a closure the compiler transforms it into this Object. - /// So you go through the following steps to get a human readable type - /// of the closure signature: - /// 1. closureObject is type of AnyObject to that holds the raw value from - /// the array. - var closureObject: AnyObject? = nil - /// 2. make the array mutable in order to access the `withUnsafeMutableBufferPointer` - /// fuctionalities - var mutableArg = arg - /// 3. Grab the closure at index 3 of the array, but we have to use the C-style - /// approach to access the raw memory underpinning the array and store it in closureObject - /// Now the object stored in the `closureObject` is `Unmanaged` and `some unspecified type` - /// the intelligent swift compiler doesn't know what sort of type it contains. It is Raw. - mutableArg.withUnsafeMutableBufferPointer { ptr in - closureObject = ptr[2] as AnyObject - } - /// 4. instantiate an opaque pointer to referenc the value of the `unspecified type` - let __challengeBlockPtr = UnsafeRawPointer(Unmanaged.passUnretained(closureObject as AnyObject).toOpaque()) - /// 5. Here the magic happen we forcefully tell the compiler that anything - /// found at this memory address that is refrenced should be a type of - /// `__ChallengeHandler`! - let handler = unsafeBitCast(__challengeBlockPtr, to: __ChallengeHandler.self) - return (view, challenge, handler) - } - - return ControlEvent(events: source) - - /** - Reference: - - This is a holy grail part for more information please read the following articles. - 1: http://codejaxy.com/q/332345/ios-objective-c-memory-management-automatic-ref-counting-objective-c-blocks-understand-one-edge-case-of-block-memory-management-in-objc - 2: http://www.galloway.me.uk/2012/10/a-look-inside-blocks-episode-2/ - 3: https://maniacdev.com/2013/11/tutorial-an-in-depth-guide-to-objective-c-block-debugging - 4: get know how [__NSStackBlock__ + UnsafeRawPointer + unsafeBitCast] works under the hood - 5: https://en.wikipedia.org/wiki/Opaque_pointer - 6: https://stackoverflow.com/questions/43662363/cast-objective-c-block-nsstackblock-into-swift-3 - */ - } - - /// Reactive wrapper for `func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Swift.Void)` - public var decidePolicyNavigationResponse: ControlEvent { - typealias __DecisionHandler = @convention(block) (WKNavigationResponsePolicy) -> () - let source:Observable = delegate - .methodInvoked(.decidePolicyNavigationResponse).map { args in - let view = try castOrThrow(WKWebView.self, args[0]) - let response = try castOrThrow(WKNavigationResponse.self, args[1]) - var closureObject: AnyObject? = nil - var mutableArgs = args - mutableArgs.withUnsafeMutableBufferPointer { ptr in - closureObject = ptr[2] as AnyObject - } - let __decisionBlockPtr = UnsafeRawPointer(Unmanaged.passUnretained(closureObject as AnyObject).toOpaque()) - let handler = unsafeBitCast(__decisionBlockPtr, to: __DecisionHandler.self) - return (view, response, handler) - } - - return ControlEvent(events: source) - } - - /// Reactive wrapper for `func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Swift.Void)` - public var decidePolicyNavigationAction: ControlEvent { - typealias __ActionHandler = @convention(block) (WKNavigationActionPolicy) -> () - let source:Observable = delegate - .methodInvoked(.decidePolicyNavigationAction).map { args in - let view = try castOrThrow(WKWebView.self, args[0]) - let action = try castOrThrow(WKNavigationAction.self, args[1]) - var closureObject: AnyObject? = nil - var mutableArgs = args - mutableArgs.withUnsafeMutableBufferPointer { ptr in - closureObject = ptr[2] as AnyObject - } - let __actionBlockPtr = UnsafeRawPointer(Unmanaged.passUnretained(closureObject as AnyObject).toOpaque()) - let handler = unsafeBitCast(__actionBlockPtr, to: __ActionHandler.self) - return (view, action, handler) - } - - return ControlEvent(events: source) - } -} -extension Selector { - static let didCommitNavigation = #selector(WKNavigationDelegate.webView(_:didCommit:)) - static let didStartProvisionalNavigation = #selector(WKNavigationDelegate.webView(_:didStartProvisionalNavigation:)) - static let didFinishNavigation = #selector(WKNavigationDelegate.webView(_:didFinish:)) - static let didReceiveServerRedirectForProvisionalNavigation = #selector(WKNavigationDelegate.webView(_:didReceiveServerRedirectForProvisionalNavigation:)) - static let didFailNavigation = #selector(WKNavigationDelegate.webView(_:didFail:withError:)) - static let didFailProvisionalNavigation = #selector(WKNavigationDelegate.webView(_:didFailProvisionalNavigation:withError:)) - static let didReceiveChallenge = #selector(WKNavigationDelegate.webView(_:didReceive:completionHandler:)) - @available(iOS 9.0, *) - static let didTerminate = #selector(WKNavigationDelegate.webViewWebContentProcessDidTerminate(_:)) - /// Xcode give error when selectors results into having same signature - /// because of swift style you get for example: - /// Ambiguous use of 'webView(_:decidePolicyFor:decisionHandler:)' - /// please see this link for further understanding - /// https://bugs.swift.org/browse/SR-3062 - static let decidePolicyNavigationResponse = #selector(WKNavigationDelegate.webView(_:decidePolicyFor:decisionHandler:) as ((WKNavigationDelegate) -> (WKWebView, WKNavigationResponse, @escaping(WKNavigationResponsePolicy) -> Void) -> Void)?) - static let decidePolicyNavigationAction = #selector(WKNavigationDelegate.webView(_:decidePolicyFor:decisionHandler:) as ((WKNavigationDelegate) -> (WKWebView, WKNavigationAction, @escaping(WKNavigationActionPolicy) -> Void) -> Void)?) -} - - diff --git a/RxWebKitTests/ForwardsEventsBehavior.swift b/RxWebKitTests/ForwardsEventsBehavior.swift deleted file mode 100644 index 6eb05f3..0000000 --- a/RxWebKitTests/ForwardsEventsBehavior.swift +++ /dev/null @@ -1,67 +0,0 @@ - -import Foundation -import Quick -import Nimble -import RxSwift -import RxCocoa -import RxTest -import WebKit -@testable import RxWebKit - -struct ForwardsEventsBehaviorContext { - let sut: WKWebView - let scheduler: TestScheduler - let selector: Selector - let invoked: (() -> ()) - - init(_ sut: WKWebView, _ scheduler: TestScheduler, _ selector: Selector, invoked: @escaping(() -> ())) { - self.sut = sut - self.scheduler = scheduler - self.selector = selector - self.invoked = invoked - } -} - -class ForwardsEventsBehavior: Quick.Behavior { - override class func spec(_ context: @escaping () -> ForwardsEventsBehaviorContext) { - - var sut: WKWebView! - var scheduler: TestScheduler! - var selector: Selector! - var invoked: (() -> ())! - - beforeEach { - let cxt = context() - sut = cxt.sut - scheduler = cxt.scheduler - selector = cxt.selector - invoked = cxt.invoked - } - - afterEach { - sut = nil - scheduler = nil - selector = nil - } - - describe("Has Events Behavior") { - it("sentMessage") { - SharingScheduler.mock(scheduler: scheduler) { - let sentMessage = scheduler.record(source: sut.rx.delegate.sentMessage(selector)) - invoked() - scheduler.start() - expect(sentMessage.events.count).to(equal(1)) - } - } - - it("methodInvoke") { - SharingScheduler.mock(scheduler: scheduler) { - let methodInvoked = scheduler.record(source: sut.rx.delegate.methodInvoked(selector)) - invoked() - scheduler.start() - expect(methodInvoked.events.count).to(equal(1)) - } - } - } - } -} diff --git a/RxWebKitTests/HasEventsBehavior.swift b/RxWebKitTests/HasEventsBehavior.swift deleted file mode 100644 index 108cc13..0000000 --- a/RxWebKitTests/HasEventsBehavior.swift +++ /dev/null @@ -1,64 +0,0 @@ -import Foundation -import Quick -import Nimble -import RxSwift -import RxCocoa -import RxTest -import WebKit -@testable import RxWebKit - -struct HasEventsBehaviorContext { - let scheduler: TestScheduler - let observable: Observable - let expected: T? - init(_ scheduler: TestScheduler, _ observable: Observable, _ expected: T?) { - self.scheduler = scheduler - self.observable = observable - self.expected = expected - } -} - -class HasEventsBehavior: Quick.Behavior> { - override class func spec(_ context: @escaping () -> HasEventsBehaviorContext) { - var scheduler: TestScheduler! - var observable: Observable! - var expected: T? - - beforeEach { - let cxt = context() - scheduler = cxt.scheduler - observable = cxt.observable - expected = cxt.expected - } - - afterEach { - scheduler = nil - observable = nil - } - - describe("Has Events Behavior") { - it("Actually got the event") { - SharingScheduler.mock(scheduler: scheduler) { - let recorded = scheduler.record(source: observable) - scheduler.start() - expect(recorded.events.count).to(equal(1)) - expect(recorded.events[0].value.element).to(equal(expected)) - } - } - } - } -} - -extension TestScheduler { - /// Builds testable observer for s specific observable sequence, binds it's results and sets up disposal. - /// parameter source: Observable sequence to observe. - /// returns: Observer that records all events for observable sequence. - func record(source: O) -> TestableObserver { - let observer = self.createObserver(O.Element.self) - let disposable = source.asObservable().bind(to: observer) - self.scheduleAt(100000) { - disposable.dispose() - } - return observer - } -} diff --git a/RxWebKitTests/RxWebKitTests.swift b/RxWebKitTests/RxWebKitTests.swift deleted file mode 100644 index 7856f10..0000000 --- a/RxWebKitTests/RxWebKitTests.swift +++ /dev/null @@ -1,153 +0,0 @@ -import WebKit -import Quick -import Nimble -import RxSwift -import RxTest -@testable import RxWebKit - -class RxWebKitTests: QuickSpec { - override func spec() { - var scheduler: TestScheduler! - var sut: WKWebView! - let html = """ - - - - RxWebKit - - - -

This is a Heading

-

This is a paragraph.

- - - - """ - - beforeEach { - scheduler = TestScheduler(initialClock: 0) - sut = WKWebView(frame: CGRect.zero) - } - - afterEach { - scheduler = nil - sut = nil - } - - itBehavesLike(HasEventsBehavior.self) { - HasEventsBehaviorContext(scheduler, sut.rx.title, "") - } - - itBehavesLike(HasEventsBehavior.self) { - sut.loadHTMLString(html, baseURL: Bundle.main.resourceURL) - return HasEventsBehaviorContext(scheduler, sut.rx.loading, true) - } - - itBehavesLike(HasEventsBehavior.self) { - HasEventsBehaviorContext(scheduler, sut.rx.loading, false) - } - - itBehavesLike(HasEventsBehavior.self) { - HasEventsBehaviorContext(scheduler, sut.rx.estimatedProgress, 0.0) - } - - itBehavesLike(HasEventsBehavior.self) { - sut.loadHTMLString(html, baseURL: Bundle.main.resourceURL) - return HasEventsBehaviorContext(scheduler, sut.rx.estimatedProgress, 0.1) - } - - itBehavesLike(HasEventsBehavior.self) { - HasEventsBehaviorContext(scheduler, sut.rx.canGoBack, false) - } - - itBehavesLike(HasEventsBehavior.self) { - HasEventsBehaviorContext(scheduler, sut.rx.canGoForward, false) - } - - itBehavesLike(ForwardsEventsBehavior.self) { - ForwardsEventsBehaviorContext(sut, scheduler, .didTerminate) { - sut.navigationDelegate?.webViewWebContentProcessDidTerminate?(sut) - } - } - - itBehavesLike(ForwardsEventsBehavior.self) { - ForwardsEventsBehaviorContext(sut, scheduler, .didCommitNavigation) { - let navigation = sut.loadHTMLString(html, baseURL: Bundle.main.resourceURL) - sut.navigationDelegate?.webView?(sut, didCommit: navigation) - } - } - - itBehavesLike(ForwardsEventsBehavior.self) { - ForwardsEventsBehaviorContext(sut, scheduler, .didFinishNavigation) { - let navigation = sut.loadHTMLString(html, baseURL: Bundle.main.resourceURL) - sut.navigationDelegate?.webView?(sut, didFinish: navigation) - } - } - - itBehavesLike(ForwardsEventsBehavior.self) { - ForwardsEventsBehaviorContext(sut, scheduler, .didReceiveServerRedirectForProvisionalNavigation) { - let navigation = sut.loadHTMLString(html, baseURL: Bundle.main.resourceURL) - sut.navigationDelegate?.webView?(sut, didReceiveServerRedirectForProvisionalNavigation: navigation) - } - } - - itBehavesLike(ForwardsEventsBehavior.self) { - ForwardsEventsBehaviorContext(sut, scheduler, .didFailNavigation) { - let navigation = sut.loadHTMLString(html, baseURL: Bundle.main.resourceURL) - sut.navigationDelegate?.webView?(sut, didFail: navigation, withError: TestError.didFailNavigation) - } - } - - itBehavesLike(ForwardsEventsBehavior.self) { - ForwardsEventsBehaviorContext(sut, scheduler, .didFailProvisionalNavigation) { - let navigation = sut.loadHTMLString(html, baseURL: Bundle.main.resourceURL) - sut.navigationDelegate?.webView?(sut, didFailProvisionalNavigation: navigation, withError: TestError.didFailProvisionalNavigation) - } - } - - itBehavesLike(ForwardsEventsBehavior.self) { - ForwardsEventsBehaviorContext(sut, scheduler, .didReceiveChallenge) { - let protectionSpace = URLProtectionSpace(host: "fake", port: 8443, protocol: nil, realm: nil, authenticationMethod: nil) - let credential = URLCredential(user: "bad-user", password: "bad-password", persistence: URLCredential.Persistence.forSession) - let sender = MockURLAuthenticationChallengeSender() - - let challenge = URLAuthenticationChallenge(protectionSpace: protectionSpace, proposedCredential: credential, previousFailureCount: 0, failureResponse:nil, error: TestError.didReceiveChallenge, sender: sender) - - sut.navigationDelegate?.webView?(sut, didReceive: challenge, completionHandler: { (_, _) in }) - } - } - - itBehavesLike(ForwardsEventsBehavior.self) { - ForwardsEventsBehaviorContext(sut, scheduler, .decidePolicyNavigationAction) { - let delegate:WKNavigationDelegate? = sut.navigationDelegate - delegate?.webView?(sut, decidePolicyFor: WKNavigationAction(), decisionHandler: { (_) in }) - } - } - - itBehavesLike(ForwardsEventsBehavior.self) { - ForwardsEventsBehaviorContext(sut, scheduler, .decidePolicyNavigationResponse) { - let delegate:WKNavigationDelegate? = sut.navigationDelegate - delegate?.webView?(sut, decidePolicyFor: WKNavigationResponse(), decisionHandler: { (_) in }) - } - } - } -} - -enum TestError: Error { - case didFailNavigation - case didFailProvisionalNavigation - case didReceiveChallenge -} - -@objc class MockURLAuthenticationChallengeSender: NSObject, URLAuthenticationChallengeSender { - override func `self`() -> Self { - return self - } - - override init() {} - func use(_ credential: URLCredential, for challenge: URLAuthenticationChallenge) { } - - func continueWithoutCredential(for challenge: URLAuthenticationChallenge) {} - - func cancel(_ challenge: URLAuthenticationChallenge) { } -} diff --git a/RxWebKitTests/Info.plist b/Sources/RxWebKit/Info.plist similarity index 90% rename from RxWebKitTests/Info.plist rename to Sources/RxWebKit/Info.plist index 6c40a6c..e1fe4cf 100644 --- a/RxWebKitTests/Info.plist +++ b/Sources/RxWebKit/Info.plist @@ -13,10 +13,10 @@ CFBundleName $(PRODUCT_NAME) CFBundlePackageType - BNDL + FMWK CFBundleShortVersionString 1.0 CFBundleVersion - 1 + $(CURRENT_PROJECT_VERSION) diff --git a/Sources/RxWebKit/Rx+WebKit.swift b/Sources/RxWebKit/Rx+WebKit.swift new file mode 100644 index 0000000..e56167f --- /dev/null +++ b/Sources/RxWebKit/Rx+WebKit.swift @@ -0,0 +1,78 @@ +// +// Rx+WebKit.swift +// RxWebKit +// +// Created by Daichi Ichihara on 2016/02/06. +// Copyright © 2016年 RxSwift Community. All rights reserved. +// + +import Foundation +import RxCocoa +import RxSwift +import WebKit + +public extension Reactive where Base: WKWebView { + /** + Reactive wrapper for `title` property + */ + var title: Observable { + return observeWeakly(String.self, "title") + } + + /** + Reactive wrapper for `loading` property. + */ + var loading: Observable { + return observeWeakly(Bool.self, "loading") + .map { $0 ?? false } + } + + /** + Reactive wrapper for `estimatedProgress` property. + */ + var estimatedProgress: Observable { + return observeWeakly(Double.self, "estimatedProgress") + .map { $0 ?? 0.0 } + } + + /** + Reactive wrapper for `url` property. + */ + var url: Observable { + return observeWeakly(URL.self, "URL") + } + + /** + Reactive wrapper for `canGoBack` property. + */ + var canGoBack: Observable { + return observeWeakly(Bool.self, "canGoBack") + .map { $0 ?? false } + } + + /** + Reactive wrapper for `canGoForward` property. + */ + var canGoForward: Observable { + return observeWeakly(Bool.self, "canGoForward") + .map { $0 ?? false } + } + + /// Reactive wrapper for `evaluateJavaScript(_:completionHandler:)` method. + /// + /// - Parameter javaScriptString: The JavaScript string to evaluate. + /// - Returns: Observable sequence of result of the script evaluation. + func evaluateJavaScript(_ javaScriptString: String) -> Observable { + return Observable.create { [weak base] observer in + base?.evaluateJavaScript(javaScriptString) { value, error in + if let error = error { + observer.onError(error) + } else { + observer.onNext(value) + observer.onCompleted() + } + } + return Disposables.create() + } + } +} diff --git a/Sources/RxWebKit/RxWKNavigationDelegateProxy.swift b/Sources/RxWebKit/RxWKNavigationDelegateProxy.swift new file mode 100644 index 0000000..a4414c7 --- /dev/null +++ b/Sources/RxWebKit/RxWKNavigationDelegateProxy.swift @@ -0,0 +1,43 @@ +// +// RxWKNavigationDelegateProxy.swift +// RxWebKit +// +// Created by Bob Obi on 23.10.17. +// Copyright © 2017 RxSwift Community. All rights reserved. +// + +import WebKit +#if !RX_NO_MODULE + import RxCocoa + import RxSwift +#endif + +public typealias RxWKNavigationDelegate = DelegateProxy + +open class RxWKNavigationDelegateProxy: RxWKNavigationDelegate, DelegateProxyType, WKNavigationDelegate { + /// Type of parent object + public private(set) weak var webView: WKWebView? + + /// Init with ParentObject + public init(parentObject: ParentObject) { + webView = parentObject + super.init(parentObject: parentObject, delegateProxy: RxWKNavigationDelegateProxy.self) + } + + /// Register self to known implementations + public static func registerKnownImplementations() { + register { parent -> RxWKNavigationDelegateProxy in + RxWKNavigationDelegateProxy(parentObject: parent) + } + } + + /// Gets the current `WKNavigationDelegate` on `WKWebView` + open class func currentDelegate(for object: ParentObject) -> WKNavigationDelegate? { + return object.navigationDelegate + } + + /// Set the navigationDelegate for `WKWebView` + open class func setCurrentDelegate(_ delegate: WKNavigationDelegate?, to object: ParentObject) { + object.navigationDelegate = delegate + } +} diff --git a/Sources/RxWebKit/RxWKUIDelegateEvents+Rx.swift b/Sources/RxWebKit/RxWKUIDelegateEvents+Rx.swift new file mode 100644 index 0000000..efc88e7 --- /dev/null +++ b/Sources/RxWebKit/RxWKUIDelegateEvents+Rx.swift @@ -0,0 +1,95 @@ +// +// RxWKUIDelegateEvents+Rx.swift +// RxWebKit +// +// Created by Bob Obi on 25.10.17. +// Copyright © 2017 RxSwift Community. All rights reserved. +// + +#if !RX_NO_MODULE + import RxCocoa + import RxSwift +#endif + +import WebKit + +public extension Reactive where Base: WKWebView { + typealias JSAlertEvent = (webView: WKWebView, message: String, frame: WKFrameInfo, handler: () -> Void) + typealias JSConfirmEvent = (webView: WKWebView, message: String, frame: WKFrameInfo, handler: (Bool) -> Void) + #if os(iOS) + typealias CommitPreviewEvent = (webView: WKWebView, controller: UIViewController) + #endif + + /// Reactive wrapper for `navigationDelegate`. + var uiDelegate: DelegateProxy { + return RxWKUIDelegateProxy.proxy(for: base) + } + + /// Reactive wrapper for `func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Swift.Void)` + var javaScriptAlertPanel: ControlEvent { + typealias __CompletionHandler = @convention(block) () -> Void + let source: Observable = uiDelegate + .methodInvoked(.jsAlert).map { args in + let view = try castOrThrow(WKWebView.self, args[0]) + let message = try castOrThrow(String.self, args[1]) + let frame = try castOrThrow(WKFrameInfo.self, args[2]) + var closureObject: AnyObject? + var mutableArgs = args + mutableArgs.withUnsafeMutableBufferPointer { ptr in + closureObject = ptr[3] as AnyObject + } + let __completionBlockPtr = UnsafeRawPointer(Unmanaged.passUnretained(closureObject as AnyObject).toOpaque()) + let handler = unsafeBitCast(__completionBlockPtr, to: __CompletionHandler.self) + return (view, message, frame, handler) + } + + return ControlEvent(events: source) + } + + /// Reactive wrapper for `func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Swift.Void)` + var javaScriptConfirmPanel: ControlEvent { + typealias __ConfirmHandler = @convention(block) (Bool) -> Void + let source: Observable = uiDelegate + .methodInvoked(.jsConfirm).map { args in + let view = try castOrThrow(WKWebView.self, args[0]) + let message = try castOrThrow(String.self, args[1]) + let frame = try castOrThrow(WKFrameInfo.self, args[2]) + var closureObject: AnyObject? + var mutableArgs = args + mutableArgs.withUnsafeMutableBufferPointer { ptr in + closureObject = ptr[3] as AnyObject + } + let __confirmBlockPtr = UnsafeRawPointer(Unmanaged.passUnretained(closureObject as AnyObject).toOpaque()) + let handler = unsafeBitCast(__confirmBlockPtr, to: __ConfirmHandler.self) + return (view, message, frame, handler) + } + + return ControlEvent(events: source) + } + + #if os(iOS) + /// Reactive wrappper for `func webView(_ webView: WKWebView, commitPreviewingViewController previewingViewController: UIViewController)` + @available(iOS 10.0, *) + var commitPreviewing: ControlEvent { + let source: Observable = uiDelegate + .methodInvoked(.commitPreviewing) + .map { args in + let view = try castOrThrow(WKWebView.self, args[0]) + let controller = try castOrThrow(UIViewController.self, args[1]) + return (view, controller) + } + + return ControlEvent(events: source) + } + #endif +} + +private extension Selector { + static let jsAlert = #selector(WKUIDelegate.webView(_:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:)) + static let jsConfirm = #selector(WKUIDelegate.webView(_:runJavaScriptConfirmPanelWithMessage:initiatedByFrame:completionHandler:)) + + #if os(iOS) + @available(iOS 10.0, *) + static let commitPreviewing = #selector(WKUIDelegate.webView(_:commitPreviewingViewController:)) + #endif +} diff --git a/Sources/RxWebKit/RxWKUIDelegateProxy.swift b/Sources/RxWebKit/RxWKUIDelegateProxy.swift new file mode 100644 index 0000000..598aa11 --- /dev/null +++ b/Sources/RxWebKit/RxWKUIDelegateProxy.swift @@ -0,0 +1,44 @@ +// +// RxWKUIDelegateProxy.swift +// RxWebKit +// +// Created by Bob Obi on 25.10.17. +// Copyright © 2017 RxSwift Community. All rights reserved. +// + +import WebKit +#if !RX_NO_MODULE + import RxCocoa + import RxSwift +#endif + +public typealias RxWKUIDelegate = DelegateProxy + +open class RxWKUIDelegateProxy: RxWKUIDelegate, DelegateProxyType, WKUIDelegate { + /// Type of parent object + /// must be WKWebView! + public private(set) weak var webView: WKWebView? + + /// Init with ParentObject + public init(parentObject: ParentObject) { + webView = parentObject + super.init(parentObject: parentObject, delegateProxy: RxWKUIDelegateProxy.self) + } + + /// Register self to known implementations + public static func registerKnownImplementations() { + register { parent -> RxWKUIDelegateProxy in + RxWKUIDelegateProxy(parentObject: parent) + } + } + + /// Gets the current `WKUIDelegate` on `WKWebView` + open class func currentDelegate(for object: ParentObject) -> WKUIDelegate? { + return object.uiDelegate + } + + /// Set the uiDelegate for `WKWebView` + open class func setCurrentDelegate(_ delegate: WKUIDelegate?, to object: ParentObject) { + object.uiDelegate = delegate + } +} diff --git a/Sources/RxWebKit/RxWKUserContentController.swift b/Sources/RxWebKit/RxWKUserContentController.swift new file mode 100644 index 0000000..bd4d336 --- /dev/null +++ b/Sources/RxWebKit/RxWKUserContentController.swift @@ -0,0 +1,47 @@ +// +// RxWKUserContentController.swift +// RxWebKit +// +// Created by Jesse Hao on 2019/3/30. +// Copyright © 2019 RxSwift Community. All rights reserved. +// + +import WebKit +#if !RX_NO_MODULE + import RxCocoa + import RxSwift +#endif + +private extension WKUserContentController { + class MessageHandler: NSObject, WKScriptMessageHandler { + typealias MessageReceiveHandler = (WKScriptMessage) -> Void + private var messageReceiveHandler: MessageReceiveHandler? + + func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { + messageReceiveHandler?(message) + } + + func onReceive(_ handler: @escaping MessageReceiveHandler) { + messageReceiveHandler = handler + } + } +} + +public extension Reactive where Base: WKUserContentController { + /// Observable sequence of script message. + /// + /// - Parameter name: The name of the message handler + /// - Returns: Observable sequence of script message. + func scriptMessage(forName name: String) -> ControlEvent { + return ControlEvent(events: Observable.create { [weak base] observer in + let handler = WKUserContentController.MessageHandler() + base?.add(handler, name: name) + handler.onReceive { + observer.onNext($0) + } + return Disposables.create { + base?.removeScriptMessageHandler(forName: name) + } + }) + } +} diff --git a/Sources/RxWebKit/WKNavigationDelegateEvents+Rx.swift b/Sources/RxWebKit/WKNavigationDelegateEvents+Rx.swift new file mode 100644 index 0000000..16d41b8 --- /dev/null +++ b/Sources/RxWebKit/WKNavigationDelegateEvents+Rx.swift @@ -0,0 +1,263 @@ +// +// WKNavigationDelegateEvents+Rx.swift +// RxWebKit +// +// Created by Bob Obi on 23.10.17. +// Copyright © 2017 RxSwift Community. All rights reserved. +// + +#if !RX_NO_MODULE + import RxCocoa + import RxSwift +#endif + +import WebKit + +func castOrThrow(_ resultType: T.Type, _ object: Any) throws -> T { + guard let returnValue = object as? T else { + throw RxCocoaError.castingError(object: object, targetType: resultType) + } + return returnValue +} + +public extension Reactive where Base: WKWebView { + /// WKNavigationEvent emits a tuple that contains both + /// WKWebView + WKNavigation + typealias WKNavigationEvent = (webView: WKWebView, navigation: WKNavigation) + + /// WKNavigationFailedEvent emits a tuple that contains both + /// WKWebView + WKNavigation + Swift.Error + typealias WKNavigationFailEvent = (webView: WKWebView, navigation: WKNavigation, error: Error) + + /// ChallengeHandler this is exposed to the user on subscription + typealias ChallengeHandler = (URLSession.AuthChallengeDisposition, URLCredential?) -> Void + /// WKNavigationChallengeEvent emits a tuple event of WKWebView + challenge + ChallengeHandler + typealias WKNavigationChallengeEvent = (webView: WKWebView, challenge: URLAuthenticationChallenge, handler: ChallengeHandler) + + /// DecisionHandler this is the block exposed to the user on subscription + typealias DecisionHandler = (WKNavigationResponsePolicy) -> Void + /// WKNavigationResponsePolicyEvent emits a tuple event of WKWebView + WKNavigationResponse + DecisionHandler + typealias WKNavigationResponsePolicyEvent = (webView: WKWebView, reponse: WKNavigationResponse, handler: DecisionHandler) + /// ActionHandler this is the block exposed to the user on subscription + typealias ActionHandler = (WKNavigationActionPolicy) -> Void + /// WKNavigationActionPolicyEvent emits a tuple event of WKWebView + WKNavigationAction + ActionHandler + typealias WKNavigationActionPolicyEvent = (webView: WKWebView, action: WKNavigationAction, handler: ActionHandler) + + /// Reactive wrapper for `navigationDelegate`. + var delegate: DelegateProxy { + return RxWKNavigationDelegateProxy.proxy(for: base) + } + + /// Reactive wrapper for delegate method `webView(_ webView: WKWebView, didCommit navigation: WKNavigation!)`. + var didCommitNavigation: ControlEvent { + let source: Observable = delegate + .methodInvoked(.didCommitNavigation) + .map { arg in + let view = try castOrThrow(WKWebView.self, arg[0]) + let nav = try castOrThrow(WKNavigation.self, arg[1]) + return (view, nav) + } + return ControlEvent(events: source) + } + + /// Reactive wrapper for delegate method `webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!)`. + var didStartProvisionalNavigation: ControlEvent { + let source: Observable = delegate + .methodInvoked(.didStartProvisionalNavigation) + .map { arg in + let view = try castOrThrow(WKWebView.self, arg[0]) + let nav = try castOrThrow(WKNavigation.self, arg[1]) + return (view, nav) + } + return ControlEvent(events: source) + } + + /// Reactive wrapper for delegate method `webView(_ webView: WKWebView, didFinish navigation: WKNavigation!)` + var didFinishNavigation: ControlEvent { + let source: Observable = delegate + .methodInvoked(.didFinishNavigation) + .map { arg in + let view = try castOrThrow(WKWebView.self, arg[0]) + let nav = try castOrThrow(WKNavigation.self, arg[1]) + return (view, nav) + } + return ControlEvent(events: source) + } + + /// Reactive wrapper for delegate method `webViewWebContentProcessDidTerminate(_ webView: WKWebView)`. + @available(iOS 9.0, *) + var didTerminate: ControlEvent { + let source: Observable = delegate + .methodInvoked(.didTerminate) + .map { try castOrThrow(WKWebView.self, $0[0]) } + return ControlEvent(events: source) + } + + /// Reactive wrapper for delegate method `webView(_ webView: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!)`. + var didReceiveServerRedirectForProvisionalNavigation: ControlEvent { + let source: Observable = delegate + .methodInvoked(.didReceiveServerRedirectForProvisionalNavigation) + .map { arg in + let view = try castOrThrow(WKWebView.self, arg[0]) + let nav = try castOrThrow(WKNavigation.self, arg[1]) + return (view, nav) + } + return ControlEvent(events: source) + } + + /// Reactive wrapper for delegate method `webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error)`. + var didFailNavigation: ControlEvent { + let source: Observable = delegate + .methodInvoked(.didFailNavigation) + .map { arg in + let view = try castOrThrow(WKWebView.self, arg[0]) + let nav = try castOrThrow(WKNavigation.self, arg[1]) + let error = try castOrThrow(Swift.Error.self, arg[2]) + return (view, nav, error) + } + return ControlEvent(events: source) + } + + /// Reactive wrapper for delegate method `webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error)`. + var didFailProvisionalNavigation: ControlEvent { + let source: Observable = delegate + .methodInvoked(.didFailProvisionalNavigation) + .map { arg in + let view = try castOrThrow(WKWebView.self, arg[0]) + let nav = try castOrThrow(WKNavigation.self, arg[1]) + let error = try castOrThrow(Swift.Error.self, arg[2]) + return (view, nav, error) + } + return ControlEvent(events: source) + } + + /// Reactive wrapper for delegate method `webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)` + var didReceiveChallenge: ControlEvent { + /// __ChallengeHandler is same as ChallengeHandler + /// They are interchangeable, __ChallengeHandler is for internal use. + /// ChallengeHandler is exposed to the user on subscription. + /// @convention attribute makes the swift closure compatible with Objc blocks + typealias __ChallengeHandler = @convention(block) (URLSession.AuthChallengeDisposition, URLCredential?) -> Void + /*! @abstract Invoked when the web view needs to respond to an authentication challenge. + @param webView The web view that received the authentication challenge. + @param challenge The authentication challenge. + @param completionHandler The completion handler you must invoke to respond to the challenge. The + disposition argument is one of the constants of the enumerated type + NSURLSessionAuthChallengeDisposition. When disposition is NSURLSessionAuthChallengeUseCredential, + the credential argument is the credential to use, or nil to indicate continuing without a + credential. + @discussion If you do not implement this method, the web view will respond to the authentication challenge with the NSURLSessionAuthChallengeRejectProtectionSpace disposition. + */ + let source: Observable = delegate + .sentMessage(.didReceiveChallenge) + .map { arg in + /// Extracting the WKWebView from the array at index zero + /// which is the first argument of the function signature + let view = try castOrThrow(WKWebView.self, arg[0]) + /// Extracting the URLAuthenticationChallenge from the array at index one + /// which is the second argument of the function signature + let challenge = try castOrThrow(URLAuthenticationChallenge.self, arg[1]) + /// Now you `Can't` transform closure easily because they are excuted + /// in the stack if try it you will get the famous error + /// `Could not cast value of type '__NSStackBlock__' (0x12327d1a8) to` + /// this is because closures are transformed into a system type which is `__NSStackBlock__` + /// the above mentioned type is not exposed to `developer`. So everytime + /// you execute a closure the compiler transforms it into this Object. + /// So you go through the following steps to get a human readable type + /// of the closure signature: + /// 1. closureObject is type of AnyObject to that holds the raw value from + /// the array. + var closureObject: AnyObject? + /// 2. make the array mutable in order to access the `withUnsafeMutableBufferPointer` + /// fuctionalities + var mutableArg = arg + /// 3. Grab the closure at index 3 of the array, but we have to use the C-style + /// approach to access the raw memory underpinning the array and store it in closureObject + /// Now the object stored in the `closureObject` is `Unmanaged` and `some unspecified type` + /// the intelligent swift compiler doesn't know what sort of type it contains. It is Raw. + mutableArg.withUnsafeMutableBufferPointer { ptr in + closureObject = ptr[2] as AnyObject + } + /// 4. instantiate an opaque pointer to referenc the value of the `unspecified type` + let __challengeBlockPtr = UnsafeRawPointer(Unmanaged.passUnretained(closureObject as AnyObject).toOpaque()) + /// 5. Here the magic happen we forcefully tell the compiler that anything + /// found at this memory address that is refrenced should be a type of + /// `__ChallengeHandler`! + let handler = unsafeBitCast(__challengeBlockPtr, to: __ChallengeHandler.self) + return (view, challenge, handler) + } + + return ControlEvent(events: source) + + /** + Reference: + + This is a holy grail part for more information please read the following articles. + 1: http://codejaxy.com/q/332345/ios-objective-c-memory-management-automatic-ref-counting-objective-c-blocks-understand-one-edge-case-of-block-memory-management-in-objc + 2: http://www.galloway.me.uk/2012/10/a-look-inside-blocks-episode-2/ + 3: https://maniacdev.com/2013/11/tutorial-an-in-depth-guide-to-objective-c-block-debugging + 4: get know how [__NSStackBlock__ + UnsafeRawPointer + unsafeBitCast] works under the hood + 5: https://en.wikipedia.org/wiki/Opaque_pointer + 6: https://stackoverflow.com/questions/43662363/cast-objective-c-block-nsstackblock-into-swift-3 + */ + } + + /// Reactive wrapper for `func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Swift.Void)` + var decidePolicyNavigationResponse: ControlEvent { + typealias __DecisionHandler = @convention(block) (WKNavigationResponsePolicy) -> Void + let source: Observable = delegate + .methodInvoked(.decidePolicyNavigationResponse).map { args in + let view = try castOrThrow(WKWebView.self, args[0]) + let response = try castOrThrow(WKNavigationResponse.self, args[1]) + var closureObject: AnyObject? + var mutableArgs = args + mutableArgs.withUnsafeMutableBufferPointer { ptr in + closureObject = ptr[2] as AnyObject + } + let __decisionBlockPtr = UnsafeRawPointer(Unmanaged.passUnretained(closureObject as AnyObject).toOpaque()) + let handler = unsafeBitCast(__decisionBlockPtr, to: __DecisionHandler.self) + return (view, response, handler) + } + + return ControlEvent(events: source) + } + + /// Reactive wrapper for `func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Swift.Void)` + var decidePolicyNavigationAction: ControlEvent { + typealias __ActionHandler = @convention(block) (WKNavigationActionPolicy) -> Void + let source: Observable = delegate + .methodInvoked(.decidePolicyNavigationAction).map { args in + let view = try castOrThrow(WKWebView.self, args[0]) + let action = try castOrThrow(WKNavigationAction.self, args[1]) + var closureObject: AnyObject? + var mutableArgs = args + mutableArgs.withUnsafeMutableBufferPointer { ptr in + closureObject = ptr[2] as AnyObject + } + let __actionBlockPtr = UnsafeRawPointer(Unmanaged.passUnretained(closureObject as AnyObject).toOpaque()) + let handler = unsafeBitCast(__actionBlockPtr, to: __ActionHandler.self) + return (view, action, handler) + } + + return ControlEvent(events: source) + } +} + +extension Selector { + static let didCommitNavigation = #selector(WKNavigationDelegate.webView(_:didCommit:)) + static let didStartProvisionalNavigation = #selector(WKNavigationDelegate.webView(_:didStartProvisionalNavigation:)) + static let didFinishNavigation = #selector(WKNavigationDelegate.webView(_:didFinish:)) + static let didReceiveServerRedirectForProvisionalNavigation = #selector(WKNavigationDelegate.webView(_:didReceiveServerRedirectForProvisionalNavigation:)) + static let didFailNavigation = #selector(WKNavigationDelegate.webView(_:didFail:withError:)) + static let didFailProvisionalNavigation = #selector(WKNavigationDelegate.webView(_:didFailProvisionalNavigation:withError:)) + static let didReceiveChallenge = #selector(WKNavigationDelegate.webView(_:didReceive:completionHandler:)) + @available(iOS 9.0, *) + static let didTerminate = #selector(WKNavigationDelegate.webViewWebContentProcessDidTerminate(_:)) + /// Xcode give error when selectors results into having same signature + /// because of swift style you get for example: + /// Ambiguous use of 'webView(_:decidePolicyFor:decisionHandler:)' + /// please see this link for further understanding + /// https://bugs.swift.org/browse/SR-3062 + static let decidePolicyNavigationResponse = #selector(WKNavigationDelegate.webView(_:decidePolicyFor:decisionHandler:) as ((WKNavigationDelegate) -> (WKWebView, WKNavigationResponse, @escaping (WKNavigationResponsePolicy) -> Void) -> Void)?) + static let decidePolicyNavigationAction = #selector(WKNavigationDelegate.webView(_:decidePolicyFor:decisionHandler:) as ((WKNavigationDelegate) -> (WKWebView, WKNavigationAction, @escaping (WKNavigationActionPolicy) -> Void) -> Void)?) +} diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift new file mode 100644 index 0000000..7575416 --- /dev/null +++ b/Tests/LinuxMain.swift @@ -0,0 +1,8 @@ +import XCTest + +import RxWebKitTests + +var tests = [XCTestCaseEntry]() +tests += RxWebKitTests.__allTests() + +XCTMain(tests) diff --git a/Tests/RxWebKitTests/ForwardsEventsBehavior.swift b/Tests/RxWebKitTests/ForwardsEventsBehavior.swift new file mode 100644 index 0000000..eb79504 --- /dev/null +++ b/Tests/RxWebKitTests/ForwardsEventsBehavior.swift @@ -0,0 +1,65 @@ +import Foundation +import Nimble +import Quick +import RxCocoa +import RxSwift +import RxTest +@testable import RxWebKit +import WebKit + +struct ForwardsEventsBehaviorContext { + let sut: WKWebView + let scheduler: TestScheduler + let selector: Selector + let invoked: () -> Void + + init(_ sut: WKWebView, _ scheduler: TestScheduler, _ selector: Selector, invoked: @escaping (() -> Void)) { + self.sut = sut + self.scheduler = scheduler + self.selector = selector + self.invoked = invoked + } +} + +class ForwardsEventsBehavior: Quick.Behavior { + override class func spec(_ context: @escaping () -> ForwardsEventsBehaviorContext) { + var sut: WKWebView! + var scheduler: TestScheduler! + var selector: Selector! + var invoked: (() -> Void)! + + beforeEach { + let cxt = context() + sut = cxt.sut + scheduler = cxt.scheduler + selector = cxt.selector + invoked = cxt.invoked + } + + afterEach { + sut = nil + scheduler = nil + selector = nil + } + + describe("b") { + it("sentMessage") { + SharingScheduler.mock(scheduler: scheduler) { + let sentMessage = scheduler.record(source: sut.rx.delegate.sentMessage(selector)) + invoked() + scheduler.start() + expect(sentMessage.events.count).to(equal(1)) + } + } + + it("methodInvoke") { + SharingScheduler.mock(scheduler: scheduler) { + let methodInvoked = scheduler.record(source: sut.rx.delegate.methodInvoked(selector)) + invoked() + scheduler.start() + expect(methodInvoked.events.count).to(equal(1)) + } + } + } + } +} diff --git a/Tests/RxWebKitTests/HasEventsBehavior.swift b/Tests/RxWebKitTests/HasEventsBehavior.swift new file mode 100644 index 0000000..79e54d6 --- /dev/null +++ b/Tests/RxWebKitTests/HasEventsBehavior.swift @@ -0,0 +1,64 @@ +import Foundation +import Nimble +import Quick +import RxCocoa +import RxSwift +import RxTest +@testable import RxWebKit +import WebKit + +struct HasEventsBehaviorContext { + let scheduler: TestScheduler + let observable: Observable + let expected: T? + init(_ scheduler: TestScheduler, _ observable: Observable, _ expected: T?) { + self.scheduler = scheduler + self.observable = observable + self.expected = expected + } +} + +class HasEventsBehavior: Quick.Behavior> { + override class func spec(_ context: @escaping () -> HasEventsBehaviorContext) { + var scheduler: TestScheduler! + var observable: Observable! + var expected: T? + + beforeEach { + let cxt = context() + scheduler = cxt.scheduler + observable = cxt.observable + expected = cxt.expected + } + + afterEach { + scheduler = nil + observable = nil + } + + describe("Has Events Behavior") { + it("Actually got the event") { + SharingScheduler.mock(scheduler: scheduler) { + let recorded = scheduler.record(source: observable) + scheduler.start() + expect(recorded.events.count).to(equal(1)) + expect(recorded.events[0].value.element).to(equal(expected)) + } + } + } + } +} + +extension TestScheduler { + /// Builds testable observer for s specific observable sequence, binds it's results and sets up disposal. + /// parameter source: Observable sequence to observe. + /// returns: Observer that records all events for observable sequence. + func record(source: O) -> TestableObserver { + let observer = createObserver(O.Element.self) + let disposable = source.asObservable().bind(to: observer) + scheduleAt(100_000) { + disposable.dispose() + } + return observer + } +} diff --git a/Tests/RxWebKitTests/RxWebKitTests.swift b/Tests/RxWebKitTests/RxWebKitTests.swift new file mode 100644 index 0000000..d367d34 --- /dev/null +++ b/Tests/RxWebKitTests/RxWebKitTests.swift @@ -0,0 +1,153 @@ +import Nimble +import Quick +import RxSwift +import RxTest +@testable import RxWebKit +import WebKit + +class RxWebKitTests: QuickSpec { + override func spec() { + var scheduler: TestScheduler! + var sut: WKWebView! + let html = """ + + + + RxWebKit + + + +

This is a Heading

+

This is a paragraph.

+ + + + """ + + beforeEach { + scheduler = TestScheduler(initialClock: 0) + sut = WKWebView(frame: CGRect.zero) + } + + afterEach { + scheduler = nil + sut = nil + } + + itBehavesLike(HasEventsBehavior.self) { + HasEventsBehaviorContext(scheduler, sut.rx.title, "") + } + + itBehavesLike(HasEventsBehavior.self) { + sut.loadHTMLString(html, baseURL: Bundle.main.resourceURL) + return HasEventsBehaviorContext(scheduler, sut.rx.loading, true) + } + + itBehavesLike(HasEventsBehavior.self) { + HasEventsBehaviorContext(scheduler, sut.rx.loading, false) + } + + itBehavesLike(HasEventsBehavior.self) { + HasEventsBehaviorContext(scheduler, sut.rx.estimatedProgress, 0.0) + } + + itBehavesLike(HasEventsBehavior.self) { + sut.loadHTMLString(html, baseURL: Bundle.main.resourceURL) + return HasEventsBehaviorContext(scheduler, sut.rx.estimatedProgress, 0.1) + } + + itBehavesLike(HasEventsBehavior.self) { + HasEventsBehaviorContext(scheduler, sut.rx.canGoBack, false) + } + + itBehavesLike(HasEventsBehavior.self) { + HasEventsBehaviorContext(scheduler, sut.rx.canGoForward, false) + } + + itBehavesLike(ForwardsEventsBehavior.self) { + ForwardsEventsBehaviorContext(sut, scheduler, .didTerminate) { + sut.navigationDelegate?.webViewWebContentProcessDidTerminate?(sut) + } + } + + itBehavesLike(ForwardsEventsBehavior.self) { + ForwardsEventsBehaviorContext(sut, scheduler, .didCommitNavigation) { + let navigation = sut.loadHTMLString(html, baseURL: Bundle.main.resourceURL) + sut.navigationDelegate?.webView?(sut, didCommit: navigation) + } + } + + itBehavesLike(ForwardsEventsBehavior.self) { + ForwardsEventsBehaviorContext(sut, scheduler, .didFinishNavigation) { + let navigation = sut.loadHTMLString(html, baseURL: Bundle.main.resourceURL) + sut.navigationDelegate?.webView?(sut, didFinish: navigation) + } + } + + itBehavesLike(ForwardsEventsBehavior.self) { + ForwardsEventsBehaviorContext(sut, scheduler, .didReceiveServerRedirectForProvisionalNavigation) { + let navigation = sut.loadHTMLString(html, baseURL: Bundle.main.resourceURL) + sut.navigationDelegate?.webView?(sut, didReceiveServerRedirectForProvisionalNavigation: navigation) + } + } + + itBehavesLike(ForwardsEventsBehavior.self) { + ForwardsEventsBehaviorContext(sut, scheduler, .didFailNavigation) { + let navigation = sut.loadHTMLString(html, baseURL: Bundle.main.resourceURL) + sut.navigationDelegate?.webView?(sut, didFail: navigation, withError: TestError.didFailNavigation) + } + } + + itBehavesLike(ForwardsEventsBehavior.self) { + ForwardsEventsBehaviorContext(sut, scheduler, .didFailProvisionalNavigation) { + let navigation = sut.loadHTMLString(html, baseURL: Bundle.main.resourceURL) + sut.navigationDelegate?.webView?(sut, didFailProvisionalNavigation: navigation, withError: TestError.didFailProvisionalNavigation) + } + } + + itBehavesLike(ForwardsEventsBehavior.self) { + ForwardsEventsBehaviorContext(sut, scheduler, .didReceiveChallenge) { + let protectionSpace = URLProtectionSpace(host: "fake", port: 8443, protocol: nil, realm: nil, authenticationMethod: nil) + let credential = URLCredential(user: "bad-user", password: "bad-password", persistence: URLCredential.Persistence.forSession) + let sender = MockURLAuthenticationChallengeSender() + + let challenge = URLAuthenticationChallenge(protectionSpace: protectionSpace, proposedCredential: credential, previousFailureCount: 0, failureResponse: nil, error: TestError.didReceiveChallenge, sender: sender) + + sut.navigationDelegate?.webView?(sut, didReceive: challenge, completionHandler: { _, _ in }) + } + } + + itBehavesLike(ForwardsEventsBehavior.self) { + ForwardsEventsBehaviorContext(sut, scheduler, .decidePolicyNavigationAction) { + let delegate: WKNavigationDelegate? = sut.navigationDelegate + delegate?.webView?(sut, decidePolicyFor: WKNavigationAction(), decisionHandler: { _ in }) + } + } + + itBehavesLike(ForwardsEventsBehavior.self) { + ForwardsEventsBehaviorContext(sut, scheduler, .decidePolicyNavigationResponse) { + let delegate: WKNavigationDelegate? = sut.navigationDelegate + delegate?.webView?(sut, decidePolicyFor: WKNavigationResponse(), decisionHandler: { _ in }) + } + } + } +} + +enum TestError: Error { + case didFailNavigation + case didFailProvisionalNavigation + case didReceiveChallenge +} + +@objc class MockURLAuthenticationChallengeSender: NSObject, URLAuthenticationChallengeSender { + override func `self`() -> Self { + return self + } + + override init() {} + func use(_ credential: URLCredential, for challenge: URLAuthenticationChallenge) {} + + func continueWithoutCredential(for challenge: URLAuthenticationChallenge) {} + + func cancel(_ challenge: URLAuthenticationChallenge) {} +} diff --git a/Tests/RxWebKitTests/XCTestManifests.swift b/Tests/RxWebKitTests/XCTestManifests.swift new file mode 100644 index 0000000..af401c7 --- /dev/null +++ b/Tests/RxWebKitTests/XCTestManifests.swift @@ -0,0 +1,42 @@ +#if !canImport(ObjectiveC) + import XCTest + + extension RxWebKitTests { + // DO NOT MODIFY: This is autogenerated, use: + // `swift test --generate-linuxmain` + // to regenerate. + static let __allTests__RxWebKitTests = [ + ("HasEventsBehavior_Optional_String____Has_Events_Behavior__Actually_got_the_event", HasEventsBehavior_Optional_String____Has_Events_Behavior__Actually_got_the_event), + ("HasEventsBehavior_Bool___Has_Events_Behavior__Actually_got_the_event", HasEventsBehavior_Bool___Has_Events_Behavior__Actually_got_the_event), + ("HasEventsBehavior_Bool___Has_Events_Behavior__Actually_got_the_event_2", HasEventsBehavior_Bool___Has_Events_Behavior__Actually_got_the_event_2), + ("HasEventsBehavior_Double___Has_Events_Behavior__Actually_got_the_event", HasEventsBehavior_Double___Has_Events_Behavior__Actually_got_the_event), + ("HasEventsBehavior_Double___Has_Events_Behavior__Actually_got_the_event_2", HasEventsBehavior_Double___Has_Events_Behavior__Actually_got_the_event_2), + ("HasEventsBehavior_Bool___Has_Events_Behavior__Actually_got_the_event_3", HasEventsBehavior_Bool___Has_Events_Behavior__Actually_got_the_event_3), + ("HasEventsBehavior_Bool___Has_Events_Behavior__Actually_got_the_event_4", HasEventsBehavior_Bool___Has_Events_Behavior__Actually_got_the_event_4), + ("ForwardsEventsBehavior__b__sentMessage", ForwardsEventsBehavior__b__sentMessage), + ("ForwardsEventsBehavior__b__methodInvoke", ForwardsEventsBehavior__b__methodInvoke), + ("ForwardsEventsBehavior__b__sentMessage_2", ForwardsEventsBehavior__b__sentMessage_2), + ("ForwardsEventsBehavior__b__methodInvoke_2", ForwardsEventsBehavior__b__methodInvoke_2), + ("ForwardsEventsBehavior__b__sentMessage_3", ForwardsEventsBehavior__b__sentMessage_3), + ("ForwardsEventsBehavior__b__methodInvoke_3", ForwardsEventsBehavior__b__methodInvoke_3), + ("ForwardsEventsBehavior__b__sentMessage_4", ForwardsEventsBehavior__b__sentMessage_4), + ("ForwardsEventsBehavior__b__methodInvoke_4", ForwardsEventsBehavior__b__methodInvoke_4), + ("ForwardsEventsBehavior__b__sentMessage_5", ForwardsEventsBehavior__b__sentMessage_5), + ("ForwardsEventsBehavior__b__methodInvoke_5", ForwardsEventsBehavior__b__methodInvoke_5), + ("ForwardsEventsBehavior__b__sentMessage_6", ForwardsEventsBehavior__b__sentMessage_6), + ("ForwardsEventsBehavior__b__methodInvoke_6", ForwardsEventsBehavior__b__methodInvoke_6), + ("ForwardsEventsBehavior__b__sentMessage_7", ForwardsEventsBehavior__b__sentMessage_7), + ("ForwardsEventsBehavior__b__methodInvoke_7", ForwardsEventsBehavior__b__methodInvoke_7), + ("ForwardsEventsBehavior__b__sentMessage_8", ForwardsEventsBehavior__b__sentMessage_8), + ("ForwardsEventsBehavior__b__methodInvoke_8", ForwardsEventsBehavior__b__methodInvoke_8), + ("ForwardsEventsBehavior__b__sentMessage_9", ForwardsEventsBehavior__b__sentMessage_9), + ("ForwardsEventsBehavior__b__methodInvoke_9", ForwardsEventsBehavior__b__methodInvoke_9) + ] + } + + public func __allTests() -> [XCTestCaseEntry] { + return [ + testCase(RxWebKitTests.__allTests__RxWebKitTests) + ] + } +#endif diff --git a/cleanup.sh b/cleanup.sh new file mode 100755 index 0000000..02fe948 --- /dev/null +++ b/cleanup.sh @@ -0,0 +1,23 @@ +if which swiftformat >/dev/null; then +`which swiftformat` "Sources" --config .swiftformat --quiet +`which swiftformat` "Tests" --config .swiftformat --quiet +`which swiftformat` "Examples/RxWebKitDemo-iOS" --config .swiftformat --quiet +`which swiftformat` "Package.swift" --config .swiftformat --quiet +else +echo "error: swiftformat not installed, do `sh setup.sh` to install swiftformat." +exit 1 +fi + +if which swiftlint >/dev/null; then +`which swiftlint` autocorrect --quiet +else +echo "error: SwiftLint not installed, do `sh setup.sh` to install SwiftLint." +exit 1 +fi + +if which xcodegen >/dev/null; then +`which xcodegen` --spec project-carthage.yml +else +echo "error: XcodeGen not installed, do `sh setup.sh` to install XcodeGen." +exit 1 +fi \ No newline at end of file diff --git a/pods.sh b/pods.sh new file mode 100644 index 0000000..c3f158b --- /dev/null +++ b/pods.sh @@ -0,0 +1,6 @@ +#!/bin/bash +set -eo pipefail +export RELEASE_VERSION="$(git describe --abbrev=0 | tr -d '\n')" +RELEASE_VERSION=${RELEASE_VERSION:1} +pod lib lint --allow-warnings +pod trunk push --allow-warnings \ No newline at end of file diff --git a/project-carthage.yml b/project-carthage.yml new file mode 100644 index 0000000..1ea7fea --- /dev/null +++ b/project-carthage.yml @@ -0,0 +1,111 @@ +name: RxWebKit +options: + minimumXcodeGenVersion: "2.15.1" + developmentLanguage: en + usesTabs: false + indentWidth: 2 + tabWidth: 2 + xcodeVersion: "1230" + deploymentTarget: + iOS: "9.0" + macOS: "10.13" + carthageExecutablePath: "`which carthage`" + defaultConfig: "Release" +configs: + Debug: debug + Release: release +attributes: + ORGANIZATIONNAME: RxSwiftCommunity +schemes: + RxWebKit iOS: + scheme: {} + build: + parallelizeBuild: true + buildImplicitDependencies: true + targets: + RxWebKit iOS: all + RxWebKitTests iOS: [test] + run: + config: Debug + test: + config: Debug + gatherCoverageData: true + targets: + - RxWebKitTests iOS + profile: + config: Release + analyze: + config: Debug + archive: + config: Release + revealArchiveInOrganizer: true + RxWebKit macOS: + scheme: {} + build: + parallelizeBuild: true + buildImplicitDependencies: true + targets: + RxWebKit macOS: all + RxWebKitTests macOS: [test] + run: + config: Debug + test: + config: Debug + gatherCoverageData: true + targets: + - RxWebKitTests macOS + profile: + config: Release + analyze: + config: Debug + archive: + config: Release + revealArchiveInOrganizer: true +targets: + RxWebKit iOS: + settings: + PRODUCT_NAME: RxWebKit + PRODUCT_BUNDLE_IDENTIFIER: RxSwiftCommunity.RxWebKit.RxWebKit-iOS + BUILD_LIBRARY_FOR_DISTRIBUTION: YES + SKIP_INSTALL: NO + SUPPORTS_MACCATALYST: NO + platform: iOS + type: framework + sources: + - Sources/RxWebKit + dependencies: + - carthage: RxCocoa + - carthage: RxSwift + RxWebKit macOS: + settings: + PRODUCT_NAME: RxWebKit + PRODUCT_BUNDLE_IDENTIFIER: RxSwiftCommunity.RxWebKit.RxWebKit-macOS + BUILD_LIBRARY_FOR_DISTRIBUTION: YES + SKIP_INSTALL: NO + platform: macOS + type: framework + sources: + - Sources/RxWebKit + dependencies: + - carthage: RxCocoa + - carthage: RxSwift + RxWebKitTests iOS: + platform: iOS + type: bundle.unit-test + sources: + - path: Tests/RxWebKitTests + dependencies: + - target: RxWebKit iOS + - carthage: Nimble + - carthage: Quick + RxWebKitTests macOS: + platform: macOS + type: bundle.unit-test + settings: + CODE_SIGN_IDENTITY: "" + sources: + - path: Tests/RxWebKitTests + dependencies: + - target: RxWebKit macOS + - carthage: Nimble + - carthage: Quick diff --git a/project-spm.yml b/project-spm.yml new file mode 100644 index 0000000..8a68d5c --- /dev/null +++ b/project-spm.yml @@ -0,0 +1,93 @@ +name: RxWebKit-SPM +options: + minimumXcodeGenVersion: "2.15.1" + developmentLanguage: en + usesTabs: false + indentWidth: 2 + tabWidth: 2 + xcodeVersion: "1230" + deploymentTarget: + iOS: "9.0" + macOS: "10.13" + carthageExecutablePath: "`which carthage`" + defaultConfig: "Release" +configs: + Debug: debug + Release: release +attributes: + ORGANIZATIONNAME: RxSwiftCommunity +schemes: + RxWebKit iOS: + scheme: {} + build: + parallelizeBuild: true + buildImplicitDependencies: true + targets: + RxWebKit iOS: all + run: + config: Debug + test: + config: Debug + gatherCoverageData: true + profile: + config: Release + analyze: + config: Debug + archive: + config: Release + revealArchiveInOrganizer: true + RxWebKit macOS: + scheme: {} + build: + parallelizeBuild: true + buildImplicitDependencies: true + targets: + RxWebKit macOS: all + run: + config: Debug + test: + config: Debug + gatherCoverageData: true + profile: + config: Release + analyze: + config: Debug + archive: + config: Release + revealArchiveInOrganizer: true +packages: + RxSwift: + url: https://github.com/ReactiveX/RxSwift.git + from: 6.0.0 +targets: + RxWebKit iOS: + settings: + PRODUCT_NAME: RxWebKit + PRODUCT_BUNDLE_IDENTIFIER: RxSwiftCommunity.RxWebKit.RxWebKit-iOS + BUILD_LIBRARY_FOR_DISTRIBUTION: YES + SKIP_INSTALL: NO + SUPPORTS_MACCATALYST: NO + platform: iOS + type: framework + sources: + - Sources/RxWebKit + dependencies: + - package: RxSwift + product: RxSwift + - package: RxSwift + product: RxCocoa + RxWebKit macOS: + settings: + PRODUCT_NAME: RxWebKit + PRODUCT_BUNDLE_IDENTIFIER: RxSwiftCommunity.RxWebKit.RxWebKit-macOS + BUILD_LIBRARY_FOR_DISTRIBUTION: YES + SKIP_INSTALL: NO + platform: macOS + type: framework + sources: + - Sources/RxWebKit + dependencies: + - package: RxSwift + product: RxSwift + - package: RxSwift + product: RxCocoa \ No newline at end of file diff --git a/scripts/bump-version.sh b/scripts/bump-version.sh new file mode 100644 index 0000000..e322781 --- /dev/null +++ b/scripts/bump-version.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +set -euo pipefail +git config --global user.name "RxWebKit Maintainers" +git config --global user.email "RxWebKit@rxswift.org" +npx standard-version +echo "RELEASE_VERSION=$(git describe --abbrev=0 | tr -d '\n')" >> $GITHUB_ENV +export VERSION="$(git describe --abbrev=0 | tr -d '\n')" +VERSION=${VERSION:1} +echo $VERSION +npx podspec-bump -w -i "$VERSION" +git add -A +git commit --amend --no-edit \ No newline at end of file diff --git a/scripts/carthage.sh b/scripts/carthage.sh new file mode 100755 index 0000000..e21348f --- /dev/null +++ b/scripts/carthage.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +# carthage.sh +# Usage example: ./carthage.sh build --platform iOS + +set -euo pipefail + +xcconfig=$(mktemp /tmp/static.xcconfig.XXXXXX) +trap 'rm -f "$xcconfig"' INT TERM HUP EXIT + +# For Xcode 12 make sure EXCLUDED_ARCHS is set to arm architectures otherwise +# the build will fail on lipo due to duplicate architectures. + +CURRENT_XCODE_VERSION=$(xcodebuild -version | grep "Build version" | cut -d' ' -f3) +echo "EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_simulator__NATIVE_ARCH_64_BIT_x86_64__XCODE_1200__BUILD_$CURRENT_XCODE_VERSION = arm64 arm64e armv7 armv7s armv6 armv8" >> $xcconfig + +echo 'EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_simulator__NATIVE_ARCH_64_BIT_x86_64__XCODE_1200 = $(EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_simulator__NATIVE_ARCH_64_BIT_x86_64__XCODE_1200__BUILD_$(XCODE_PRODUCT_BUILD_VERSION))' >> $xcconfig +echo 'EXCLUDED_ARCHS = $(inherited) $(EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_$(EFFECTIVE_PLATFORM_SUFFIX)__NATIVE_ARCH_64_BIT_$(NATIVE_ARCH_64_BIT)__XCODE_$(XCODE_VERSION_MAJOR))' >> $xcconfig + +export XCODE_XCCONFIG_FILE="$xcconfig" +carthage build "$@" \ No newline at end of file diff --git a/scripts/xcframeworks.sh b/scripts/xcframeworks.sh new file mode 100644 index 0000000..2ebf0c8 --- /dev/null +++ b/scripts/xcframeworks.sh @@ -0,0 +1,25 @@ +set -euo pipefail +rm -rf RxWebKit-SPM.xcodeproj +rm -rf xcarchives/* +rm -rf RxWebKit.xcframework.zip +rm -rf RxWebKit.xcframework + +xcodegen --spec project-spm.yml + +xcodebuild archive -quiet -project RxWebKit-SPM.xcodeproj -configuration Release -scheme "RxWebKit iOS" -destination "generic/platform=iOS" -archivePath "xcarchives/RxWebKit-iOS" SKIP_INSTALL=NO SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES OTHER_CFLAGS="-fembed-bitcode" BITCODE_GENERATION_MODE="bitcode" ENABLE_BITCODE=YES | xcpretty --color --simple +xcodebuild archive -quiet -project RxWebKit-SPM.xcodeproj -configuration Release -scheme "RxWebKit iOS" -destination "generic/platform=iOS Simulator" -archivePath "xcarchives/RxWebKit-iOS-Simulator" SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES OTHER_CFLAGS="-fembed-bitcode" BITCODE_GENERATION_MODE="bitcode" ENABLE_BITCODE=YES | xcpretty --color --simple +xcodebuild archive -quiet -project RxWebKit-SPM.xcodeproj -configuration Release -scheme "RxWebKit macOS" -destination "generic/platform=macOS" -archivePath "xcarchives/RxWebKit-macOS" SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES OTHER_CFLAGS="-fembed-bitcode" BITCODE_GENERATION_MODE="bitcode" ENABLE_BITCODE=YES | xcpretty --color --simple + +xcodebuild -create-xcframework \ +-framework "xcarchives/RxWebKit-iOS-Simulator.xcarchive/Products/Library/Frameworks/RxWebKit.framework" \ +-debug-symbols ""$(pwd)"/xcarchives/RxWebKit-iOS-Simulator.xcarchive/dSYMs/RxWebKit.framework.dSYM" \ +-framework "xcarchives/RxWebKit-iOS.xcarchive/Products/Library/Frameworks/RxWebKit.framework" \ +-debug-symbols ""$(pwd)"/xcarchives/RxWebKit-iOS.xcarchive/dSYMs/RxWebKit.framework.dSYM" \ +-framework "xcarchives/RxWebKit-macOS.xcarchive/Products/Library/Frameworks/RxWebKit.framework" \ +-debug-symbols ""$(pwd)"/xcarchives/RxWebKit-macOS.xcarchive/dSYMs/RxWebKit.framework.dSYM" \ +-output "RxWebKit.xcframework" + +zip -r RxWebKit.xcframework.zip RxWebKit.xcframework +rm -rf xcarchives/* +rm -rf RxWebKit.xcframework +rm -rf RxWebKit-SPM.xcodeproj \ No newline at end of file