১৬ ডিসে, ২০২৫·7 মিনিট পড়তে

SwiftUI ফর্ম ভ্যালিডেশন যা নেটিভ মনে হয়: ফোকাস ও ত্রুটি

SwiftUI ফর্ম ভ্যালিডেশন যা নেটিভ মনে হয়: ফোকাস পরিচালনা করুন, উপযুক্ত সময়ে ইনলাইন ত্রুটি দেখান, এবং সার্ভারের বার্তাগুলো পরিষ্কারভাবে দেখান যাতে ব্যবহারকারী বিরক্ত না হন।

SwiftUI ফর্ম ভ্যালিডেশন যা নেটিভ মনে হয়: ফোকাস ও ত্রুটি

SwiftUI-এ "নেটিভ-সদৃশ" ভ্যালিডেশন কেমন হওয়া উচিত

একটি নেটিভ-সদৃশ iOS ফর্ম শান্ত। এটা ব্যবহারকারীর টাইপ করার সময় ঝগড়া করে না। প্রয়োজনীয় মুহূর্তে পরিষ্কার প্রতিক্রিয়া দেয়, এবং ব্যবহারকারীকে সমস্যা খুঁজে বেড়াতে বাধ্য করে না।

মুখ্য প্রত্যাশা হল পূর্বানুমেয়তা। একই কাজ করলে একই ধরনের প্রতিক্রিয়া প্রতিবার হওয়া উচিত। যদি কোনো ফিল্ড অবৈধ হয়, ফর্মটিতে এটি একই স্থানে, একই স্বর ও একটি পরিষ্কার পরবর্তী পদক্ষেপ নিয়ে দেখানো উচিত।

অধিকাংশ ফর্মে মূলত তিন ধরনের নিয়ম লাগে:

  • ফিল্ড নিয়ম: এই একক মানটি বৈধ কি (খালি, ফরম্যাট, দৈর্ঘ্য)?
  • ক্রস-ফিল্ড নিয়ম: মানগুলো কি একে অপরের উপর নির্ভর করে বা মেলে (Password এবং Confirm Password)?
  • সার্ভার নিয়ম: ব্যাকএন্ড এটিকে গ্রহণ করে কি (ইমেল ইতিমধ্যেই ব্যবহৃত, ইনভাইট দরকার)?

টাইমিং চতুর শব্দভাণ্ডরের চেয়েও বেশি গুরুত্বপূর্ণ। ভালো ভ্যালিডেশন একটি অর্থবহ মুহূর্তের জন্য অপেক্ষা করে, তারপর একবার পরিষ্কারভাবে বলে। ব্যবহারিক রিদম এভাবে দেখা যায়:

  • ব্যবহারকারী টাইপ করার সময় নীরব থাকুন, বিশেষত ফরম্যাট নিয়মের জন্য।
  • ফিল্ড ত্যাগ করার পরে বা ব্যবহারকারী Submit চাপানোর পরে প্রতিক্রিয়া দেখান।
  • ত্রুটিগুলো ঠিক হওয়া পর্যন্ত দৃশ্যমান রাখুন, তারপর সেগুলো তৎক্ষণাৎ সরিয়ে দিন।

ব্যবহারকারী এখনও উত্তর গঠন করছে এমন সময় ভ্যালিডেশন নীরব থাকা উচিত — যেমন ইমেল বা পাসওয়ার্ড টাইপ করা। প্রথম অক্ষরে ত্রুটি দেখানো কথায় কথায় তিরস্কারের মত লাগে, যদিও তা প্রযুক্তিগতভাবে সঠিক হতে পারে।

ভ্যালিডেশন তখনই দৃশ্যমান হওয়া উচিত যখন ব্যবহারকারী বলে দেয় যে তিনি শেষ করেছেন: ফোকাস সরে যায়, অথবা তিনি Submit চেষ্টা করেন। এটাই সেই মুহূর্ত যখন তারা নির্দেশনা চায়, এবং তখন আপনি তাদের ঠিক কোন ফিল্ডে মনোযোগ দিতে হবে সেটা দেখাতে পারেন।

টাইমিং ঠিক থাকলে বাকিটা সহজ হয়ে যায়। ইনলাইন মেসেজগুলো সংক্ষিপ্ত থাকতে পারে, ফোকাস স্থানান্তর সহায়ক করে তোলে, এবং সার্ভার-সাইড ত্রুটিগুলো নির্যাতনের বদলে স্বাভাবিক প্রতিক্রিয়ার মত লাগে।

একটি সহজ ভ্যালিডেশন স্টেট মডেল সেটআপ করুন

