diff --git a/KiwiPods.podspec b/KiwiPods.podspec index ac0df1d..26765fc 100644 --- a/KiwiPods.podspec +++ b/KiwiPods.podspec @@ -119,6 +119,11 @@ Pod::Spec.new do |s| twitter.source_files = "KiwiPods/Social/Twitter/**/*.{h,m,swift}" twitter.dependency 'TwitterKit' end + socialMedia.subspec 'Google' do |google| + google.source_files = "KiwiPods/Social/Google/**/*.{h,m,swift}" + google.dependency 'GoogleSignIn' + s.framework = 'GoogleSignIn' + end end s.subspec 'ImagePicker' do |imagePicker| diff --git a/KiwiPods.xcodeproj/project.pbxproj b/KiwiPods.xcodeproj/project.pbxproj index eeff703..72e0bc2 100644 --- a/KiwiPods.xcodeproj/project.pbxproj +++ b/KiwiPods.xcodeproj/project.pbxproj @@ -8,6 +8,8 @@ /* Begin PBXBuildFile section */ 38F04F541C2C888359AB8568 /* Pods_KiwiPods.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 41185E9826A76800BF01C8A8 /* Pods_KiwiPods.framework */; }; + D66402A921E4D4C70024B3D3 /* ValidationsUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66402A821E4D4C70024B3D3 /* ValidationsUtils.swift */; }; + D66402AF21E4D4FF0024B3D3 /* GoogleHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66402AE21E4D4FF0024B3D3 /* GoogleHandler.swift */; }; D66ADF4121D50488004499F2 /* HashTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66ADF3E21D50488004499F2 /* HashTextView.swift */; }; D66ADF4221D50488004499F2 /* UILinkLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66ADF4021D50488004499F2 /* UILinkLabel.swift */; }; D66ADF4F21D504B0004499F2 /* ImagePickerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66ADF4321D504AD004499F2 /* ImagePickerController.swift */; }; @@ -32,6 +34,8 @@ 41185E9826A76800BF01C8A8 /* Pods_KiwiPods.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_KiwiPods.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 807FADC5BC231460701B403A /* Pods-KiwiPods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-KiwiPods.release.xcconfig"; path = "Pods/Target Support Files/Pods-KiwiPods/Pods-KiwiPods.release.xcconfig"; sourceTree = ""; }; C57934D16A5207D271DDC35C /* Pods-KiwiPods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-KiwiPods.debug.xcconfig"; path = "Pods/Target Support Files/Pods-KiwiPods/Pods-KiwiPods.debug.xcconfig"; sourceTree = ""; }; + D66402A821E4D4C70024B3D3 /* ValidationsUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ValidationsUtils.swift; sourceTree = ""; }; + D66402AE21E4D4FF0024B3D3 /* GoogleHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GoogleHandler.swift; sourceTree = ""; }; D66ADF3E21D50488004499F2 /* HashTextView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HashTextView.swift; sourceTree = ""; }; D66ADF4021D50488004499F2 /* UILinkLabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UILinkLabel.swift; sourceTree = ""; }; D66ADF4321D504AD004499F2 /* ImagePickerController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImagePickerController.swift; sourceTree = ""; }; @@ -75,6 +79,14 @@ name = Pods; sourceTree = ""; }; + D66402AD21E4D4FF0024B3D3 /* Google */ = { + isa = PBXGroup; + children = ( + D66402AE21E4D4FF0024B3D3 /* GoogleHandler.swift */, + ); + path = Google; + sourceTree = ""; + }; D66ADF3D21D50488004499F2 /* HashTextView */ = { isa = PBXGroup; children = ( @@ -112,6 +124,7 @@ D66ADF5D21D504D8004499F2 /* Social */ = { isa = PBXGroup; children = ( + D66402AD21E4D4FF0024B3D3 /* Google */, D66ADF5B21D504BA004499F2 /* Facebook */, D66ADF5C21D504C6004499F2 /* Twitter */, ); @@ -161,6 +174,7 @@ D66ADF3D21D50488004499F2 /* HashTextView */, D66ADF3F21D50488004499F2 /* UILinkLabel */, D6B031672189D2C9003431C6 /* Networking */, + D66402A821E4D4C70024B3D3 /* ValidationsUtils.swift */, D6B031602189D172003431C6 /* Info.plist */, ); path = KiwiPods; @@ -323,6 +337,8 @@ D66ADF4F21D504B0004499F2 /* ImagePickerController.swift in Sources */, D6E90B7421E4D5BA0072876C /* Logger.swift in Sources */, D66ADF5421D504B0004499F2 /* TwitterHelper.swift in Sources */, + D66402AF21E4D4FF0024B3D3 /* GoogleHandler.swift in Sources */, + D66402A921E4D4C70024B3D3 /* ValidationsUtils.swift in Sources */, D66ADF5521D504B0004499F2 /* ImagePickerCell.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/KiwiPods/Networking/NetworkModel.swift b/KiwiPods/Networking/NetworkModel.swift index cf7a0da..46d2784 100644 --- a/KiwiPods/Networking/NetworkModel.swift +++ b/KiwiPods/Networking/NetworkModel.swift @@ -30,7 +30,7 @@ public enum RequestType: String { //using our own URLRequestConvertible so that networking library can be updated easily public protocol URLRequestConvertible { - func asURLRequest() -> URLRequest? + func asURLRequest() throws -> URLRequest } public protocol APIConfigurable: URLRequestConvertible { @@ -41,7 +41,7 @@ public protocol APIConfigurable: URLRequestConvertible { } public extension APIConfigurable { - public func asURLRequest() -> URLRequest? { + public func asURLRequest() throws -> URLRequest { var queryItems = "" if type == .GET, parameters.count > 0 { queryItems = parameters.reduce("?") { (value: String, arg1: (String, Any)) -> String in @@ -56,20 +56,18 @@ public extension APIConfigurable { if type != .GET { urlRequest.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: JSONSerialization.WritingOptions.prettyPrinted) } - urlRequest.cachePolicy = .reloadIgnoringCacheData return urlRequest } catch { - print(error.localizedDescription) - return nil + throw error } } } public protocol ParameterConvertible: Codable { - static func objectFrom(json: Any, decoder: JSONDecoder)throws -> ParameterConvertible? + static func objectFrom(json: Any, decoder: JSONDecoder)throws -> Self? func toParams()throws -> [String: Any]? } public extension ParameterConvertible { - static public func objectFrom(json: Any, decoder: JSONDecoder) throws -> ParameterConvertible? { + static public func objectFrom(json: Any, decoder: JSONDecoder = JSONDecoder()) throws -> Self? { do { let data = try JSONSerialization.data(withJSONObject: json, options: JSONSerialization.WritingOptions.prettyPrinted) let jsonModel = try decoder.decode(self, from: data) @@ -95,7 +93,7 @@ public enum Response where ResponseType: ParameterConvertible { public let error: Error? public let statusCode: Int? public let errorValue: [String: Any]? - public init(error: Error?, statusCode: Int?, errorValue: [String: Any]? = nil) { + public init(error: Error?, statusCode: Int? = nil, errorValue: [String: Any]? = nil) { self.error = error self.statusCode = statusCode self.errorValue = errorValue diff --git a/KiwiPods/Social/Google/GoogleHandler.swift b/KiwiPods/Social/Google/GoogleHandler.swift new file mode 100644 index 0000000..0ba5426 --- /dev/null +++ b/KiwiPods/Social/Google/GoogleHandler.swift @@ -0,0 +1,50 @@ +// +// GoogleHandler.swift +// +// +// Created by KiwiTech on 07/01/19. +// Copyright © 2019 KiwiTech. All rights reserved. +// + +import UIKit +import GoogleSignIn +open class GoogleHandler: NSObject { + static public let `shared` = GoogleHandler() + override private init() { + super.init() + GIDSignIn.sharedInstance()?.delegate = self + } + fileprivate var loginCompletion: ((String?, Error?) -> Void)? + fileprivate var loginHandlerController: UIViewController? + public func getUser(from controller: UIViewController, completion: @escaping (_ token: String?, _ error: Error?) -> Void) { + if let user = GIDSignIn.sharedInstance()?.currentUser { + loginCompletion = nil + completion(user.authentication.idToken, nil) + } else { + loginCompletion = completion + loginHandlerController = controller + GIDSignIn.sharedInstance()?.uiDelegate = self + GIDSignIn.sharedInstance()?.signIn() + } + } +} +extension GoogleHandler: GIDSignInDelegate { + public func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) { + guard error == nil else { + loginCompletion?(nil, error) + return + } + loginCompletion?(user.authentication.idToken, nil) + } +} +extension GoogleHandler: GIDSignInUIDelegate { + public func sign(_ signIn: GIDSignIn!, present viewController: UIViewController!) { + guard let controller = loginHandlerController else { + return + } + controller.present(viewController, animated: true, completion: nil) + } + public func sign(_ signIn: GIDSignIn!, dismiss viewController: UIViewController!) { + viewController.dismiss(animated: true, completion: nil) + } +} diff --git a/KiwiPods/ValidationsUtils.swift b/KiwiPods/ValidationsUtils.swift new file mode 100644 index 0000000..a0505de --- /dev/null +++ b/KiwiPods/ValidationsUtils.swift @@ -0,0 +1,149 @@ +// +// ValidationsUtils.swift +// Treble +// +// Created by kiwitech on 03/02/17. +// Copyright © 2016 KiwiTech. All rights reserved. +// + +import UIKit + +open class ValidationsUtils: NSObject { + //----------------------------------------------- + // Mark Email validation + //----------------------------------------------- + class public func validateEmail(emailID: String) -> Bool { + let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}" + // NSString *emailRegEx = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"; + let emailTest: NSPredicate = NSPredicate(format: "SELF MATCHES %@", emailRegEx) + return emailTest.evaluate(with: + emailID) + } + //----------------------------------------------- + // Alpha - Numeric validation + //----------------------------------------------- + class public func alphanumericValidation(validation: String) -> Bool { + let alphanumericRegEx = "^[a-zA-Z0-9]+$" + let alphanumericTest: NSPredicate = NSPredicate(format: "SELF MATCHES %@", alphanumericRegEx) + return alphanumericTest.evaluate(with: validation) + } + //----------------------------------------------- + // Mark number validation + //----------------------------------------------- + class public func onlyNumberValidation(number: String) -> Bool { + let nameRegex: String = "^[0-9]+$" + let nameTest: NSPredicate = NSPredicate(format: "SELF MATCHES %@", nameRegex) + return nameTest.evaluate(with: number) + } + //----------------------------------------------- + // Mark number validation + //----------------------------------------------- + class public func onlyNumberValidationWithDash(number: String) -> Bool { + let nameRegex: String = "^[0-9 '-]+$" + let nameTest: NSPredicate = NSPredicate(format: "SELF MATCHES %@", nameRegex) + return nameTest.evaluate(with: number) + } + //----------------------------------------------- + // Mark enter only alphabets + //----------------------------------------------- + class public func onlyAlphabetsValidation(alphabet: String) -> Bool { + let nameRegex: String = "^[a-zA-Z '-]+$" + ///^[a-zA-Z ]*$/ + let nameTest: NSPredicate = NSPredicate(format: "SELF MATCHES %@", nameRegex) + return nameTest.evaluate(with: alphabet) + // return true + } + class public func onlyAlphabetsWithSpaceValidation(alphabet: String) -> Bool { + let nameRegex: String = "^[a-zA-Z ]+$" + let nameTest: NSPredicate = NSPredicate(format: "SELF MATCHES %@", nameRegex) + return nameTest.evaluate(with: alphabet) + } + class public func onlyAlphaNumericWithSpaceValidation(alphabet: String) -> Bool { + let nameRegex: String = "^[a-zA-Z0-9 ]+$" + let nameTest: NSPredicate = NSPredicate(format: "SELF MATCHES %@", nameRegex) + return nameTest.evaluate(with: alphabet) + } + //----------------------------------------------- + // Mark mathch password + //----------------------------------------------- + class public func confirmationPasswordValidation(password: String, confirmationPassword: String) -> Bool { + if password == confirmationPassword { + return true + } else { + return false + } + } + public var tableSourceList: [[String]] = [[Int](0..<20).map({ "section 0, cell \($0)" })] + class public func contentView(text: String) -> UIView { + let view = UIView(frame: CGRect(x: 0, y: 0, width: 375, height: 64)) + view.autoresizingMask = [.flexibleWidth, .flexibleHeight] + let label = UILabel(frame: view.bounds) + label.frame.origin.x = 10 + label.frame.origin.y = 10 + label.frame.size.width -= label.frame.origin.x + label.frame.size.height -= label.frame.origin.y + label.autoresizingMask = [.flexibleWidth, .flexibleHeight] + label.text = text + label.numberOfLines = 2 + label.textColor = UIColor.white + view.addSubview(label) + return view + } + class public func isEmpty(text: String) -> Bool { + if text.trimmingCharacters(in: CharacterSet.whitespaces).isEmpty { + return true + } + return false + } + class public func trimeedCount(text: String) -> Int { + + return text.trimmingCharacters(in: CharacterSet.whitespaces).count + } + class public func isValidCountPassword(passwordString: String) -> Bool { + if passwordString.count >= 4 { + return true + } + return false + } + class public func hasCharacterInString(string: String) -> Bool { + let stricterFilterString = ".*[a-zA-Z]+.*" + let stringTest = NSPredicate(format: "SELF MATCHES %@", stricterFilterString) + return stringTest.evaluate(with: string) + } + + class public func isValidCountOfMobile(textString: String) -> Bool { + if textString.count != 10 { + return false + } + return true + } + class public func isValidZipCode(textString: String) -> Bool { + if textString.count != 5 { + return false + } + return true + } + class public func formatPhoneNumber(contactStr: String) -> String { + let range = contactStr.range(of: contactStr) + let strippedValue = contactStr.replacingOccurrences(of: "[^0-9]", with: "", options: .regularExpression, range: range) + var formattedString = "" + if strippedValue.count == 0 { + formattedString = "" + } else if strippedValue.count < 3 { + formattedString = strippedValue + } else if strippedValue.count == 3 { + formattedString = strippedValue + } else if strippedValue.count < 6 { + let startIndex = strippedValue.index(strippedValue.startIndex, offsetBy: 3) + formattedString = "(" + String(strippedValue[...startIndex]) + ") " + String(strippedValue[startIndex...]) + } else if strippedValue.count == 6 { + let startIndex = strippedValue.index(strippedValue.startIndex, offsetBy: 3) + formattedString = "(" + String(strippedValue[...startIndex]) + ") " + String(strippedValue[startIndex...]) + " - " + } else if strippedValue.count <= 10 { + //let startIndex = strippedValue.index(strippedValue.startIndex, offsetBy: 3) +// formattedString = "(" + String(strippedValue[...startIndex]) + ") " + strippedValue.substring(with: NSMakeRange(0, contactStr.count)) + " - " + String(strippedValue[startIndex...]) + } else if strippedValue.count >= 11 { + } + return formattedString + } + } diff --git a/Podfile b/Podfile index 0ed5ba3..36eec5c 100644 --- a/Podfile +++ b/Podfile @@ -10,6 +10,6 @@ target 'KiwiPods' do pod 'SDWebImage' pod 'TwitterKit' pod 'MBProgressHUD' - # Pods for KiwiPods + pod 'GoogleSignIn' end diff --git a/README.md b/README.md index a153934..009bdef 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,13 @@ # KiwiPods To integrate Kiwipods in your app add `pod 'KiwiPods', :git => 'https://github.com/KiwiTechLLC/KiwiPods.git'` to your pod file. -KiwiPods are supported for `Swift 4.2` and `iOS 11.0 and above` +KiwiPods are supported for `Swift 4.2` and `iOS 11.0 and above` + + +In case `Social` depandency is needed, add following code in `podfile` : +``` +pre_install do |installer| + # workaround for https://github.com/CocoaPods/CocoaPods/issues/3289 + Pod::Installer::Xcode::TargetValidator.send(:define_method, :verify_no_static_framework_transitive_dependencies) {} +end +```