diff --git a/demoapp/ViewController.swift b/demoapp/ViewController.swift index 2cf2ea5..fa6805e 100644 --- a/demoapp/ViewController.swift +++ b/demoapp/ViewController.swift @@ -13,7 +13,7 @@ class ViewController: UIViewController { - let merchantID = "1211149" //"1211149" //"210251" + let merchantID = "210251" //"1211149" //"210251" var initRequest : PHInitialRequest? @@ -157,6 +157,11 @@ extension ViewController : PHViewControllerDelegate{ func onErrorReceived(error: Error) { print("✋ Error",error) + + let ac = UIAlertController(title: "Error Occurred", message: error.localizedDescription, preferredStyle: .alert) + let okAction = UIAlertAction(title: "OK", style: .default, handler: nil) + ac.addAction(okAction) + present(ac, animated: true, completion: nil) } func onResponseReceived(response: PHResponse?) { diff --git a/payHereSDK.podspec b/payHereSDK.podspec index 9d8e72d..16c591b 100644 --- a/payHereSDK.podspec +++ b/payHereSDK.podspec @@ -8,7 +8,7 @@ s.summary = "Mobile SDK for payHere" s.requires_arc = true # 2 -s.version = "3.0.3" +s.version = "3.0.4" # 3 s.license = { :type => "MIT", :file => "LICENSE" } diff --git a/payHereSDK.xcodeproj/project.pbxproj b/payHereSDK.xcodeproj/project.pbxproj index 394664d..f0775bf 100644 --- a/payHereSDK.xcodeproj/project.pbxproj +++ b/payHereSDK.xcodeproj/project.pbxproj @@ -59,6 +59,7 @@ C7E9F6C1277C76B70013D2D4 /* PHBottomSheetTableViewSectioHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = C7E9F6C0277C76B70013D2D4 /* PHBottomSheetTableViewSectioHeader.xib */; }; D68AD170D5E2B0BDB07655F7 /* Pods_demoapp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C5C73F5CCE9DE42DB20A5A09 /* Pods_demoapp.framework */; }; F503041127E4744C008844E5 /* PHUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = F503041027E4744C008844E5 /* PHUtils.swift */; }; + F505EC902833418C00F6AC4F /* WaitUntil.swift in Sources */ = {isa = PBXBuildFile; fileRef = F505EC8F2833418C00F6AC4F /* WaitUntil.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -144,6 +145,7 @@ D10E7597F9AFFB0D66AE7793 /* Pods_payHereSDK.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_payHereSDK.framework; sourceTree = BUILT_PRODUCTS_DIR; }; E98AA3326CB2BEE8C4106D35 /* Pods-payHereSDK.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-payHereSDK.debug.xcconfig"; path = "Pods/Target Support Files/Pods-payHereSDK/Pods-payHereSDK.debug.xcconfig"; sourceTree = ""; }; F503041027E4744C008844E5 /* PHUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PHUtils.swift; sourceTree = ""; }; + F505EC8F2833418C00F6AC4F /* WaitUntil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaitUntil.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -292,6 +294,7 @@ C746D50F234C9A7300F9D06F /* PHPrecentController.swift */, C799349323A8E72B005E5A7B /* PHBottomViewController.swift */, C72750CC23A75B8A00AE9037 /* image.xcassets */, + F505EC8F2833418C00F6AC4F /* WaitUntil.swift */, ); path = Sources; sourceTree = ""; @@ -492,6 +495,7 @@ buildActionMask = 2147483647; files = ( C7A7DA3323C5D6F90029210E /* HeaderCollectionReusableView.swift in Sources */, + F505EC902833418C00F6AC4F /* WaitUntil.swift in Sources */, C7E9F6B8277C2FA20013D2D4 /* PayWithHelaPayTableViewCell.swift in Sources */, C72A13D12784500D00F08E22 /* PaymentOptionTableViewCell.swift in Sources */, 8A74D7FC20528E5C00CF10AB /* Address.swift in Sources */, diff --git a/payHereSDK/Sources/Model/PaymentUI.swift b/payHereSDK/Sources/Model/PaymentUI.swift index 4f7a3d1..1fdf9b6 100644 --- a/payHereSDK/Sources/Model/PaymentUI.swift +++ b/payHereSDK/Sources/Model/PaymentUI.swift @@ -17,6 +17,10 @@ import Foundation var status: Int? var msg: String? var data: [String: Datum]? + + func getDataCount() -> Int{ + return data?.keys.count ?? 0 + } } // MARK: - Datum diff --git a/payHereSDK/Sources/PHBottomViewController.swift b/payHereSDK/Sources/PHBottomViewController.swift index 8d5a4b0..ce13875 100644 --- a/payHereSDK/Sources/PHBottomViewController.swift +++ b/payHereSDK/Sources/PHBottomViewController.swift @@ -55,6 +55,7 @@ internal class PHBottomViewController: UIViewController { private var statusResponse : StatusResponse? private var timer : Timer? private var isBackPressed : Bool = false + private var waitUntilPaymentUI: WaitUntil! private let net = NetworkReachabilityManager() private var bankAccount : [PaymentMethod] = [] @@ -772,31 +773,15 @@ internal class PHBottomViewController: UIViewController { if let url = submitResponse.data?.url{ - self.tableView.isHidden = true - self.webView.isHidden = false - - self.webView.contentMode = .scaleAspectFill - self.webView.uiDelegate = self - self.webView.navigationDelegate = self - - self.calculateWebHeight() - - if let URL = URL(string: url){ - - let request = URLRequest(url: URL) - self.webView.load(request) - self.progressBar.isHidden = false - self.webView.isHidden = true - - - }else{ - //MARK:TODO - //ERROR HANDLING - self.close { - let error = NSError(domain: "", code: 401, userInfo: [NSLocalizedDescriptionKey: "Invalid URL"]) - self.delegate?.onErrorReceived(error: error) + waitUntilPaymentUI = WaitUntil( + condition: { [weak self] in + return (self?.paymentUI.getDataCount() ?? 0) > 0 + }, + onCompletion: { [weak self] in + self?.loadPayHereSubmitUI(url: url) } - } + ) + }else{ self.close { let error = NSError(domain: "", code: 401, userInfo: [NSLocalizedDescriptionKey: "Invalid URL"]) @@ -806,39 +791,51 @@ internal class PHBottomViewController: UIViewController { } - private func initWebView(_ submitResponse : PayHereInitnSubmitResponse){ + private func loadPayHereSubmitUI(url: String){ + self.tableView.isHidden = true + self.webView.isHidden = false + self.webView.contentMode = .scaleAspectFill + self.webView.uiDelegate = self + self.webView.navigationDelegate = self + self.calculateWebHeight() + + if let URL = URL(string: url){ + + let request = URLRequest(url: URL) + self.webView.load(request) + self.progressBar.isHidden = false + self.webView.isHidden = true + + + }else{ + //MARK:TODO + //ERROR HANDLING + self.close { + let error = NSError(domain: "", code: 401, userInfo: [NSLocalizedDescriptionKey: "Invalid URL"]) + self.delegate?.onErrorReceived(error: error) + } + } + } + + private func initWebView(_ submitResponse : PayHereInitnSubmitResponse){ // MARK: TODO Remove comment when submit API Precent if let url = submitResponse.data?.redirection?.url{ // self.collectionView.isHidden = true - self.webView.isHidden = false - - self.webView.contentMode = .scaleAspectFill - self.webView.uiDelegate = self - self.webView.navigationDelegate = self - self.calculateWebHeight() - - if let URL = URL(string: url){ - - let request = URLRequest(url: URL) - self.webView.load(request) - self.progressBar.isHidden = false - self.webView.isHidden = true - - - }else{ - //MARK:TODO - //ERROR HANDLING - self.close { - let error = NSError(domain: "", code: 401, userInfo: [NSLocalizedDescriptionKey: "Invalid URL"]) - self.delegate?.onErrorReceived(error: error) + waitUntilPaymentUI = WaitUntil( + condition: { [weak self] in + return (self?.paymentUI.getDataCount() ?? 0) > 0 + }, + onCompletion: { [weak self] in + self?.loadPayHereInitAndSubmitUI(url: url) } - } + ) + }else{ self.close { let error = NSError(domain: "", code: 401, userInfo: [NSLocalizedDescriptionKey: "Invalid URL"]) @@ -848,6 +845,33 @@ internal class PHBottomViewController: UIViewController { } + private func loadPayHereInitAndSubmitUI(url: String){ + self.webView.isHidden = false + + self.webView.contentMode = .scaleAspectFill + self.webView.uiDelegate = self + self.webView.navigationDelegate = self + + self.calculateWebHeight() + + if let URL = URL(string: url){ + + let request = URLRequest(url: URL) + self.webView.load(request) + self.progressBar.isHidden = false + self.webView.isHidden = true + + + }else{ + //MARK:TODO + //ERROR HANDLING + self.close { + let error = NSError(domain: "", code: 401, userInfo: [NSLocalizedDescriptionKey: "Invalid URL"]) + self.delegate?.onErrorReceived(error: error) + } + } + } + func calculateWebHeight(){ var viewSize : ViewSize? @@ -1174,7 +1198,10 @@ internal class PHBottomViewController: UIViewController { } } - case .failure(_): + case .failure(let error): + self.close { + self.delegate?.onErrorReceived(error: error) + } break } diff --git a/payHereSDK/Sources/WaitUntil.swift b/payHereSDK/Sources/WaitUntil.swift new file mode 100644 index 0000000..fb9e4e0 --- /dev/null +++ b/payHereSDK/Sources/WaitUntil.swift @@ -0,0 +1,68 @@ +// +// WaitUntil.swift +// payHereSDK +// +// Created by Thisura Dodangoda on 2022-05-17. +// Copyright © 2022 PayHere. All rights reserved. +// + +import Foundation + +/** + Wait until a condition is true to execute a handler + */ +internal class WaitUntil{ + + private let condition: (() -> Bool)! + private let completion: (() -> Void)! + private let timeout: TimeInterval! + + init( + condition: @escaping () -> Bool, + onCompletion: @escaping () -> Void, + timeout: TimeInterval = 5.0 + ){ + self.condition = condition + self.completion = onCompletion + self.timeout = timeout + + run() + } + + private func run(){ + guard !condition() else { + completion() + return + } + + DispatchQueue.global().async { [weak self] in + guard let `self` = self else { return } + + let start = Date().timeIntervalSince1970 + var shouldBreak = false + var isTimeout = false + + while(!shouldBreak){ + usleep(80000) + + DispatchQueue.main.async { + if self.condition(){ + shouldBreak = true + } + } + + if ((Date().timeIntervalSince1970 - start) > self.timeout){ + shouldBreak = true + isTimeout = true + } + } + + guard !isTimeout else { return } + + DispatchQueue.main.async { + self.completion() + } + } + } + +} diff --git a/payHereSDK/Sources/image.xcassets/warning.imageset/Contents.json b/payHereSDK/Sources/image.xcassets/warning.imageset/Contents.json new file mode 100644 index 0000000..acb4256 --- /dev/null +++ b/payHereSDK/Sources/image.xcassets/warning.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "warning.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "warning@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "warning@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/payHereSDK/Sources/image.xcassets/warning.imageset/warning.png b/payHereSDK/Sources/image.xcassets/warning.imageset/warning.png new file mode 100644 index 0000000..af8ac97 Binary files /dev/null and b/payHereSDK/Sources/image.xcassets/warning.imageset/warning.png differ diff --git a/payHereSDK/Sources/image.xcassets/warning.imageset/warning@2x.png b/payHereSDK/Sources/image.xcassets/warning.imageset/warning@2x.png new file mode 100644 index 0000000..724f6e5 Binary files /dev/null and b/payHereSDK/Sources/image.xcassets/warning.imageset/warning@2x.png differ diff --git a/payHereSDK/Sources/image.xcassets/warning.imageset/warning@3x.png b/payHereSDK/Sources/image.xcassets/warning.imageset/warning@3x.png new file mode 100644 index 0000000..3d96c8c Binary files /dev/null and b/payHereSDK/Sources/image.xcassets/warning.imageset/warning@3x.png differ