নেটিভ-সদৃশ ফর্ম শুরু হয় একটি পরিষ্কার পৃথকীকরণ দিয়ে: ব্যবহারকারী যা টাইপ করেছে তা অ্যাপে সেই বিষয়ে মতামত নয়। যদি আপনি এ দুটোকে মিশিয়ে দেন, তাহলে আপনি হয় ত্রুটি খুব আগেই দেখাবেন অথবা UI রিফ্রেশ হলে সার্ভার মেসেজ হারিয়ে যাবে।

একটি সহজ পদ্ধতি হল প্রতিটি ফিল্ডকে তার নিজস্ব স্টেট দেওয়া, যার চারটি অংশ আছে: বর্তমান মান, ব্যবহারকারী এতে ইন্টারঅ্যাক্ট করেছে কি না, লোকাল (ডিভাইস-অভিত) ত্রুটি, এবং সার্ভার ত্রুটি (যদি থাকে)। তখন UI “touched” এবং “submitted” দেখে সিদ্ধান্ত নিতে পারে, প্রতিটি কীস্ট্রোকে প্রতিক্রিয়া স্বরূপ নয়।

struct FieldState {
    var value: String = ""
    var touched: Bool = false
    var localError: String? = nil
    var serverError: String? = nil

    // One source of truth for what the UI displays
    func displayedError(submitted: Bool) -> String? {
        guard touched || submitted else { return nil }
        return localError ?? serverError
    }
}

struct FormState {
    var submitted: Bool = false
    var email = FieldState()
    var password = FieldState()
}

কয়েকটি ছোট নিয়ম এটাকে পূর্বানুমেয় রাখে:

  • লোকাল এবং সার্ভার ত্রুটি আলাদা রাখুন। লোকাল নিয়ম (যেমন “প্রয়োজনীয়” বা “অবৈধ ইমেল”) সার্ভার বার্তা যেমন “ইমেল ইতিমধ্যেই নেওয়া” ওভাররাইট করবে না।
  • ব্যবহারকারী যখন ফিল্ডটি আবার সম্পাদনা করে তখন serverError পরিষ্কার করুন, যাতে তারা পুরানো বার্তা দেখে আটকে না যায়।
  • touched = true সেট করুন শুধু যখন ব্যবহারকারী ফিল্ডটি ছেড়ে যায় (বা যখন আপনি সিদ্ধান্ত নেন যে তারা ইন্টারঅ্যাক্ট করার চেষ্টা করেছে), প্রথম অক্ষরে নয়।

এটি থাকলে আপনার ভিউ value-এর সাথে অবাধে বাঁধতে পারে। ভ্যালিডেশন localError আপডেট করে, এবং আপনার API স্তর serverError সেট করে, একে অপরের সাথে লড়াই না করে।

ফোকাস পরিচালনা যা গাইড করে, তিরস্কার করে না

ভালো SwiftUI ভ্যালিডেশন অনুভব করায় যেন সিস্টেম কীবোর্ড ব্যবহারকারীকে কাজটি শেষ করতে সাহায্য করছে, অ্যাপ তিরস্কার করছে না। ফোকাস এটার বড় একটা অংশ।

একটি সরল প্যাটার্ন হল @FocusState ব্যবহার করে ফোকাসকে একক সত্য উৎস হিসেবে দেখা। আপনার ফিল্ডগুলোর জন্য একটি enum সংজ্ঞায়িত করুন, প্রতিটি ফিল্ডকে বেঁধে দিন, তারপর ব্যবহারকারী কীবোর্ডের বোতাম চাপালে এগোয়।

enum Field: Hashable { case email, password, confirm }

@FocusState private var focused: Field?

TextField("Email", text: $email)
  .textContentType(.emailAddress)
  .keyboardType(.emailAddress)
  .textInputAutocapitalization(.never)
  .submitLabel(.next)
  .focused($focused, equals: .email)
  .onSubmit { focused = .password }

SecureField("Password", text: $password)
  .submitLabel(.next)
  .focused($focused, equals: .password)
  .onSubmit { focused = .confirm }

এটাকে নেটিভ-সদৃশ রাখে সংযম। কেবল স্পষ্ট ব্যবহারকারী ক্রিয়াগুলোর উপরেই ফোকাস সরান: Next, Done, অথবা প্রাইমারি বোতাম চাপা। সাবমিটে প্রথম অবৈধ ফিল্ডে ফোকাস দিন (আর প্রয়োজনে স্ক্রল করুন)। ব্যবহারকারী টাইপ করার সময় ফোকাস চুরি করবেন না, এমনকি মান বর্তমানে অবৈধ হলেও। কীবোর্ড লেবেলগুলোও ধারাবাহিক রাখুন: মধ্যবর্তী ফিল্ডগুলোর জন্য Next, শেষ ফিল্ডের জন্য Done।

