Formatter در iOS مکانیزمی برای قالببندی دادههای ورودی است که به طور خودکار متن غیرساختاریافته را به قالبی مشخص تبدیل میکند. کلاسهای سیستمی NSFormatter و InputMask امکان پردازش شماره تلفنها، کارتهای اعتباری، تاریخها و سایر دادههای ساختاریافته را فراهم میکنند. طبق Apple Foundation Framework Reference (2025)، قالببندی صحیح ورودی تعداد خطاها را هنگام پر کردن فرمها 55% کاهش میدهد و ورود داده را 30% سرعت میبخشد. برای همه فیلدهایی که ورودی ساختاریافته انتظار میرود از فرمتدهندهها استفاده کنید — این کار تجربه کاربری و کیفیت دادههای جمعآوری شده را بهبود میبخشد.
نکات اصلی
Formatter در iOS مؤلفهای است که ورودی خام کاربر را مطابق با یک الگوی مشخص به قالبی ساختاریافته تبدیل میکند. برخلاف اعتبارسنجی ساده پس از ارسال فرم، فرمتدهنده در زمان واقعی کار میکند و نمایش داده را در حین ورود تصحیح میکند. این تفاوت کلیدی است: کاربر نتیجه قالببندی شده را بلافاصله میبیند، بدون نیاز به وارد کردن دستی جداکنندهها.
iOS چندین سطح قالببندی را فراهم میکند: فرمتدهندههای سیستمی Foundation (NumberFormatter, DateFormatter, ByteCountFormatter) برای نمایش داده، فریمورک PhoneNumberKit برای شماره تلفن و کتابخانههای شخص ثالث InputMask برای ماسکهای ورودی دلخواه. انتخاب سطح به نوع داده و انعطافپذیری قالببندی مورد نیاز بستگی دارد.
طبق Apple Human Interface Guidelines، فرمتدهندههای ورودی سه وظیفه را حل میکنند: بار شناختی کاربر را کاهش میدهند (نیاز به فکر کردن درباره جداکنندهها نیست)، تعداد خطاها را کاهش میدهند (دادهها در قالب صحیح وارد میشوند) و پر کردن فرمها را سرعت میبخشند (انتقال خودکار بین گروههای ارقام).
فرمتدهندهها برای دستگاههای موبایل بسیار مهم هستند، جایی که ورود داده با صفحه کلید لمسی نسبت به فیزیکی نیازمند تلاش بیشتری است. هر کاراکتر اضافی که باید به صورت دستی وارد شود، زمان پر کردن فرم و خطر خطا را افزایش میدهد. جایگذاری خودکار جداکنندهها تعداد لمسها را برای فرمتهای معمولی 20-40% کاهش میدهد.
فرمتدهندههای ورودی در iOS به سه دسته تقسیم میشوند: فرمتدهندههای سیستمی Foundation، فرمتدهندههای تخصصی اپل (PhoneNumberKit) و کتابخانههای شخص ثالث (InputMask, MaskedTextField). هر دسته وظایف خود را حل میکند و ویژگیهای پیادهسازی خاصی دارد.
NumberFormatter مقادیر عددی را قالببندی میکند: مبالغ پول، درصدها، نمادهای علمی. از بومیسازی جداکنندههای گروه و اعشار پشتیبانی میکند. DateFormatter تاریخ و زمان را به رشتههای بومیسازی شده تبدیل میکند. این فرمتدهندهها برای نمایش طراحی شدهاند، نه برای ماسکگذاری ورودی، بنابراین اعمال مستقیم آنها در حین تایپ در UITextField دشوار است.
PhoneNumberKit — کتابخانه اپل برای قالببندی شماره تلفن مطابق با استانداردهای ملی. این کتابخانه به طور خودکار کشور را بر اساس کد شناسایی کرده و فرمت مناسب را اعمال میکند. به عنوان مثال، شماره روسی +7 912 345-67-89 متفاوت از شماره آمریکایی +1 212-555-0198 قالببندی میشود. PhoneNumberKit همچنین شماره را از نظر صحت اعتبارسنجی میکند.
کتابخانههای شخص ثالث InputMask یک مکانیزم جهانی ماسکگذاری ورودی برای هر قالبی ارائه میدهند: شماره کارت (0000 0000 0000 0000)، تاریخ (YYYY/MM/DD)، کد ملی (0000000000). کتابخانهها از طریق UITextFieldDelegate کار میکنند، ورودی را گرفته و ماسک را در زمان واقعی اعمال میکنند.
| نوع | فریمورک | کاربرد | حالت کار |
|---|---|---|---|
| اعداد | NumberFormatter | پول، درصد، علمی | نمایش |
| تاریخها | DateFormatter | تاریخ، زمان، timestamp | نمایش |
| تلفنها | PhoneNumberKit | شمارههای استاندارد کشورها | ورود + اعتبارسنجی |
| ماسکها | InputMask | کارتها، کدها، کد ملی | ورود در زمان واقعی |
NSFormatter — کلاس انتزاعی Foundation است که همه فرمتدهندههای سیستمی iOS از آن ارث میبرند. این کلاس دو روش اصلی را تعریف میکند: string(for:) برای تبدیل شیء به رشته و getObjectValue(_:for:errorDescription:) برای تبدیل معکوس رشته به شیء. این مکانیزم دوطرفه هم امکان نمایش داده و هم خواندن آن از فیلدهای متنی را فراهم میکند.
ایجاد فرمتدهنده اختصاصی بر اساس NSFormatter برای فرمتهای خاصی که توسط کلاسهای سیستمی پوشش داده نمیشوند امکانپذیر است. برای این کار باید متدهای string(for:) و getObjectValue(_:for:errorDescription:) را بازنویسی کرد. فرمتدهنده اختصاصی را میتوان از طریق ویژگی formatter با UILabel، UITextField و سایر viewها استفاده کرد.
اپل استفاده از فرمتدهندههای موجود Foundation را به جای ایجاد فرمتدهندههای اختصاصی توصیه میکند. NumberFormatter به درستی 32 زبان و استانداردهای منطقهای را پردازش میکند، DateFormatter تقویمهای فرهنگهای مختلف را در نظر میگیرد و ByteCountFormatter بسته به مقدار بین بایت، کیلوبایت و مگابایت به طور خودکار جابجا میشود.
NSFormatter همچنین از بومیسازی پیامهای خطا در هنگام ورود نادرست پشتیبانی میکند. متد getObjectValue توضیح خطا را برمیگرداند که میتواند به صورت بومیسازی شده به کاربر نمایش داده شود. این برای فرمهایی که کاربر داده را در قالب نادرست وارد میکند بسیار مهم است — پیام خطا باید واضح و به زبان رابط کاربری باشد.
Input Mask (ماسک ورودی) — الگویی است که فرمت دادههای ورودی را تعیین میکند و به طور خودکار جداکنندهها را در حین تایپ قرار میدهد. ماسک از کاراکترهای جایگزین (معمولاً 0 یا 9 برای ارقام، A برای حروف) و کاراکترهای ثابت (پرانتز، خط فاصله، فاصله) تشکیل شده است که به طور خودکار درج میشوند. کاربر فقط کاراکترهای معنیدار را وارد میکند و جداکنندهها توسط سیستم قرار داده میشوند.
محبوبترین کتابخانه برای iOS — InputMask از RedMadRobot. این کتابخانه از ماسکهای پیچیده با شرایط، بلوکهای اختیاری و افیکس (پیشوند و پسوند) پشتیبانی میکند. کتابخانه از طریق delegate پیادهسازی شده است که امکان استفاده از آن با هر UITextField بدون subclassing را فراهم میکند. ماسکهایی برای شماره تلفن، کارت بانکی، تاریخ، کد تأیید و سایر دادههای ساختاریافته پشتیبانی میشود.
فرمت ماسک InputMask از نحو اختصاصی استفاده میکند: براکت برای کاراکترهای اجباری، آکولاد برای اختیاری، کاراکترهای ثابت خارج از براکتها. به عنوان مثال، ماسک شماره کارت به صورت [0000] [0000] [0000] [0000] و برای تاریخ — [00]{.}[00]{.}[0000] است. بلوکهای اختیاری در آکولاد اگر کاربر دادهای برای آنها وارد نکند ناپدید میشوند.
برای شماره تلفن ماسک معمولاً شامل کد کشور در افیکس است: +7 ([000]) [000]-[00]-[00]. کاربر فقط 10 رقم شماره را وارد میکند و کاراکترهای +7، (، )، - به طور خودکار درج میشوند. هنگام حذف کاراکتر، ماسک backspace را به درستی پردازش میکند، آخرین کاراکتر معنیدار را حذف کرده و به موقعیت قبلی بازمیگردد.
قالببندی شماره تلفن — رایجترین سناریوی استفاده از فرمتدهندهها در برنامههای موبایل است. iOS برای این کار فریمورک PhoneNumberKit را فراهم میکند که به طور خودکار کشور را بر اساس کد شناسایی کرده و فرمت ملی مناسب را اعمال میکند. این کتابخانه از بیش از 200 کشور پشتیبانی کرده و به طور منظم بهروزرسانی میشود.
PhoneNumberKit در دو مرحله کار میکند: تشخیص قالب و اعمال آن. در مرحله اول، کتابخانه کد کشور وارد شده را تحلیل میکند (مثلاً +7 روسیه را تشخیص میدهد) و قوانین قالببندی را بارگذاری میکند. در مرحله دوم، ماسک مربوط به استاندارد ملی را اعمال میکند: برای روسیه +7 XXX XXX-XX-XX، برای آمریکا — +1 XXX-XXX-XXXX، برای بریتانیا — +44 XXXX XXX XXX.
طبق Apple Developer Documentation، از iOS 16 یک مکانیزم داخلی برای قالببندی شماره تلفن از طریق UIContentUnavailableConfiguration ظاهر شده است. با این حال، برای قالببندی کامل در زمان واقعی توصیه میشود از PhoneNumberKit از طریق UITextFieldDelegate استفاده شود. کتابخانه همچنین شماره را اعتبارسنجی میکند: تعداد ارقام، مجاز بودن کد کشور و مطابقت با فرمت ملی را بررسی میکند.
برای برنامههای بینالمللی مهم است که کاربر ممکن است شماره را در هر قالبی وارد کند: با +7، 8 (برای روسیه) یا بدون کد کشور. یک فرمتدهنده خوب باید هر فرمت اولیه را تشخیص داده و آن را به یک استاندارد بینالمللی واحد با پیشوند + و کد کشور نرمال کند.
پیادهسازی فرمتدهنده در Swift به رویکرد انتخابی بستگی دارد. برای فرمتدهندههای سیستمی Foundation از ویژگی formatter که از iOS 15 برای UITextField در دسترس است استفاده میشود. برای Input Mask از delegate UITextFieldDelegate با کتابخانه InputMask استفاده میشود. برای شماره تلفن — PhoneNumberKit از طریق delegate.
import PhoneNumberKit
class PhoneViewController: UIViewController {
let phoneNumberKit = PhoneNumberKit()
@IBOutlet var phoneField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
phoneField.delegate = self
}
}
extension PhoneViewController: UITextFieldDelegate {
func textField(
_ textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String
) -> Bool {
guard let text = textField.text else { return true }
let partial = (text as NSString).replacingCharacters(in: range, with: string)
textField.text = partial.applyPhoneMask()
return false
}
}
برای NumberFormatter از iOS 15+ ویژگی formatter در UITextField در دسترس است که به طور خودکار عدد وارد شده را در حین تایپ قالببندی میکند. این رویکرد نیاز به پیادهسازی delegate ندارد و برای فرمتهای پولی، درصدها و سایر دادههای عددی با در نظر گرفتن locale کاربر «جعبهای» کار میکند.
let amountField = UITextField()
let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.locale = Locale(identifier: "ru_RU")
amountField.formatter = formatter
برای کتابخانه InputMask RedMadRobot پیکربندی از طریق مقداردهی اولیه ماسک و اعمال از طریق delegate انجام میشود. کتابخانه از چسباندن (paste)، حذف (backspace) پشتیبانی کرده و با انتخابهای متنی به درستی کار میکند.
import InputMask
class CardViewController: UIViewController {
@IBOutlet var cardField: UITextField!
var listener: MaskedTextFieldDelegate!
override func viewDidLoad() {
super.viewDidLoad()
listener = MaskedTextFieldDelegate(
primaryMaskFormat: "[0000] [0000] [0000] [0000]"
)
cardField.delegate = listener
}
}
سوالات متداول
برای شماره تلفن — PhoneNumberKit، برای ماسکهای عمومی — InputMask از RedMadRobot. برای اعداد و تاریخها NumberFormatter و DateFormatter سیستمی کافی هستند.
بله، UITextView از همان delegateها و متدهای shouldChangeCharactersIn مشابه UITextField پشتیبانی میکند. فرمتدهنده را میتوان از طریق پیادهسازی delegate UITextViewDelegate اعمال کرد.
چسباندن از طریق همان delegate shouldChangeCharactersIn پردازش میشود. یک فرمتدهنده خوب ابتدا همه جداکنندهها را از متن چسبانده شده حذف میکند، سپس ماسک را روی دادههای خالص اعمال میکند.
خیر، ایمیل فرمت ثابتی با جداکننده ندارد. برای ایمیل کافی است textContentType = .emailAddress و کیبورد با علامت @ تنظیم شود.
فرمتدهندههای مدرن ورودی را در کمتر از 1 میلیثانیه به ازای هر کاراکتر پردازش میکنند. تأخیر برای کاربر نامحسوس است. کتابخانههای InputMask و PhoneNumberKit برای کار در زمان واقعی بهینه شدهاند.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید