Ashutosh Mukherjee
Ashutosh Mukherjee

Reputation: 3

Getting a SSL error code -1200 while trying to integrate a post API using Alamofire in swift

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:-

  1. Model:-

    import Foundation

    struct RegisterModel: Encodable { let email: String let firstname: String let lastname: String let password: String }

  2. 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()
        
    }
}
  1. 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 = ""
             }
         }
     }
    

    }

  2. 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

Answers (1)

Ashutosh Mukherjee
Ashutosh Mukherjee

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

Related Questions