একটি সাধারণ উদাহরণ হলো সাইন আপ। ব্যবহারকারী Create Account চাপান। আপনি একবার ভ্যালিডেট করবেন, ত্রুটিগুলো দেখাবেন, তারপর প্রথম ব্যর্থ ফিল্ডে (সাধারণত Email) ফোকাস দেবেন। যদি তারা Password ফিল্ডে থাকে এবং এখনও টাইপ করছে, তখন মধ্য-টাইপিং-এ তাদের Email-এ ফেরত নিয়ে যাবেন না। এই ছোট্ট অংশটাই প্রায়ই পার্থক্য গড়ে দেয় “পলিশড iOS ফর্ম” এবং “কঠোর ফর্ম” এর মধ্যে।

ইনলাইন ত্রুটি যা সঠিক সময়ে দেখা যায়

ইনলাইন ত্রুটি নীরব নির্দেশনার মত হওয়া উচিত, তিরস্কারের মত নয়। “নেটিভ” এবং “কঠোর” এর মধ্যে বড় পার্থক্যটি কখন বার্তা দেখানো হয়।

টাইমিং নিয়ম

যদি কেউ টাইপ করা শুরু করলে সঙ্গে সঙ্গে ত্রুটি দেখান, সেটা বিরক্ত করে। ভাল নিয়ম হল: ব্যবহারকারীকে পুরো ফিল্ড শেষ করার সুবর্ণ সুযোগ দিন।

ইনলাইন ত্রুটি দেখানোর ভাল মুহূর্তগুলো:

  • ফিল্ড ফোকাস ছেড়ে গেলে
  • ব্যবহারকারী Submit চাপালে
  • টাইপ করার সময় সামান্য বিরতি নিলে (শুধু স্পষ্ট চেকের জন্য, যেমন ইমেল ফরম্যাট)

একটি নির্ভরযোগ্য পদ্ধতি হল বার্তা তখনই দেখানো যখন ফিল্ডটি touched হয়েছে বা সাবমিট করা হয়েছে। নতুন ফর্ম শীতল থাকে, কিন্তু ব্যবহারকারী ইন্টারঅ্যাক্ট করলে পরিষ্কার নির্দেশনা পাবেন।

লেআউট এবং স্টাইল

কিছুই iOS-সদৃশ নয় বাকল কাটাকাটি ছাড়াই লেআউট যখন ত্রুটি দেখা যায়। বার্তাটির জায়গা সংরক্ষণ করুন, অথবা এর আপিয়ারেন্স অ্যানিমেট করুন যাতে পরের ফিল্ডটি আকস্মিকভাবে নিচে ঠেলে না দেয়।

ত্রুটি টেক্সট সংক্ষিপ্ত ও নির্দিষ্ট রাখুন, প্রতি বার্তায় একটিই ফিক্স দিন। "Password must be at least 8 characters" ব্যবহারকারীর জন্য কার্যকর, কিন্তু "Invalid input" নয়।

স্টাইলের জন্য সূক্ষ্ম ও ধারাবাহিক চেষ্টা করুন। ফিল্ডের নিচে ছোট ফন্ট (যেমন footnote), একটি ধারাবাহিক ত্রুটি রঙ, এবং ফিল্ডে নরম হাইলাইট সাধারণত ভারী ব্যাকগ্রাউন্ডের তুলনায় ভালো লাগে। মান বৈধ হয়ে গেলে বার্তাটি পরিষ্কার করুন।

বাস্তব উদাহরণ: সাইনআপ ফর্মে ব্যবহারকারী name@ টাইপ করার সময় "Email is invalid" দেখাবেন না। ফিল্ড ছেড়ে দেওয়ার পরে বা একটু বিরতির পরে দেখান, এবং ঠিকঠাক হলে তা মুছে ফেলুন।

লোকাল ভ্যালিডেশন ফ্লো: টাইপিং, ফিল্ড ত্যাগ, সাবমিট

Add cross field validation
Create field and cross-field checks with drag and drop business logic.
Build Form

ভালো লোকাল ফ্লোতে তিনটি গতি আছে: টাইপিং চলাকালীন মৃদু হিন্ট, ফিল্ড ত্যাগ করার সময় কড়া চেক, এবং সাবমিটে পূর্ণ নিয়ম। এই রিদমটাই ভ্যালিডেশনকে নেটিভ মনে করায়।

