Codementor Events

SwiftUI custom OTP View, Firebase OTP authentication-Part 03

Published Jun 08, 2022
SwiftUI custom OTP View, Firebase OTP authentication-Part 03

In this last part of mini series, we will show how to create reusable swift package that consists of OTP view from part 2.

First thins first, lets oopen XCode and create new package. Open XCode and go to File -> New -> Package…

1_AzXdiYaUCqD6zQu4HiuYzw.png

Save our package in selected folder and create local Git repository.

1_CRU4q8wQXzR0jxAgGy12tQ.png

Now lets add some code. In order to use this package, we need to add some parameters that will allow us to dynamically use this control as package.

Now lets add some fields and constructor.

//MARK: Fields
enum FocusField: Hashable {
    case field
}
@FocusState private var focusedField: FocusField?
@Binding var otpCode: String
var otpCodeLength: Int
var textColor: Color
var textSize: CGFloat

//MARK: Constructor
public init(otpCode: Binding<String>, otpCodeLength: Int, textColor: Color, textSize: CGFloat) {
    self._otpCode = otpCode
    self.otpCodeLength = otpCodeLength
    self.textColor = textColor
    self.textSize = textSize
}

First lets explain our variables. We use 4 parameters where one is Binding as we will need to update property that stores data and use it later.

otpCode is our Binding var that will hold otp code that user enters. We use it later for user authentication so that why it must be Binding.

otpCodeLength is parameter that is setting number of dashes for out otp code.

textColor is parameter that sets the color of our text and dashes.

textSize is setting text size.

Now lets add body of our view.

//MARK: Body
public var body: some View {
    HStack {
        ZStack(alignment: .center) {
            TextField("", text: $otpCode)
                .frame(width: 0, height: 0, alignment: .center)
                .font(Font.system(size: 0))
                .accentColor(.clear)
                .foregroundColor(.clear)
                .multilineTextAlignment(.center)
                .keyboardType(.numberPad)
                .onReceive(Just(otpCode)) { _ in limitText(otpCodeLength) }
                .focused($focusedField, equals: .field)
                .task {
                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.5)
                    {
                        self.focusedField = .field
                    }
                }
                .padding()
            HStack {
                ForEach(0..<otpCodeLength) { index in
                    ZStack {
                        Text(self.getPin(at: index))
                            .font(Font.system(size: textSize))
                            .fontWeight(.semibold)
                            .foregroundColor(textColor)
                        Rectangle()
                            .frame(height: 2)
                            .foregroundColor(textColor)
                            .padding(.trailing, 5)
                            .padding(.leading, 5)
                            .opacity(self.otpCode.count <= index ? 1 : 0)
                    }
                }
            }
        }
    }
}

As we can see, we have used same code from part 02 of our tutorial, with defined parameters of course. Last lets add missing functions that limit user input length depending on otpCodeLength and function that is getting otp code digit at desired index.

//MARK: func
private func getPin(at index: Int) -> String {
    guard self.otpCode.count > index else {
        return ""
    }
    return self.otpCode[index]
}

private func limitText(_ upper: Int) {
    if otpCode.count > upper {
        otpCode = String(otpCode.prefix(upper))
    }
}

Now lets create new tag from our code. In XCode open Source Control Navigator.

1_vPtea8oyXgGBhjOq51oFVA.png

Then commit the changes of our source code. Then commit will be shown in right panel. Now right click on lates commit and click tag. Enter desired revision number and click create. We will end up with next result.

1_gewwUOAomgduBnj-eUxSJA.png

Now go to Source Control and choose Push. Check “Include Tags” and click on Push.

1_Khm5D92cu1r7nnPULN-gLQ.png

Now, next step is to add created package to our app. Open up the OtpView app and in package dependencies right click and choose Add packages...

1_QULGbEJcgDTe6SGzxSXsKg.png

In search paste the url of our Git repository.
GitHub repository

1_X0lJo4xwO47IK5mdsvhCkA.png

You can choose either branch or exact version like 1.0.3 and click Add package.

Now lets update our ActivateAccountView.swift. First import our new package then change the codeDigits view as following.

import OtpView_SwiftUI

var codeDigits: some View {
      VStack {
          //...
          
          //Old code
          //OTPTextFieldView(phoneViewModel: phoneViewModel)
          //     .padding(.leading, 55)
          //     .padding(.trailing, 55)
        
          //Our package module
          OtpView_SwiftUI(otpCode: $otpCode, otpCodeLength: 6, textColor: Color.black, textSize: 15.0)
          //...
      }
      .padding(.top, 35)
  }

That is it, hope you have enjoyed this tutorial, and stay tuned for more content.

As always, the code is available in the GitHub repository:

CustomOtpView

And custom package also.

GitHub package

Discover and read more posts from Kenan Begić
get started