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…
Save our package in selected folder and create local Git repository.
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.
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.
Now go to Source Control and choose Push. Check “Include Tags” and click on Push.
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...
In search paste the url of our Git repository.
GitHub repository
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:
And custom package also.