ব্যবহারকারী টাইপ করার সময় ভ্যালিডেশন হালকা ও নীরব রাখুন। চিন্তা করুন “এটা স্পষ্টত অসম্ভব কি?” না “এটা পারফেক্ট কি?” ইমেল ফিল্ডের জন্য আপনি হয়ত শুধু চেক করবেন এতে @ আছে কি এবং স্পেস নেই কি। পাসওয়ার্ডের জন্য, তারা টাইপ করা শুরু করলে একটি ছোট হেল্পার দেখাতে পারেন যেমন “8+ অক্ষর”, কিন্তু প্রথম কীস্ট্রোকেই লাল ত্রুটি দেখাবেন না।

ব্যবহারকারী ফিল্ড ছেড়ে গেলে কঠোর একক-ফিল্ড নিয়ম চালান এবং প্রয়োজনে ইনলাইন ত্রুটি দেখান। এখানে “Required” ও “Invalid format” থাকা উচিত। এটি হোয়াইটস্পেস ট্রিম করে ইনপুট নর্মালাইজ করারও একটি ভাল মুহূর্ত (যেমন ইমেলকে lowercasing করা) যাতে ব্যবহারকারী দেখে কী সাবমিট হবে।

সাবমিটে সবকিছু আবার ভ্যালিডেট করুন, ক্রস-ফিল্ড নিয়মসহ যেগুলো আগে ঠিক করতে পারিনাই। ক্লাসিক উদাহরণ হলো Password এবং Confirm Password মিলছে কি না। যদি ব্যর্থ হয়, প্রথম যে ফিল্ডটিকে ঠিক করতে হবে সেখানে ফোকাস সন্নিবেশ করান এবং তার পাশে এক পরিষ্কার বার্তা দেখান।

সাবমিট বোতাম সাবধানে ব্যবহার করুন। ব্যবহারকারী ফর্ম পূরণ করতেছেন এমন সময় এটিকে সক্রিয় রাখুন। কেবলমাত্র তখনই disable করুন যখন ট্যাপ করলেই কিছুই হবে না (উদাহরণ: ইতিমধ্যেই সাবমিটিং চলছে)। যদি আপনি ইনভ্যালিড ইনপুটের কারণে এটি disable করেন, তবুও নিকটবর্তী স্থানে কি ঠিক করতে হবে তা দেখান।

সাবমিশনের সময় স্পষ্ট লোডিং স্টেট দেখান। বোতাম লেবেলকে ProgressView দিয়ে বদলান, ডাবল ট্যাপ রোধ করুন, এবং ফর্ম দৃশ্যমান রাখুন যাতে ব্যবহারকারীরা বুঝে কী হচ্ছে। অনুরোধ এক সেকেন্ডের বেশি সময় নিলে “Creating account...” ধরনের ছোট লেবেল উদ্বেগ কমায়।

সার্ভার-সাইড ভ্যালিডেশন ব্যবহারকারীকে হতাশ না করে কিভাবে দেখাবেন

সার্ভার-সাইড চেক হলো চূড়ান্ত সত্য, এমনকি আপনার লোকাল চেক শক্ত হলে ও। পাসওয়ার্ড আপনার নিয়ম পাস করলেও সার্ভার সেটাকে খুব সাধারণ বলে নামজদ হতে পারে, বা ইমেল ইতিমধ্যেই নেওয়া থাকতে পারে।

সবচেয়ে বড় UX বিজয় হলো “আপনার ইনপুট গ্রহণযোগ্য নয়” এবং “আমরা সার্ভারে পৌঁছাতে পারিনি” আলাদা করা। যদি অনুরোধ টাইমআউট হয় বা ব্যবহারকারী অফলাইন, ফিল্ডগুলো অবৈধ হিসেবে চিহ্নিত করবেন না। একটি শান্ত ব্যানার বা এলার্ট দেখান যেমন "Couldn’t connect. Try again." এবং ফর্ম ঠিক তেমন রাখুন।

যখন সার্ভার বলে ভ্যালিডেশন ব্যর্থ হয়েছে, ব্যবহারকারীর ইনপুট অক্ষত রাখুন এবং সঠিক ফিল্ডগুলোর দিকে ইঙ্গিত করুন। ফর্ম মুছা, পাসওয়ার্ড ক্লিয়ার করা, বা ফোকাস সরিয়ে দেওয়া ব্যবহারকারীকে চেষ্টা করার জন্য শাস্তি মনে হয়।

একটি সহজ প্যাটার্ন হলো স্ট্রাকচার্ড এরর রেসপন্সকে দুটি বালতিতে পার্স করা: ফিল্ড এরর এবং ফর্ম-স্তরের এরর। তারপর আপনার UI স্টেট আপডেট করুন টেক্সট বাঁধন বদল না করে।

struct ServerValidation: Decodable {
  var fieldErrors: [String: String]
  var formError: String?
}
// Map keys like "email" or "password" to your local field IDs.

