diff --git a/Example/Podfile.lock b/Example/Podfile.lock index bc273fd..38cfc5c 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -1,5 +1,5 @@ PODS: - - TrustlySDK (3.1.1) + - TrustlySDK (3.2.1) DEPENDENCIES: - TrustlySDK (from `../`) @@ -9,8 +9,8 @@ EXTERNAL SOURCES: :path: "../" SPEC CHECKSUMS: - TrustlySDK: 8bf9044a576043775ac7032ac2a569eb7e14a746 + TrustlySDK: 8426a3ec86b7ea314fe593401912fab9d7a68db1 PODFILE CHECKSUM: 2d88e8d6e29e33aaa64b36a8d0e73ac21b25b6ba -COCOAPODS: 1.12.1 +COCOAPODS: 1.15.2 diff --git a/Example/Tests/ValidationHelperTests.swift b/Example/Tests/ValidationHelperTests.swift new file mode 100644 index 0000000..f4739bd --- /dev/null +++ b/Example/Tests/ValidationHelperTests.swift @@ -0,0 +1,69 @@ +// +// ValidationHelperTests.swift +// TrustlySDK_Tests +// +// Created by Marcos Rivereto on 05/07/24. +// Copyright © 2024 CocoaPods. All rights reserved. +// + +import XCTest +@testable import TrustlySDK + +final class ValidationHelperTests: XCTestCase { + + override func setUpWithError() throws { + } + + override func tearDownWithError() throws { + } + + func testRecognize400Error() throws { + + let content = "Error 404 not found" + + let expectdResult = true + + let matches = ValidationHelper.findMatchesForErrorCode(content: content) + + let isErrorCodePage = ValidationHelper.isErrorCodePage(matches: matches, content: content) + + XCTAssertEqual(expectdResult, isErrorCodePage) + } + + func testRecognize500Error() throws { + + let content = "Internal error server 500" + + let expectdResult = true + + let matches = ValidationHelper.findMatchesForErrorCode(content: content) + + let isErrorCodePage = ValidationHelper.isErrorCodePage(matches: matches, content: content) + + XCTAssertEqual(expectdResult, isErrorCodePage) + } + + func testRecognizeIsNotErrorPage() throws { + + let content = "Regular content" + + let expectdResult = false + + let matches = ValidationHelper.findMatchesForErrorCode(content: content) + + let isErrorCodePage = ValidationHelper.isErrorCodePage(matches: matches, content: content) + + XCTAssertEqual(expectdResult, isErrorCodePage) + } + + func testMatchErrorCodes() throws { + + let content = "Internal error server 500" + + let expectdResult = 1 + + let matches = ValidationHelper.findMatchesForErrorCode(content: content) + + XCTAssertEqual(expectdResult, matches.count) + } +} diff --git a/Example/TrustlySDK.xcodeproj/project.pbxproj b/Example/TrustlySDK.xcodeproj/project.pbxproj index fd5f6f8..edd63bb 100644 --- a/Example/TrustlySDK.xcodeproj/project.pbxproj +++ b/Example/TrustlySDK.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ 1587AB912A2FE043006F6FC3 /* SessionManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1587AB902A2FE043006F6FC3 /* SessionManagerTests.swift */; }; 15987B0929DEF79D00D7A395 /* TrustlyLightBoxViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15987B0829DEF79D00D7A395 /* TrustlyLightBoxViewController.swift */; }; + 15BEC9B42C383FB900050FB9 /* ValidationHelperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15BEC9B32C383FB900050FB9 /* ValidationHelperTests.swift */; }; 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; }; 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; }; 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; }; @@ -31,6 +32,7 @@ /* Begin PBXFileReference section */ 1587AB902A2FE043006F6FC3 /* SessionManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionManagerTests.swift; sourceTree = ""; }; 15987B0829DEF79D00D7A395 /* TrustlyLightBoxViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrustlyLightBoxViewController.swift; sourceTree = ""; }; + 15BEC9B32C383FB900050FB9 /* ValidationHelperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValidationHelperTests.swift; sourceTree = ""; }; 2416E32056EECA07B4C86E1B /* TrustlySDK.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = TrustlySDK.podspec; path = ../TrustlySDK.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 24C6055BF6640A73038BF66E /* Pods_TrustlySDK_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_TrustlySDK_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 38845E178FF73A019452105E /* Pods-TrustlySDK_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TrustlySDK_Tests.debug.xcconfig"; path = "Target Support Files/Pods-TrustlySDK_Tests/Pods-TrustlySDK_Tests.debug.xcconfig"; sourceTree = ""; }; @@ -71,6 +73,14 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 15BEC9B22C383F3600050FB9 /* Helpers */ = { + isa = PBXGroup; + children = ( + 15BEC9B32C383FB900050FB9 /* ValidationHelperTests.swift */, + ); + name = Helpers; + sourceTree = ""; + }; 607FACC71AFB9204008FA782 = { isa = PBXGroup; children = ( @@ -118,6 +128,7 @@ 607FACE81AFB9204008FA782 /* Tests */ = { isa = PBXGroup; children = ( + 15BEC9B22C383F3600050FB9 /* Helpers */, 1587AB902A2FE043006F6FC3 /* SessionManagerTests.swift */, 607FACE91AFB9204008FA782 /* Supporting Files */, ); @@ -346,6 +357,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 15BEC9B42C383FB900050FB9 /* ValidationHelperTests.swift in Sources */, 1587AB912A2FE043006F6FC3 /* SessionManagerTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -536,6 +548,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = 38845E178FF73A019452105E /* Pods-TrustlySDK_Tests.debug.xcconfig */; buildSettings = { + DEVELOPMENT_TEAM = 935WTYE9VM; FRAMEWORK_SEARCH_PATHS = ( "$(PLATFORM_DIR)/Developer/Library/Frameworks", "$(inherited)", @@ -545,13 +558,13 @@ "$(inherited)", ); INFOPLIST_FILE = Tests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 17.4; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.TrustlySDK-Example"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 5.0; @@ -563,18 +576,19 @@ isa = XCBuildConfiguration; baseConfigurationReference = 4374DB88B53812152BC15F73 /* Pods-TrustlySDK_Tests.release.xcconfig */; buildSettings = { + DEVELOPMENT_TEAM = 935WTYE9VM; FRAMEWORK_SEARCH_PATHS = ( "$(PLATFORM_DIR)/Developer/Library/Frameworks", "$(inherited)", ); INFOPLIST_FILE = Tests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 17.4; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.TrustlySDK-Example"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 5.0; diff --git a/Example/TrustlySDK/AppDelegate.swift b/Example/TrustlySDK/AppDelegate.swift index 857d741..71f3e5c 100644 --- a/Example/TrustlySDK/AppDelegate.swift +++ b/Example/TrustlySDK/AppDelegate.swift @@ -7,6 +7,7 @@ // import UIKit +import TrustlySDK @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { @@ -16,6 +17,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. + return true } @@ -40,6 +42,21 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func applicationWillTerminate(_ application: UIApplication) { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } + + func application(_ application: UIApplication, + open url: URL, + options: [UIApplication.OpenURLOptionsKey : Any] = [:] ) -> Bool { + + + // Determine who sent the URL. + if url.absoluteString == "demoapp://" { + NotificationCenter.default.post(name: Notification.Name(TrustlyView.trustlyCloseWebview), object: nil) + + return true + } + + return false + } } diff --git a/Example/TrustlySDK/Info.plist b/Example/TrustlySDK/Info.plist index eb18faa..6434269 100644 --- a/Example/TrustlySDK/Info.plist +++ b/Example/TrustlySDK/Info.plist @@ -18,6 +18,17 @@ 1.0 CFBundleSignature ???? + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLSchemes + + demoapp + + + CFBundleVersion 1 LSRequiresIPhoneOS diff --git a/Example/TrustlySDK/TrustlyLightBoxViewController.swift b/Example/TrustlySDK/TrustlyLightBoxViewController.swift index 73dae03..012618a 100644 --- a/Example/TrustlySDK/TrustlyLightBoxViewController.swift +++ b/Example/TrustlySDK/TrustlyLightBoxViewController.swift @@ -30,7 +30,7 @@ class TrustlyLightBoxViewController: UIViewController { }, onCancel: {(payWithMyBank, returnParameters)->Void in let response = returnParameters as! [String:String] - self.delegate?.onCancelWithTransactionId(transactionId: response["transactionId"]!, controller: self) + self.delegate?.onCancelWithTransactionId(transactionId: response["transactionId"] ?? "No Transaction ID", controller: self) }) } else { diff --git a/README.md b/README.md index 95c9d80..adc0c7a 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,7 @@ ___ | VERSION | DESCRIPTION | BRANCH | | :-------: | :----------- | :----------- | +3.2.2 | Fix a bug when we try to check if the sdk is loading a error page(400 and 500) | *main* 3.2.1 | Prepare the sdk to support Buck build system | *main* 3.2.0 | Add PrivacyInfo.xcprivacy | *main* 3.1.1 | Fix minor bug when use the SDK in local environment | *main* diff --git a/Sources/TrustlySDK/Helpers/ValidationsHelper.swift b/Sources/TrustlySDK/Helpers/ValidationsHelper.swift new file mode 100644 index 0000000..c5f2ed1 --- /dev/null +++ b/Sources/TrustlySDK/Helpers/ValidationsHelper.swift @@ -0,0 +1,38 @@ +// +// ValidationsHelper.swift +// TrustlySDK +// +// Created by Marcos Rivereto on 05/07/24. +// + +import Foundation +import WebKit + + +class ValidationHelper { + + static let HTTP_400_STATUS_CODE = 4 + static let HTTP_500_STATUS_CODE = 5 + + static func isErrorCodePage(matches: [NSTextCheckingResult], content: String) -> Bool { + for match in matches { + + let value = (Int(content[Range(match.range,in: content)!]) ?? 0) / 100 + + if value == HTTP_400_STATUS_CODE || value == HTTP_500_STATUS_CODE { + return true + } + } + + return false + } + + static func findMatchesForErrorCode(content: String) -> [NSTextCheckingResult] { + guard let regex = try? NSRegularExpression(pattern: "[0-9]+", options:NSRegularExpression.Options.caseInsensitive) else { return []} + + let matches = regex.matches(in: content, options:[], range: NSMakeRange(0, content.count)) + + return matches + } + +} diff --git a/Sources/TrustlySDK/TrustlyView.swift b/Sources/TrustlySDK/TrustlyView.swift index acc6cc7..206f7bc 100644 --- a/Sources/TrustlySDK/TrustlyView.swift +++ b/Sources/TrustlySDK/TrustlyView.swift @@ -35,7 +35,7 @@ let NavBarHeight:Int = 26 let NavBarIconWidth:Int = 10 let NavBarIconHeight:Int = 10 -let build = "3.2.1" +let build = "3.2.2" let CloseIconBase64:String! = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAACXBIWXMAACxLAAAsSwGlPZapAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAG1SURBVHgB3diLTcNADAZgpxOUBVA6CYzQDdoRGMETABMAG8AEVUdggmaDdoMYn5KTQlSau8RnW/ySVUWyo/sa9XEH8E9SDS+IaM0vO647rmNVVUdwFF5feAlr3HLVXN+8xq9x047rQr/zAk4SEFwbrma0xhNXHZvqK4iYdzDODUTMITbu6XbMMAmIkHbV968n7re3wFD3mdhwhXe8Thl4pLSoYRKfRMxpOPhBaSmOyUS0XLvxDcwxmYgQ/OtGZhgxhCVGHGGBKYbQxBRHaGDUECUx6ogSGDOEJMYcIYFxg1iKcYWYi6Fuz9MkziBoJgPz6RYxA+MXIYxB8JCFGARPmYlB8JhMDIJQViAY6s6XHjJG7sFTKP8Xe5g38JCFCB8YIYQtRhhhg5mBQEr/NtPB0IK/4m4wtHA/wdeVOYaENkWmGBLe2ZlgqND2VBVDhffYKhhSOigoiiHl044iGDI6shHFkPG5kwjGGiGG8YBYjKHuaTSJgwgKycQ8x6Ft4gCCYjIw5ziACc0IBknEtLF56okgGCYB0w6bT9carBExExgcNtZch37xoc5cT+AoPeZ1ALhExA8NsASbTxPzlwAAAABJRU5ErkJggg==" @@ -115,6 +115,11 @@ public class TrustlyView : UIView, TrustlyProtocol, WKNavigationDelegate, WKScri mainWebView.scrollView.bounces = false mainWebView.backgroundColor = UIColor.clear mainWebView.isOpaque = false + if #available(iOS 16.4, *) { + mainWebView.isInspectable = true + } else { + // Fallback on earlier versions + } addSubview(mainWebView) } @@ -367,23 +372,28 @@ public class TrustlyView : UIView, TrustlyProtocol, WKNavigationDelegate, WKScri if webView.tag == WidgetView { self.notifyEvent("widget","load") } - - let regex = try? NSRegularExpression(pattern: "[0-9]+", options:NSRegularExpression.Options.caseInsensitive) - - let theTitle:String! = webView.title - let matches = regex!.matches(in: theTitle, options:[], range: NSMakeRange(0, theTitle.count)) - - for match in matches { - let value = Int(theTitle[Range(match.range,in: theTitle)!])! / 100 - if value == 4 || value == 5 { - if (self.cancelHandler != nil) { - self.cancelHandler!(self, [:]) - } - break + if let theTitle = webView.title, !theTitle.isEmpty { + let matches = ValidationHelper.findMatchesForErrorCode(content: theTitle) + + if let cancelHandler = self.cancelHandler, ValidationHelper.isErrorCodePage(matches: matches, content: theTitle) { + cancelHandler(self, [:]) } - } - + + } else { + + if let url = webView.url, url.absoluteString.contains("/undefined") { + webView.evaluateJavaScript("document.title", completionHandler: { result, error in + guard let dataHtml = result as? String else { return } + + let matches = ValidationHelper.findMatchesForErrorCode(content: dataHtml) + + if let cancelHandler = self.cancelHandler, ValidationHelper.isErrorCodePage(matches: matches, content: dataHtml) { + cancelHandler(self, [:]) + } + }) + } + } } public func webView(webView:WKWebView!, didFailNavigation error:NSError!) { diff --git a/TrustlySDK.podspec b/TrustlySDK.podspec index d2a8f11..c1718f9 100644 --- a/TrustlySDK.podspec +++ b/TrustlySDK.podspec @@ -9,7 +9,7 @@ Pod::Spec.new do |s| s.name = 'TrustlySDK' - s.version = '3.2.1' + s.version = '3.2.2' s.summary = 'This SDK help the merchants to integrate their solutions with Trustly Widget and LightBox.' s.swift_version = '5.0'