Reputation: 3
I am trying to integrate a POST api in my project using ALAMOFIRE, but there is an error that I am getting which prints "An SSL error has occurred and a secure connection to the server cannot be made." in my console. The entire error that is being printed in my console is as below:-
[Request]: POST https://b2c-api.digital.com/customerservice/customers/createCustomer
[Headers]:
Content-Type: application/json
[Body]:
{"email":"[email protected]","lastname":"Tosh","password":"Ashu123!!","firstname":"Ashu"}
[Response]: None
[Network Duration]: 0.41680002212524414s
[Serialization Duration]: 0.0s
[Result]: failure(Alamofire.AFError.sessionTaskFailed(error: Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, NSErrorPeerCertificateChainKey=(
"<cert(0x7f87d8827c00) s: b2c-api.tadigital.com i: ca.oss.de.goskope.com>",
"<cert(0x7f87d8823800) s: ca.oss.de.goskope.com i: caadmin.netskope.com>",
"<cert(0x7f87d8897200) s: caadmin.netskope.com i: caadmin.netskope.com>"
), NSErrorClientCertificateStateKey=0, NSErrorFailingURLKey=https://b2c-api.tadigital.com/customerservice/customers/createCustomer, NSErrorFailingURLStringKey=https://b2c-api.tadigital.com/customerservice/customers/createCustomer, NSUnderlyingError=0x600000dbe250 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x6000032b00a0>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, kCFStreamPropertySSLPeerCertificates=(
"<cert(0x7f87d8827c00) s: b2c-api.tadigital.com i: ca.oss.de.goskope.com>",
"<cert(0x7f87d8823800) s: ca.oss.de.goskope.com i: caadmin.netskope.com>",
"<cert(0x7f87d8897200) s: caadmin.netskope.com i: caadmin.netskope.com>"
)}}, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask <CEAA8DFD-FC6B-4C49-B906-1CD9AAB11F62>.<1>"
), _kCFStreamErrorCodeKey=-9802, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <CEAA8DFD-FC6B-4C49-B906-1CD9AAB11F62>.<1>, NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x6000032b00a0>, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made.}))
URLSessionTask failed with error: An SSL error has occurred and a secure connection to the server cannot be made.
There are several files that constitute to my project as follows:-
Model:-
import Foundation
struct RegisterModel: Encodable { let email: String let firstname: String let lastname: String let password: String }
View
import SwiftUI
struct SignupFormView: View {
@StateObject private var formModel = FormViewModel()
var body: some View {
ZStack {
VStack {
LogoImage()
PrimarytextStyle(title: "Create an Account")
Group{
TextField("Email address", text: $formModel.textEmail, onEditingChanged: { formModel.handleEditChanged($0, formModel: formModel) })
if !formModel.isEmailValid {
InvalidEmailView()
}
TextField("First name", text: $formModel.firstname)
.padding(.top)
.padding(.bottom)
TextField("Last name", text: $formModel.lastname)
.padding(.bottom)
TextField("Mobile Phone number (optional)", text: $formModel.phone)
.padding(.bottom)
SecureField("Create Password", text: $formModel.Password)
Text(formModel.passwordPrompt)
.foregroundColor(.red)
.font(.system(size: 10))
.frame(maxWidth: .infinity, alignment: .leading)
SecureField("Confirm Password", text: $formModel.ConfirmPassword)
Text(formModel.confirmPwPrompt)
.foregroundColor(.red)
.font(.system(size: 10))
.frame(maxWidth: .infinity, alignment: .leading)
}
.textFieldStyle(.roundedBorder)
.frame(width: 360)
.autocapitalization(.none)
Button {
if formModel.isEmailValid && formModel.isPasswordCriteriaValid && formModel.isConfirmPasswordValid {
let register = RegisterModel(email: formModel.textEmail, firstname: formModel.firstname, lastname: formModel.lastname, password: formModel.Password)
APIManager.shareInstance.callingRegisterAPI(register: register)
}
} label: {
PrimaryButton(title: "CREATE AN ACCOUNT", bgcolor: Color.blue, textcolor: Color.white)
}
.opacity(formModel.canCreateAccount ? 1 : 0.6)
.disabled(!formModel.canCreateAccount)
NavigationLink(destination: LoginView(), label: {
SecondaryButton(title: "Or Sign-In")
})
.navigationBarHidden(true)
.navigationBarBackButtonHidden(true)
}
.padding(.bottom, 120)
}
}
}
struct SignupFormView_Previews: PreviewProvider {
static var previews: some View {
SignupFormView()
}
}
ViewModel
import Foundation import Combine
class FormViewModel: ObservableObject {
@Published var Password = ""
@Published var ConfirmPassword = ""
@Published var firstname = ""
@Published var lastname = ""
@Published var phone = ""
@Published var isPasswordCriteriaValid = true
@Published var isConfirmPasswordValid = true
@Published var canCreateAccount = true
private var cancellableSet: Set<AnyCancellable> = []
@Published var emailString : String = ""
@Published var textEmail : String = ""
@Published var isEmailValid : Bool = true
func textFieldValidatorEmail(_ string: String) -> Bool {
if string.count > 100 {
return false
}
let emailFormat = "(?:[\\p{L}0-9!#$%\\&'*+/=?\\^_`{|}~-]+(?:\\.[\\p{L}0-9!#$%\\&'*+/=?\\^_`{|}" + "~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\" + "x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[\\p{L}0-9](?:[a-" + "z0-9-]*[\\p{L}0-9])?\\.)+[\\p{L}0-9](?:[\\p{L}0-9-]*[\\p{L}0-9])?|\\[(?:(?:25[0-5" + "]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-" + "9][0-9]?|[\\p{L}0-9-]*[\\p{L}0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21" + "-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])"
//let emailFormat = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
let emailPredicate = NSPredicate(format:"SELF MATCHES %@", emailFormat)
return emailPredicate.evaluate(with: string)
}
let passwordPredicate = NSPredicate(format: "SELF MATCHES %@", "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[@$!%*#?&])[A-Za-z\\d@$!%*#?&]{8,}$")
init() {
$Password
.map { Password in
return self.passwordPredicate.evaluate(with: Password)
}
.assign(to: \.isPasswordCriteriaValid, on: self)
.store(in: &cancellableSet)
Publishers.CombineLatest($Password , $ConfirmPassword)
.map { Password , ConfirmPassword in
return Password == ConfirmPassword
}
.assign(to: \.isConfirmPasswordValid, on: self)
.store(in: &cancellableSet)
Publishers.CombineLatest3($isEmailValid , $isPasswordCriteriaValid, $isConfirmPasswordValid)
.map { isEmailValid , isPasswordCriteriaValid, isConfirmPasswordValid in
return ( isEmailValid && isPasswordCriteriaValid && isConfirmPasswordValid)
}
.assign(to: \.canCreateAccount, on: self)
.store(in: &cancellableSet)
}
var confirmPwPrompt: String {
isConfirmPasswordValid ? "" : "Password does not match"
}
var passwordPrompt: String {
isPasswordCriteriaValid ? "" : "Strong Password required"
}
func createAccount() {
print("Creating an account")
textEmail = ""
Password = ""
ConfirmPassword = ""
firstname = ""
lastname = ""
phone = ""
}
func handleEditChanged(_ isChanged: Bool, formModel: FormViewModel)
{
if !isChanged {
if formModel.textFieldValidatorEmail(formModel.textEmail) {
formModel.isEmailValid = true
} else {
formModel.isEmailValid = false
formModel.textEmail = ""
}
}
}
}
API Manager
import Foundation import Alamofire
class APIManager {
static let shareInstance = APIManager()
func callingRegisterAPI(register: RegisterModel) {
let headers: HTTPHeaders = [
.contentType("application/json")
]
AF.request("https://b2c-api.digital.com/customerservice/customers/createCustomer", method: .post, parameters: register, encoder: JSONParameterEncoder.default, headers: headers).response { response in
debugPrint(response)
switch response.result {
case .success(let data):
do {
let json = try JSONSerialization.jsonObject(with: data!, options: [])
print(json)
} catch {
}
case .failure(let err):
print(err.localizedDescription)
}
}
}
}
Can someone please provide the solution on how to resolve it I am new to swift.
Also I am getting a Fatal error: Unexpectedly found nil while unwrapping an Optional value in API Manager code inside do{} block over data!.
Upvotes: 0
Views: 579
Reputation: 3
So we need to pass the authorization header too in the api. So it would be like
let headers: HTTPHeaders = [
.contentType("application/json"), .authorization(bearerToken: "Bearer eyJhbGciOiJIUzUxMiJ9.eyJqdGkiOiJzb2Z0dGVrSldUIiwic3ViIjoiZGV2IiwiYXV0aG9yaXRpZXMiOlsiUk9MRV9VU0VSIl0sImlhdCI6MTY2NzQ3Njg3OCwiZXhwIjoxNjY3NTYzMjc4fQ.t7rsskdb7ADELZCWxTZnq2mBLuJcsvSqOFKn0i54m2F_IKMl7zOjSgbyadDIAgNd9tQfEISsZ-g7uq-ssVGeIQ")
]
So it will resolve the error. the authorization token is unique and needs to be generated for one's own.
Upvotes: 0