কীটি সাধারণত নেটিভ মনে হয়:

  • ফিল্ড মেসেজগুলো ইনলাইন রাখুন, ফিল্ডের নিচে, সার্ভারের লেখাকে ব্যবহার করুন যদি তা পরিষ্কার হয়।
  • সাবমিটের পরে শুধু তবেই প্রথম ত্রুটিপূর্ণ ফিল্ডে ফোকাস দিন, টাইপিংয়ের মাঝখানে নয়।
  • সার্ভার একাধিক সমস্যা দিলে, প্রতিটি ফিল্ডের জন্য প্রথমটি দেখান যাতে পড়তে সহজ হয়।
  • যদি ফিল্ড ডিটেইল থাকে, "Something went wrong."-এর মত আলটারনেটিভে ফিরে যাবেন না।

উদাহরণ: ব্যবহারকারী সাইনআপ সাবমিট করে, এবং সার্ভার ফেরত দেয় “email already in use.” ইমেল তারা টাইপ করা রেখে দিন, বার্তাটি Email-এর নিচে দেখান, এবং সেই ফিল্ডে ফোকাস দিন। যদি সার্ভার ডাউন থাকে, একটি সিঙ্গেল রিট্রাই মেসেজ দেখান এবং সব ফিল্ড অপরিবর্তিত রাখুন।

সার্ভার মেসেজগুলো সঠিক জায়গায় কিভাবে দেখাবেন

Handle server errors cleanly
Test server-side errors like email taken without wiping user input or breaking the UI.
Prototype

যখন সার্ভার বার্তা র‍্যান্ডম ব্যানারে দেখায়, তা অন্যায়বোধ দেয়। প্রতিটি মেসেজকে সম্ভব হলে যে ফিল্ডটি বিষয় তা যতটা কাছাকাছি থাক যে স্থানে দেখান। সাধারণ বার্তা কেবল তখনই ব্যবহার করুন যখন কোনো একক ইনপুটের সাথে জোড়া লাগানো যায় না।

শুরুতে সার্ভারের এরর পে-লোডকে আপনার SwiftUI ফিল্ড আইডেন্টিফায়ারগুলোর সাথে অনুবাদ করুন। ব্যাকএন্ড হয়ত email, password, বা profile.phone এর মতো কি পাঠায়, আর আপনার UI enum ব্যবহার করে থাকতে পারে যেমন Field.emailField.password। রেসপন্সের ঠিক পরেই ম্যাপিং একবার করুন, যাতে বাকি ভিউ ধারাবাহিক থাকে।

একটি নমনীয় মডেল হলো serverFieldErrors: [Field: [String]] এবং serverFormErrors: [String] রাখা। অ্যারে রাখুন যদিও সাধারণত একটি মেসেজই দেখাবেন। ইনলাইন ত্রুটি দেখালে সবচেয়ে সাহায্যকারী মেসেজটি প্রথমে দেখান। উদাহরণস্বরূপ, যদি একই সাথে “Email already in use” এবং “Invalid email” আসুক, “Email already in use” বেশি কার্যকর।

একাধিক ত্রুটি প্রতিটি ফিল্ডে সাধারণই, কিন্তু সবগুলো দেখানো শব্দাধিক্য। অধিকাংশ সময়ে শুধুমাত্র প্রথম মেসেজটি ইনলাইন দেখান এবং বাকি গুলো দরকার হলে ডিটেইল ভিউতে রাখুন।

যেগুলো কোনো ফিল্ডের সাথে জড়িত নয় (সেশন মেয়াদোত্তীর্ণ, রেট লিমিট, “Try again later”), সেগুলো সাবমিট বোতামের কাছাকাছি রাখুন যাতে ব্যবহারকারী যখন কাজ করেন তখন দেখতে পান। সফল হলে পুরাতন ত্রুটিগুলো পরিষ্কার করা নিশ্চিত করুন যাতে UI "স্টাক" মনে না হয়।

অবশেষে, ব্যবহারকারী সম্পর্কিত ফিল্ড পরিবর্তন করলে সার্ভার ত্রুটি পরিষ্কার করুন। বাস্তবে, email-এর onChange হ্যান্ডলার serverFieldErrors[.email] রিমুভ করা উচিত যাতে UI অনতঃপ্রফুল্ল ভাবে প্রতিফলিত করে, “ঠিক আছে, আপনি সেটি ঠিক করছেন।”

অ্যাক্সেসিবিলিটি ও টোন: ছোট ছোট পছন্দ যা নেটিভ মনে করায়

Build a calm signup form
Build a SwiftUI signup flow with client and server validation backed by real APIs.
Try AppMaster

ভালো ভ্যালিডেশন কেবল লজিক নয়। এটা কিভাবে পড়ে, শোনায়, এবং Dynamic Type, VoiceOver ও বিভিন্ন ভাষার সাথে কিভাবে আচরণ করে তাও।

ত্রুটিগুলো পড়তে সহজ করুন (শুধু রঙে নির্ভর না করে)

টেক্সট বড় হতে পারে বোঝে নিয়ে কাজ করুন। Dynamic Type-সংগত স্টাইল ব্যবহার করুন (যেমন .font(.footnote) বা .font(.caption)—ফিক্সড সাইজ না করে), এবং ত্রুটি লেবেলগুলিকে র‍্যাপ করতে দিন। স্পেসিং ধারাবাহিক রাখুন যাতে ত্রুটি দেখা হলে লেআউট অনেক ঝাঁপ না করে।

শুধু লাল টেক্সটে নির্ভর করবেন না। একটি পরিষ্কার আইকন, “Error:” প্রিফিক্স, বা উভয়ই যোগ করুন। এটা রঙ দৃষ্টিশক্তিহীনতার সমস্যাযুক্তদের সাহায্য করে এবং স্ক্যান করা দ্রুত করে।

দ্রুত চেকগুলো যা সাধারণত টেকসই:

  • Dynamic Type-কে সাপোর্ট করে এমন পঠনযোগ্য টেক্সট স্টাইল ব্যবহার করুন।
  • ত্রুটি বার্তাগুলোকে র‍্যাপ করতে দিন এবং ট্রানানকেশন এড়ান।
  • আইকন বা “Error:” লেবেল যোগ করুন রঙের পাশাপাশি।
  • Light ও Dark মোড উভয়েই কন্ট্রাস্ট উচ্চ রাখুন।

VoiceOver সঠিক জিনিস পড়ুক

যখন একটি ফিল্ড অবৈধ, VoiceOver-কে লেবেল, বর্তমান মান এবং ত্রুটিটি একসঙ্গে পড়তে হবে। যদি ত্রুটি ফিল্ডের নিচে আলাদা Text হয়, তা স্কিপ করা বা প্রেক্ষিতের বাইরে পড়া হতে পারে।

দুইটি প্যাটার্ন সাহায্য করে:

  • ফিল্ড ও তার ত্রুটিকে একটিভ্যাক্সেসিবিলিটি এলিমেন্টে মিলিয়ে দিন, যাতে ফোকাস করলে ত্রুটি ঘোষিত হয়।
  • অ্যাক্সেসিবিলিটি হিন্ট বা ভ্যালু সেট করুন যা ত্রুটি বার্তাটি অন্তর্ভুক্ত করে (উদাহরণ: “Password, required, must be at least 8 characters”).

টোনটাও গুরুত্বপূর্ণ। বার্তাগুলো পরিষ্কার ও সহজ লোকালাইজেবল রাখুন। স্ল্যাং, রসিকতা, বা অস্পষ্ট লাইন যেমন “Oops” এড়ান। স্পষ্ট নির্দেশ like “Email is missing” বা “Password must include a number” ব্যবহার করুন।

উদাহরণ: লোকাল ও সার্ভার নিয়ম দুটোই থাকা সাইনআপ ফর্ম

একটি সাইনআপ ফর্ম কল্পনা করুন যার তিনটি ফিল্ড আছে: Email, Password, এবং Confirm Password। লক্ষ্য হলো এমন একটি ফর্ম যা ব্যবহারকারী টাইপ করার সময় শিথিল থাকে, পরে এগোতে চেষ্টার সময় সহায়ক হয়।

ফোকাস ক্রম (Return কী কি করবে)

SwiftUI FocusState দিয়ে প্রতিটি Return কী চাপ প্রাকৃতিক ধাপের মত হওয়া উচিত।

  • Email Return: Password-এ ফোকাস সরান।
  • Password Return: Confirm Password-এ ফোকাস সরান।
  • Confirm Password Return: কীবোর্ড নামান এবং Submit চেষ্টা করুন।
  • যদি Submit ব্যর্থ হয়: প্রথম ফাঁক আছে এমন ফিল্ডে ফোকাস ফেরান।

শেষ ধাপটি জরুরি। যদি ইমেল অবৈধ হয়, ফোকাস Email-এ ফেরান, না যে কোনো লাল বার্তায় কেবল নজর দিতে।

যখন ত্রুটি প্রকাশ পায়

একটি সহজ নিয়ম UI-কে শান্ত রাখে: একটি ফিল্ড touched হলে (ব্যবহারকারী ছেড়ে দেয়) বা সাবমিট চেষ্টা হলে বার্তা দেখান।

  • Email: ছেড়ে দিলে বা Submit-এ "Enter a valid email" দেখান।
  • Password: ছেড়ে দিলে বা Submit-এ নিয়মগুলো দেখান (যেমন ন্যূনতম দৈর্ঘ্য)।
  • Confirm Password: ছেড়ে দিলে বা Submit-এ "Passwords don’t match" দেখান।

এখন সার্ভার সাইড। ধরুন ব্যবহারকারী সাবমিট করে এবং আপনার API নিম্নরূপ দেয়:

{
  "errors": {
    "email": "That email is already in use.",
    "password": "Password is too weak. Try 10+ characters."
  }
}

ব্যবহারকারী যা দেখেন: Email-এ সার্ভার বার্তাটি ঠিক নিচে দেখায়, এবং Password-এ তার বার্তাটি দেখায়। Confirm Password তখন নীরব থাকে যদি তা লোকালি সফল হয়।

তারা পরের কী করবে: ফোকাস Email-এ যাবে (প্রথম সার্ভার এরর)। তারা ইমেল পরিবর্তন করবেন, Return চাপলে Password-এ যাবেন, পাসওয়ার্ড ঠিক করবেন, এবং আবার সাবমিট করবেন। মেসেজগুলো ইনলাইন এবং ফোকাস উদ্দেশ্যপ্রণোদিত হলে ফর্মটি সহযোগিতামূলক মনে হবে, তিরস্কারী মনে হবে না।

এমন কিছু সাধারণ ভুল যা ভ্যালিডেশনকে “অন-iOS” করে তোলে

Reduce rework on changes
Keep client and server validation aligned as requirements change and the app regenerates.
Get Started

একটি ফর্ম প্রযুক্তিগতভাবে সঠিক হলেও খারাপ লাগে। বেশিরভাগ "অন-iOS" সমস্যার মূল কারণ টাইমিং: আপনি কখন ত্রুটি দেখাচ্ছেন, কখন ফোকাস সরান, এবং সার্ভারের প্রতি কিভাবে প্রতিক্রিয়া জানাচ্ছেন।

একটি সাধারণ ভুল হচ্ছে খুব আগেই বলা। যদি প্রথম কীস্ট্রোকেই ত্রুটি দেখান, মানুষ টাইপ করার সময় তিরস্কার বোধ করে। ফিল্ডটি touched হওয়া পর্যন্ত (ছেড়ে দেওয়া বা Submit চেষ্টা) অপেক্ষা করলে সাধারণত ঠিক হয়ে যায়।

অ্যাসিঙ্ক সার্ভার রেসপন্সও ফ্লো ভাঙতে পারে। যদি সাইনআপ রিকোয়েস্ট ফিরিয়ে দেয় এবং আপনি আকস্মিকভাবে ফোকাস বদলে ফেলেন, তা র‌্যান্ডম লাগে। যেখানে ব্যবহারকারী শেষ ছিল সেটাই রাখুন, এবং কেবল তখনই সরান যখন তারা Next চাপায় বা সাবমিট হ্যান্ডল করছেন।

আরেকটি ধরন হলো প্রতিটি এডিটে সবকিছু মুছে ফেলা। যেকোনো অক্ষর পরিবর্তনেই সব ত্রুটি পরিষ্কার করলে সত্যিকার সমস্যাগুলো লুকিয়ে পড়তে পারে, বিশেষত সার্ভার বার্তাগুলোর ক্ষেত্রে। কেবল সেই ফিল্ডের ত্রুটি পরিষ্কার করুন যা সম্পাদিত হচ্ছে, এবং বাকি রাখুন যতক্ষণ না সেগুলো ঠিক হয়ে যায়।

"নীরব ব্যর্থতা" সাবমিট বোতাম এড়িয়ে চলুন। Submit চিরতরে disable করে রাখা এবং কি ঠিক করতে হবে না বলা ব্যবহারকারীকে অনুমান করতে বাধ্য করে। যদি আপনি disable করেন, সেটির পাশে নির্দিষ্ট হিন্ট দিন, অথবা সাবমিট করার সুযোগ রাখুন এবং তারপর প্রথম সমস্যায় গাইড করুন।

ধীর অনুরোধ ও ডুপ্লিকেট ট্যাপ সহজেই সমস্যা করে। আপনি যদি লোডিং না দেখান ও ডাবল সাবমিট রোধ না করেন, ব্যবহারকারী দুইবার ট্যাপ করে দুইটি রেসপন্স পেতে পারেন এবং বিভ্রান্তিকর ত্রুটিতে পড়তে পারেন।

একটি দ্রুত সেনসিটি চেক:

  • ব্লার বা সাবমিট পর্যন্ত ত্রুটি দেরি করুন, প্রথম অক্ষরে নয়।
  • সার্ভার রেসপন্সে ফোকাস স্বয়ংক্রিয়ভাবে স্থানান্তর করবেন না যদি ব্যবহারকারী না চান।
  • ক্ষেত্রভিত্তিকভাবে ত্রুটি পরিষ্কার করুন, সবকিছু একসাথে নয়।
  • যদি সাবমিট ব্লক করা থাকে, ব্যাখ্যা করুন (অথবা নির্দেশনা সহ সাবমিট অনুমোদন করুন)।
  • অপেক্ষমান অবস্থায় লোড দেখান এবং অতিরিক্ত ট্যাপ উপেক্ষা করুন।

উদাহরণ: যদি সার্ভার বলে "email already in use" (সম্ভবত এমন একটি ব্যাকএন্ড থেকে যা আপনি AppMaster-এ তৈরি করেছেন), Email-এর নিচে বার্তাটি রাখুন, Password অপরিবর্তিত রাখুন, এবং ব্যবহারকারীকে পুরো ফর্ম পুনরায় শুরু করতে বাধ্য করবেন না।

দ্রুত চেকলিস্ট এবং পরবর্তী ধাপ

নেটিভ-সদৃশ ভ্যালিডেশন অভিজ্ঞতা মূলত টাইমিং ও সংযমের উপর নির্ভর করে। আপনি কঠোর নিয়ম রাখতে পারেন এবং তবুও পর্দা শান্ত রাখার অনুভূতি দিতে পারেন।

পণ্য পরীক্ষার আগে পরীক্ষা করুন:

  • সঠিক সময়ে ভ্যালিডেট করুন। প্রথম কীস্ট্রোকেই ত্রুটি দেখাবেন না যদি তা স্পষ্টভাবে সহায়ক না হয়।
  • উদ্দেশ্যপ্রণোদিতভাবে ফোকাস সরান। সাবমিটে প্রথম অবৈধ ফিল্ডে ঝাঁপ দিন এবং কি সমস্যা তা স্পষ্ট করে বলুন।
  • শব্দভাণ্ডার সংক্ষিপ্ত ও নির্দিষ্ট রাখুন। পরামর্শ দিন কী করতে হবে, না কি ভুল হয়েছে।
  • লোডিং ও রিট্রাই সম্মান করুন। পাঠানো সময় Submit disable করুন এবং অনুরোধ ব্যর্থ হলে টাইপ করা মান রাখুন।
  • সার্ভার ত্রুটিকে সম্ভব হলে ফিল্ড প্রতিক্রিয়ায় পরিণত করুন। সার্ভার কোডকে একটি ফিল্ডে ম্যাপ করুন, এবং কেবল সত্যিই গ্লোবাল সমস্যার জন্য একটি টপ মেসেজ ব্যবহার করুন।

তারপর বাস্তব মানুষ হিসেবে টেস্ট করুন। একটি ছোট ফোন এক হাতে ধরুন এবং আপনার বুড়ো আঙুল দিয়ে ফর্মটি পূরণের চেষ্টা করুন। তারপর VoiceOver চালু করে দেখুন ফোকাস ক্রম, ত্রুটি ঘোষণা এবং বোতাম লেবেল সব ঠিক আছে কি না।

ডিবাগ ও সাপোর্টের জন্য, সার্ভার ভ্যালিডেশন কোডগুলি (خام মেসেজ নয়) স্ক্রিন ও ফিল্ড নামের সাথে লগ করা ভালো। যখন একজন ব্যবহারকারী বলবে “আবেদন করতে পারছিনা”, আপনি দ্রুত বলতে পারবেন এটা ছিল email_taken, weak_password, না নেটওয়ার্ক টাইমআউট।

এই রীতি বজায় রাখতে, আপনার ফিল্ড মডেল স্ট্যান্ডার্ডাইজ করুন (value, touched, local error, server error), ত্রুটি স্থাপন ও ফোকাস নিয়ম। যদি আপনি প্রতিটি স্ক্রিন নিজে করে তুলতে না চান, AppMaster (appmaster.io) SwiftUI অ্যাপ এবং ব্যাকএন্ড সার্ভিস উভয় জেনারেট করতে পারে, যা ক্লায়েন্ট ও সার্ভার ভ্যালিডেশন নিয়মগুলো সমন্বয় করা সহজ করে।

শুরু করা সহজ
কিছু আশ্চর্যজনকতৈরি করুন

বিনামূল্যের পরিকল্পনা সহ অ্যাপমাস্টারের সাথে পরীক্ষা করুন।
আপনি যখন প্রস্তুত হবেন তখন আপনি সঠিক সদস্যতা বেছে নিতে পারেন৷

এবার শুরু করা যাক