ਮੋਬਾਇਲ ਪ੍ਰੋਜੈਕਟਾਂ ਵਿੱਚ ਅਖੀਰਲੇ ਸਮੇਂ ਦੀਆਂ ਹੈਰਾਨੀਆਂ ਤੋਂ ਬਚੋ: Flutter vibe ਕੋਡਿੰਗ ਗਲਤੀਆਂ ਸਮਝੋ ਅਤੇ ਨੈਵੀਗੇਸ਼ਨ, API, ਫਾਰਮ, ਪਰਮਿਸ਼ਨ ਅਤੇ ਰਿਲੀਜ਼ ਬਿਲਡ ਲਈ ਹੱਲ ਪਾਉ।

Vibe coding ਤੁਹਾਨੂੰ ਇੱਕ ਕਲਿਕ ਕਰਨਯੋਗ Flutter ਡੈਮੋ ਤੁਰੰਤ ਦੇ ਸਕਦਾ ਹੈ। Koder.ai ਵਰਗਾ ਟੂਲ ਸਧਾਰਨ ਚੈਟ ਤੋਂ ਸਕ੍ਰੀਨਾਂ, ਫਲੋ ਅਤੇ ਪਿੱਛੇ-ਅੰਤ ਦੀ ਵਾਇਰਿੰਗ ਤੱਕ ਜਨਰੇਟ ਕਰ ਸਕਦਾ ਹੈ। ਪਰ ਇਹ ਬਦਲ ਨਹੀਂ ਸਕਦਾ ਕਿ ਮੋਬਾਇਲ ਐਪ ਨੈਵੀਗੇਸ਼ਨ, ਸਟੇਟ, ਪਰਮਿਸ਼ਨ ਅਤੇ ਰਿਲੀਜ਼ ਬਿਲਡਾਂ ਬਾਰੇ ਕਿੰਨੇ ਨਿਯਮਤ ਹਨ। ਫੋਨ ਹਜੇ ਵੀ ਅਸਲ ਹਾਰਡਵੇਅਰ, OS ਨਿਯਮ ਅਤੇ ਸਟੋਰ ਦੀਆਂ ਲੋੜਾਂ 'ਤੇ ਚੱਲਦੇ ਹਨ।
ਕਈ ਸਮੱਸਿਆਵਾਂ ਦੇਰ ਨਾਲ ਵੱਖ-ਵੱਖ ਇਸ ਲਈ ਆਉਂਦੀਆਂ ਹਨ ਕਿਉਂਕਿ ਤੁਸੀਂ ਉਨ੍ਹਾਂ ਨੂੰ ਸਿਰਫ ਖੁਸ਼ ਰਾਹ (happy path) ਛੱਡਣ ਸਮੇਂ ਹੀ ਨੋਟਿਸ ਕਰਦੇ ਹੋ। ਸਿਮੂਲੇਟਰ ਇੱਕ ਘੱਟ-ਕੋਐਲਟੀ Android ਡਿਵਾਈਸ ਵਰਗਾ ਨਹੀਂ ਹੋ ਸਕਦਾ। ਡੀਬੱਗ ਬਿਲਡ ਟਾਈਮਿੰਗ ਦੀਆਂ ਸਮੱਸਿਆਵਾਂ ਨੂੰ ਛੁپا ਸਕਦਾ ਹੈ। ਅਤੇ ਇੱਕ ਫੀਚਰ ਜੋ ਇੱਕ ਸਕ੍ਰੀਨ 'ਤੇ ਠੀਕ ਲੱਗਦਾ ਹੈ, ਵਾਪਸ ਜਾਓ ਤਾਂ, ਨੈੱਟਵਰਕ ਖੋ ਗਿਆ ਜਾਂ ਡਿਵਾਈਸ ਰੋਟੇਟ ਹੋ ਜਾਣ 'ਤੇ ਟੁੱਟ ਸਕਦਾ ਹੈ।
ਦਰਅਸਲ ਦੇਰ ਨਾਲ ਆਉਣ ਵਾਲੀਆਂ ਹੈਰਾਨੀਆਂ ਆਮ ਤੌਰ 'ਤੇ ਕੁਝ ਸ਼੍ਰੇਣੀਆਂ ਵਿੱਚ ਆਉਂਦੀਆਂ ਹਨ, ਅਤੇ ਹਰ ਇਕ ਦੀ ਇੱਕ ਪਛਾਣਯੋਗ ਲક્ષણ ਹੁੰਦੀ ਹੈ:
ਇੱਕ ਤੇਜ਼ ਮਾਨਸਿਕ ਮਾਡਲ ਮਦਦ ਕਰਦਾ ਹੈ। ਇੱਕ ਡੈਮੋ "ਇੱਕ ਵਾਰੀ ਚੱਲਦਾ ਹੈ"। ਇੱਕ ਸ਼ਿੱਪ ਕਰਨਯੋਗ ਐਪ "ਗੰਦਗੀ ਵਾਲੀ ਅਸਲ ਜ਼ਿੰਦਗੀ ਵਿੱਚ ਵੀ ਕੰਮ ਕਰਦਾ ਰਹਿੰਦਾ ਹੈ"। "ਹੋ ਗਿਆ" ਆਮ ਤੌਰ 'ਤੇ ਇਹਨਾਂ ਤੋਂ ਸਬ True:
ਜ਼ਿਆਦਾਤਰ "ਕੱਲ੍ਹ ਚੱਲਦਾ ਸੀ" ਵਾਲੇ ਪਲ ਉਹ ਹਨ ਕਿਉਂਕਿ ਪ੍ਰੋਜੈਕਟ ਕੋਲ ਸਾਂਝੇ ਨਿਯਮ ਨਹੀਂ ਹੁੰਦੇ। Vibe coding ਨਾਲ ਤੁਸੀਂ ਬਹੁਤ ਕੁਝ ਤੇਜ਼ੀ ਨਾਲ ਜਨਰੇਟ ਕਰ ਸਕਦੇ ਹੋ, ਪਰ ਤੁਹਾਨੂੰ ਫਿਰ ਵੀ ਇੱਕ ਛੋਟਾ ਫਰੇਮ ਚਾਹੀਦਾ ਹੈ ਤਾਂ ਜੋ ਟੁਕੜੇ ਇਕੱਠੇ ਫਿੱਟ ਹੋ ਜਾਣ। ਇਹ ਸੈਟਅਪ ਤੇਜ਼ੀ ਨੂੰ ਬਰਕਰਾਰ ਰੱਖਦਾ ਹੈ ਅਤੇ ਦੇਰ-ਵਾਲੀਆਂ ਸਮੱਸਿਆਵਾਂ ਘਟਾਉਂਦਾ ਹੈ।
ਇੱਕ ਸਧਾਰਣ ਢਾਂਚਾ ਚੁਣੋ ਅਤੇ ਉਸ 'ਤੇ ਟਿਕੇ ਰਹੋ। ਇਹ ਫੈਸਲਾ ਕਰੋ ਕਿ ਕੀ ਗਿਣਿਆ ਜਾਵੇਗਾ ਇਕ ਸਕ੍ਰੀਨ ਵਜੋਂ, ਨੈਵੀਗੇਸ਼ਨ ਕਿੱਥੇ ਰਹੇਗੀ, ਅਤੇ ਸਟੇਟ ਕਿਸ ਦਾ ਹੋਏਗਾ। ਇਕ ਵ੍ਹਾਇਕਲ ਡਿਫਾਲਟ: ਸਕ੍ਰੀਨ ਪਤਲੇ ਰਹਿਣ, ਸਟੇਟ ਫੀਚਰ-ਲੇਵਲ ਕੰਟਰੋਲਰ ਕੋਲ ਹੋਵੇ, ਅਤੇ ਡਾਟਾ ਐਕਸੈਸ ਇੱਕ ਡਾਟਾ ਲੇਅਰ (ਰਿਪੋਜ਼ਟਰੀ ਜਾਂ ਸਰਵਿਸ) ਰਾਹੀਂ ਜਾਵੇ।
ਕੁਝ ਕਨਵੈਨਸ਼ਨ ਜਲਦੀ ਲਾਕ ਕਰੋ। ਫੋਲਡਰ ਨਾਮ, ਫਾਈਲ ਨੈਮਿੰਗ ਅਤੇ ਗਲਤੀਆਂ ਕਿਵੇਂ ਦਿਖਾਈਆਂ ਜਾਣ ਇਸ 'ਤੇ ਸਮਝੋ। ਏਕ async ਲੋਡਿੰਗ ਪੈਟਰਨ (loading, success, error) ਲਈ ਇਕ ਪੈਟਰਨ ਫੈਸਲਾ ਕਰੋ ਤਾਂ ਕਿ ਸਕ੍ਰੀਨ ਇੱਕਸਾਰ ਵਰਤਣ।
ਹਰ ਫੀਚਰ ਨਾਲ ਛੋਟੀ ਟੈਸਟ ਪਲਾਨ ਸ਼ਾਮਲ ਕਰੋ। ਚੈਟ-ਜਨਰੇਟ ਕੀਤੇ ਫੀਚਰ ਨੂੰ ਸਵੀਕਾਰ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਤਿੰਨ ਚੈੱਕ ਲਿਖੋ: ਹੈਪੀ ਪਾਥ ਅਤੇ ਦੋ ਏਜ ਕੇਸ। ਉਦਾਹਰਣ: “login ਕੰਮ ਕਰਦਾ”, “ਗਲਤ ਪਾਸਵਰਡ ਸੁਨੇਹਾ ਦਿਖਦਾ”, “ਆਫਲਾਈਨ ਰੀਟ੍ਰਾਈ ਦਿਖਾਉਂਦਾ”। ਇਹ ਉਹ ਸਮੱਸਿਆਵਾਂ ਪਕੜਦਾ ਹੈ ਜੋ ਸਿਰਫ ਅਸਲ ਡਿਵਾਈਸ 'ਤੇ ਨਜ਼ਰ ਆਉਂਦੀਆਂ ਨੇ।
ਹੁਣ ਲਾਗਿੰਗ ਅਤੇ ਕਰੈਸ਼ ਰਿਪੋਰਟਿੰਗ ਪਲੇਸਹੋਲਡਰ ਜੋੜੋ। ਭਾਵੇਂ ਤੁਸੀਂ ਅਜੇ ਉਨ੍ਹਾਂ ਨੂੰ ਚਾਲੂ ਨਾ ਕਰੋ, ਇੱਕ ਲਾਗਿੰਗ ਐਂਟਰੀ ਪੌਇੰਟ ਬਣਾਓ (ਤਾਂ ਜੋ ਤੁਸੀਂ ਬਾਅਦ ਵਿੱਚ ਪ੍ਰੋਵਾਈਡਰ ਬਦਲ ਸਕੋ) ਅਤੇ ਇੱਕ ਸਥਾਨ ਜਿੱਥੇ ਅਣਕੈਚ ਕੀਤੀਆਂ ਗਲਤੀਆਂ ਦਰਜ ਹੋਣ। ਜਦੋਂ ਕਿਸੇ ਬੀਟਾ ਯੂਜ਼ਰ ਤੋਂ ਕਰੈਸ਼ ਰਿਪੋਰਟ ਆਏਗੀ, ਤੁਹਾਨੂੰ ਟਰੇਲ ਚਾਹੀਦੀ ਹੋਵੇਗੀ।
ਇੱਕ ਜਿੰਦੇ "ਸ਼ਿਪ ਕਰਨ ਲਈ ਤਿਆਰ" ਨੋਟ ਰੱਖੋ। ਹਰ ਰਿਲੀਜ਼ ਤੋਂ ਪਹਿਲਾਂ ਤੁਸੀਂ ਜੋ ਸਮੀਖਿਆ ਕਰਦੇ ਹੋ ਉਸ ਲਈ ਇੱਕ ਛੋਟਾ ਪੇਜ਼ ਪੈਨ ਕਰੋ, ਇਹ ਆਖਰੀ-ਮਿੰਟ ਪੈਨਿਕ ਰੋਕਦਾ ਹੈ।
ਜੇ ਤੁਸੀਂ Koder.ai ਨਾਲ ਬਿਲਡ ਕਰ ਰਹੇ ਹੋ, ਤਾਂ ਪਹਿਲਾਂ ਪ੍ਰਾਇਮਰੀ ਫੋਲਡਰ ਢਾਂਚਾ, ਸਾਂਝਾ ਐਰਰ ਮਾਡਲ ਅਤੇ ਇੱਕ ਸਿੰਗਲ ਲਾਗਿੰਗ ਰੈਪਰ ਜਨਰੇਟ ਕਰਨ ਲਈ ਆਗਿਆ ਦਿਓ। ਫਿਰ ਉਸ ਫਰੇਮ ਦੇ ਅੰਦਰ ਫੀਚਰ ਜਨਰੇਟ ਕਰੋ ਬਜਾਏ ਹਰ ਸਕ੍ਰੀਨ ਨੂੰ ਆਪਣਾ ਤਰੀਕਾ ਖੋਜਣ ਦੇ।
ਇੱਕ ਚੈੱਕਲਿਸਟ ਵਰਤੋ ਜੋ ਤੁਸੀਂ ਅਸਲ ਵਿੱਚ ਮੰਨ ਸਕੋ:
ਇਹ ਪ੍ਰਸ਼ਾਸਕੀ ਕੰਮ ਨਹੀਂ ਹੈ। ਇਹ ਇੱਕ ਛੋਟੀ ਸਮਝੌਤਾ ਹੈ ਜੋ ਚੈਟ-ਜਨਰੇਟ ਕੀਤੇ ਕੋਡ ਨੂੰ "ਵੱਖ-ਵੱਖ ਇੱਕ-ਵਾਰੀ ਸਕ੍ਰੀਨ" ਬਣਨ ਤੋਂ ਰੋਕਦੀ ਹੈ।
ਨੈਵੀਗੇਸ਼ਨ ਬੱਗ ਅਕਸਰ ਹੈਪੀ-ਪਾਥ ਡੈਮੋ ਵਿੱਚ ਛੁਪੇ ਹੋਏ ਹੁੰਦੇ ਹਨ। ਇੱਕ ਅਸਲ ਡਿਵਾਈਸ ਬੈਕ ਜੈਸਚਰ, ਰੋਟੇਸ਼ਨ, ਐਪ ਰੀਜਿਊਮ ਅਤੇ ਧੀਮੀ ਨੈੱਟਵਰਕ ਜੋੜਦਾ ਹੈ, ਅਤੇ ਅਚਾਨਕ ਤੁਸੀਂ ਏਸੇਰਾਂ ਦੇਖਦੇ ਹੋ ਜਿਵੇਂ “setState() called after dispose()” ਜਾਂ "Looking up a deactivated widget’s ancestor is unsafe." ਇਹ ਸਮੱਸਿਆਵਾਂ ਚੈਟ-ਬਿਲਟ ਫਲੋਜ਼ ਵਿੱਚ ਆਮ ਹਨ ਕਿਉਂਕਿ ਐਪ ਸਕ੍ਰੀਨ-ਦਰ-ਸਕ੍ਰੀਨ ਵਧਦਾ ਹੈ, ਨਾ ਕਿ ਇੱਕ ਯੋਜਨਾ ਦੇ ਤਹਿਤ।
ਇੱਕ ਕਲਾਸਿਕ ਸਮੱਸਿਆ ਹੈ ਕਿ ਇੱਕ ਅਜਿਹਾ context ਨਾਲ ਨੈਵੀਗੇਟ ਕਰਨਾ ਜੋ ਹੁਣ ਮਾਨਣਯੋਗ ਨਹੀਂ ਹੈ। ਇਹ ਉਸ ਵੇਲੇ ਹੁੰਦਾ ਹੈ ਜਦੋਂ ਤੁਸੀਂ Navigator.of(context) ਕਾਲ ਕਰਦੇ ਹੋ ਕਿਸੇ async ਅਨੁਰੋਧ ਤੋਂ ਬਾਅਦ, ਪਰ ਯੂਜ਼ਰ ਪਹਿਲਾਂ ਹੀ ਸਕ੍ਰੀਨ ਛੱਡ ਚੁੱਕਾ ਹੁੰਦਾ ਹੈ, ਜਾਂ OS ਨੇ ਰੋਟੇਸ਼ਨ ਦੇ ਬਾਅਦ ਵਿਜੇਟ ਨੂੰ ਦੁਬਾਰਾ ਬਣਾਇਆ ਹੋਇਆ ਹੁੰਦਾ ਹੈ।
ਹੋਰ ਇੱਕ ਹੈ "ਇੱਕ ਸਕ੍ਰੀਨ 'ਤੇ ਚੱਲਦਾ ਹੈ" ਵਾਪਸੀ ਵਰਤ_behavior। Android ਦਾ ਬੈਕ ਬਟਨ, iOS ਦਾ ਬੈਕ ਸਵਾਈਪ ਅਤੇ ਸਿਸਟਮ ਬੈਕ ਜੈਸਚਰ ਵੱਖ-ਵੱਖ ਤਰੀਕੇ ਨਾਲ ਵਿਹੜਨ ਕਰ ਸਕਦੇ ਹਨ, ਖਾਸ ਕਰਕੇ ਜਦੋਂ ਤੁਸੀਂ ਡਾਇਲਾਗ, ਨੇਸਟਡ ਨੈਵੀਗੇਟਰ (ਟੈਬ), ਅਤੇ ਕਸਟਮ ਰੂਟ ਟਰਾਂਜ਼ਿਸ਼ਨ ਮਿਲਾ ਦੇਓ।
ਡੀਪ ਲਿੰਕ ਹੋਰ ਇਕ ਮੁੜ-ਮਸਲਾ ਲਿਆਉਦਾ ਹੈ। ਐਪ ਸਿੱਧਾ ਕਿਸੇ ਡੀਟੇਲ ਸਕ੍ਰੀਨ ਵਿੱਚ ਖੁਲ ਸਕਦੀ ਹੈ, ਪਰ ਤੁਹਾਡਾ ਕੋਡ ਅਜੇ ਵੀ ਮੰਨਦਾ ਹੈ ਕਿ ਯੂਜ਼ਰ ਘਰ ਤੋਂ ਆਇਆ ਸੀ। ਫਿਰ "ਬੈਕ" ਉਨ੍ਹਾਂ ਨੂੰ ਇੱਕ ਖਾਲੀ ਪੇਜ 'ਤੇ ਲੈ ਜਾਂਦਾ ਹੈ, ਜਾਂ ਐਪ ਨੂੰ ਬੰਦ ਕਰ ਦਿੰਦਾ ਹੈ ਜਦੋਂ ਯੂਜ਼ਰ ਉਮੀਦ ਕਰਦੇ ਹਨ ਕਿ ਉਹ ਇੱਕ ਲਿਸਟ ਵੇਖਣਗੇ।
ਇੱਕ ਨੈਵੀਗੇਸ਼ਨ ਤਰੀਕੇ ਨੂੰ ਚੁਣੋ ਅਤੇ ਉਸ 'ਤੇ ਟਿਕੇ ਰਹੋ। ਸਭ ਤੋਂ ਵੱਡੀ ਸਮੱਸਿਆ ਮਿਲਾਓਣ ਵਾਲੇ ਪੈਟਰਨ ਹਨ: ਕੁਝ ਸਕ੍ਰੀਨ ਨਾਮਿਤ ਰੂਟ ਵਰਤਦੇ ਹਨ, ਹੋਰ ਡਾਇਰੈਕਟ ਵਿੱਜੇਟ push ਕਰਦੇ ਹਨ, ਹੋਰ ਮੈਨੁਅਲੀ ਸਟੈਕਾਂ ਨੂੰ ਮੈਨੇਜ ਕਰਦੇ ਹਨ। ਇਹ ਫੈਸਲਾ ਕਰੋ ਕਿ ਰੂਟਾਂ ਕਿਵੇਂ ਬਣਦੀਆਂ ਹਨ ਅਤੇ ਕੁਝ ਨਿਯਮ ਲਿਖੋ ਤਾਂ ਕਿ ਹਰ ਨਵੀਂ ਸਕ੍ਰੀਨ ਉਹੀ ਮਾਡਲ ਫੋਲੋ ਕਰੇ।
Async ਨੈਵੀਗੇਸ਼ਨ ਨੂੰ ਸੁਰੱਖਿਅਤ ਬਣਾਓ। ਕਿਸੇ ਵੀ awaited ਕਾਲ ਤੋਂ ਬਾਅਦ ਜੋ ਸਕਰੀਨ ਤੋਂ ਲੰਬਾ ਜੀਉਂਦੀ ਹੋ ਸਕਦੀ ਹੈ (login, payment, upload), ਸਕ੍ਰੀਨ ਅਜੇ ਵੀ ਜ਼ਿੰਦਾ ਹੈ ਜਾਂ ਨਹੀਂ ਇਹ ਪੁਸ਼ਟੀ ਕਰੋ ਪਹਿਲਾਂ ਕਿ state ਅਪਡੇਟ ਕਰੋ ਜਾਂ ਨੈਵੀਗੇਟ ਕਰੋ।
ਫਾਇਦੇ ਦੇਣ ਵਾਲੇ ਗਾਰਡਰੇਲਸ:
await, use if (!context.mounted) return; before setState or navigationdispose()BuildContext for later use (pass data, not context)push, pushReplacement, and pop for each flow (login, onboarding, checkout)ਸਟੇਟ ਲਈ, ਉਹ ਮੁੱਲ ਵੇਖੋ ਜੋ ਰੀਬਿਲਡ ਤੇ ਰੀਸੈੱਟ ਹੁੰਦੇ ਹਨ (ਰੋਟੇਸ਼ਨ, ਥੀਮ ਚੇੰਜ, ਕੀਬੋਰਡ ਖੁਲ/ਬੰਦ)। ਜੇ ਕਿਸੇ ਫਾਰਮ, ਚੁਣਿਆ ਟੈਬ, ਜਾਂ ਸਕ੍ਰੋਲ ਪੋਜ਼ੀਸ਼ਨ ਦੀ ਮਹੱਤਤਾ ਹੈ, ਤਾਂ ਇਹ ਕੁਝ ਥਾਂ ਸਟੋਰ ਕਰੋ ਜੋ ਰੀਬਿਲਡਸ ਤੋਂ ਬਚਦਾ ਹੈ, ਸਿਰਫ਼ ਲੋਕਲ ਵੇਰੀਏਬਲ 'ਚ ਨਹੀਂ।
ਅਕਸਰ ਕਹਿੰਦੇ ਹਨ ਕਿ ਇੱਕ ਫਲੋ "ਡਨ" ਹੋਣ ਤੋਂ ਪਹਿਲਾਂ, ਇੱਕ ਛੋਟੀ ਅਸਲ-ਡਿਵਾਈਸ ਪੈਸ ਚਲਾਓ:
ਜੇ ਤੁਸੀਂ Koder.ai ਜਾਂ ਕਿਸੇ ਵੀ ਚੈਟ-ਡਰਾਇਵਨ ਵਰਕਫ਼ਲੋ ਨਾਲ Flutter ਐਪ ਬਣਾਉਂਦੇ ਹੋ, ਤਾਂ ਇਹ ਚੈੱਕ ਸ਼ੁਰੂ ਵਿੱਚ ਕਰੋ ਜਦ ਨੈਵੀਗੇਸ਼ਨ ਨਿਯਮ ਅਜੇ ਵੀ ਆਸਾਨੀ ਨਾਲ ਲਾਗੂ ਕੀਤੇ ਜਾ ਸਕਦੇ ਹਨ।
ਇੱਕ ਆਮ ਦੇਰ-ਟੁੱਟਣ ਵਾਲੀ ਗਲਤੀ ਇਹ ਹੁੰਦੀ ਹੈ ਕਿ ਹਰ ਸਕ੍ਰੀਨ ਬੈਕਐਂਡ ਨਾਲ ਥੋੜ੍ਹਾ ਵੱਖਰਾ ਤਰੀਕਾ ਨਾਲ ਗੱਲ ਕਰਦਾ ਹੈ। Vibe coding ਨਾਲ ਇਹ ਅਚਾਨਕ ਹੋ ਸਕਦਾ ਹੈ: ਤੁਸੀਂ ਇੱਕ ਸਕ੍ਰੀਨ 'ਤੇ “quick login call” ਮੰਗਦੇ ਹੋ, ਫਿਰ ਦੂਜੇ 'ਤੇ “fetch profile” ਅਤੇ ਤੁਹਾਡੇ ਕੋਲ ਦੋ ਜਾਂ ਤਿੰਨ HTTP ਸੈਟਅਪ ਹੋ ਜਾਂਦੇ ਹਨ ਜੋ ਮੇਲ ਨਹੀਂ ਖਾਂਦੇ।
ਇੱਕ ਸਕ੍ਰੀਨ ਚੱਲਦੀ ਹੈ ਕਿਉਂਕਿ ਉਹ ਸਹੀ base URL ਅਤੇ headers ਵਰਤਦਾ ਹੈ। ਹੋਰ ਇੱਕ ਅਸਫਲ ਹੋ ਜਾਂਦਾ ਹੈ ਕਿਉਂਕਿ ਉਹ staging ਵੱਲ ਇਸ਼ਾਰਾ ਕਰਦਾ ਹੈ, header ਭੁੱਲ ਜਾਂਦਾ ਹੈ, ਜਾਂ token ਵੱਖਰੇ ਫਾਰਮੈਟ ਵਿੱਚ ਭੇਜਦਾ ਹੈ। ਬੱਗ ਰੈਂਡਮ ਲੱਗਦਾ ਹੈ, ਪਰ ਆਮ ਤੌਰ 'ਤੇ ਇਹ ਅਸੰਗਤਤਾ ਹੁੰਦੀ ਹੈ।
ਇਹ ਮੁੜ-ਮੁੜ ਨਜ਼ਰ ਆਉਂਦੀਆਂ ਹਨ:
ਇੱਕ ਸਿੰਗਲ API client ਬਣਾਓ ਅਤੇ ਹਰ ਫੀਚਰ ਨੂੰ ਉਹੀ ਵਰਤਣ ਲਈ ਪਾਬੰਦ ਕਰੋ। ਉਹ client base URL, headers, auth token storage, refresh flow, retries (ਜੇ ਹਨ) ਅਤੇ request logging ਦਾ ਮਾਲਕ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ।
Refresh ਲੋਜਿਕ ਇੱਕ ਥਾਂ ਰੱਖੋ ਤਾਂ ਜੋ ਤੁਸੀਂ ਇਸ ਬਾਰੇ ਸੋਚ ਸਕੋ। ਜੇ ਕਿਸੇ request ਨੂੰ 401 ਮਿਲਦੀ ਹੈ, ਇੱਕ ਵਾਰੀ refresh ਕਰੋ, ਫਿਰ request ਨੂੰ ਇੱਕ ਵਾਰੀ ਮੁੜ ਚਲਾਓ। ਜੇ refresh ਫੇਲ ਹੋ ਜਾਂਦਾ ਹੈ, logout ਕਰੋ ਅਤੇ ਸਪਸ਼ਟ ਸੁਨੇਹਾ ਦਿਖਾਓ।
Typed models ਉਮੀਦ ਤੋਂ ਜ਼ਿਆਦਾ ਮਦਦਗਾਰ ਹਨ। सफलता ਅਤੇ error responses ਲਈ ਮਾਡਲ define ਕਰੋ ਤਾਂ ਜੋ ਤੁਸੀਂ ਸਰਵਰ ਨੇ ਕੀ ਭੇਜਿਆ ਉਸ ਬਾਰੇ guess ਨਾ ਕਰੋ। ਗਲਤੀਆਂ ਨੂੰ 앱-ਲੇਵਲ ਨਤੀਜਿਆਂ (unauthorized, validation error, server error, no network) ਦੇ ਛੋਟੇ ਸੈੱਟ ਵਿੱਚ ਮੈਪ ਕਰੋ ਤਾਂ ਜੋ ਹਰ ਸਕ੍ਰੀਨ ਇਕਸਾਰ ਵਰਤੋਂ।
ਲਾਗਿੰਗ ਲਈ, method, path, status code, ਅਤੇ ਇੱਕ request ID ਦਰਜ ਕਰੋ। ਕਦੇ ਵੀ tokens, cookies, ਜਾਂ ਪੂਰੇ payloads ਜਿਹੜੇ passwords ਜਾਂ card data ਰੱਖਦੇ ਹਨ ਲੌਗ ਨਾ ਕਰੋ। ਜੇ ਤੁਹਾਨੂੰ body logs ਦੀ ਲੋੜ ਹੈ, ਤਾਂ "password" ਅਤੇ "authorization" ਜਿਹੇ ਫੀਲਡਾਂ ਨੂੰ ਰੀਡੈਕਟ ਕਰੋ।
ਉਦਾਹਰਨ: ਇੱਕ signup ਸਕ੍ਰੀਨ ਸਫਲ ਹੋ ਜਾਂਦੀ ਹੈ, ਪਰ "edit profile" 401 ਲੂਪ ਨਾਲ ਫੇਲ ਹੁੰਦਾ ਹੈ। Signup ਨੇ Authorization: Bearer <token> ਵਰਤਿਆ, ਜਦਕਿ profile ਨੇ token= <token> query param ਵਜੋਂ ਭੇਜਿਆ। ਇੱਕ ਸਾਂਝਾ client ਨਾਲ, ਇਹ মিল ਨਹੀਂ ਸਕਦੀ, ਅਤੇ ਡੀਬੱਗਿੰਗ ਇੱਕ request ID ਨੂੰ ਇੱਕ ਕੋਡ ਪਾਥ ਨਾਲ ਮੈਚ ਕਰਨ ਵਰਗੀ ਸਾਡੇ ਲਈ ਸਧਾਰਨ ਹੋ ਜਾਂਦੀ ਹੈ।
ਅਸਲੀ ਦੁਨੀਆ ਦੀਆਂ ਬਹੁਤ ਸਾਰੀਆਂ ناکਾਮੀਆਂ ਫਾਰਮਾਂ ਦੇ ਅੰਦਰ ਹੁੰਦੀਆਂ ਹਨ। ਫਾਰਮ ਡੈਮੋ ਵਿੱਚ ਠੀਕ ਲੱਗਦੇ ਹਨ ਪਰ ਅਸਲ ਯੂਜ਼ਰ ਇਨਪੁਟ ਹੇਠਾਂ ਫੇਲ ਹੋ ਜਾਂਦੇ ਹਨ। ਨਤੀਜਾ ਮਹਿੰਗਾ ਹੁੰਦਾ ਹੈ: ਸਾਈਨਅਪ ਜਿਹੜੇ ਕਦੇ ਪੂਰੇ ਨਹੀਂ ਹੁੰਦੇ, ਐਡਰੈੱਸ ਫੀਲਡ ਚੈੱਕਆਉਟ ਨੂੰ ਰੋਕ ਦਿੰਦੇ ਹਨ, ਭੁਗਤਾਨ ਅਸਪਸ਼ਟ ਗਲਤੀਆਂ ਨਾਲ ਫੇਲ ਹੋ ਜਾਂਦੇ ਹਨ।
ਸਭ ਤੋਂ ਆਮ ਸਮੱਸਿਆ ਐਪ ਨਿਯਮਾਂ ਅਤੇ ਬੈਕਐਂਡ ਨਿਯਮਾਂ ਵਿਚਕਾਰ ਅਸਮਰਥਾ ਹੈ। UI 3-ਕੈਰੈਕਟਰ ਪਾਸਵਰਡ ਆਦਿ ਦੀ ਆਗਿਆ ਦੇ ਸਕਦਾ ਹੈ, ਫੋਨ ਨੰਬਰ ਸਪੇਸ ਦੇ ਨਾਲ ਕਬੂਲ ਕਰ ਲੈਂਦਾ ਹੈ, ਜਾਂ ਇੱਕ ਵਿਕਲਪਿਕ ਫੀਲਡ ਨੂੰ ਲਾਜ਼ਮੀ ਮੰਨ ਲੈਂਦਾ ਹੈ, ਫਿਰ ਸਰਵਰ ਉਸਨੂੰ رد ਕਰਦਾ ਹੈ। ਯੂਜ਼ਰਾਂ ਨੂੰ صرف "ਕੁਝ ਗਲਤ ਹੋ ਗਿਆ" ਦਿਖਾਈ ਦਿੰਦਾ ਹੈ, ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰਦੇ ਹਨ, ਅਤੇ ਅਖੀਰਕਾਰ ਛੱਡ ਦਿੰਦੇ ਹਨ।
ਵੈਧਤਾ ਨੂੰ ਇੱਕ ਛੋਟੇ ਠੇਕੇ ਵਜੋਂ ਨਿਭਾਓ ਜੋ ਐਪ ਭਰ ਵਿੱਚ ਸਾਂਝਾ ਹੋਵੇ। ਜੇ ਤੁਸੀਂ ਚੈਟ ਰਾਹੀਂ ਸਕ੍ਰੀਨ ਜਨਰੇਟ ਕਰ ਰਹੇ ਹੋ (Koder.ai ਸਮੇਤ), ਤਾਂ ਵਾਰ-ਵਾਰ ਪੁੱਛੋ: ਬੈਕਐਂਡ ਸੀਮਾਵਾਂ ਬਾਰੇ ਸਪੱਸ਼ਟ ਹੋਵੋ (min ਅਤੇ max length, allowed characters, required fields, ਅਤੇ ਨਾਰਮਲਾਈਜੇਸ਼ਨ ਜਿਵੇਂ trimming spaces)। ਗਲਤੀਆਂ ਫੀਲਡ ਦੇ ਨੇੜੇ ਸਾਫ-ਸਾਫ ਭਾਸ਼ਾ ਵਿੱਚ ਦਿਖਾਓ, ਨਾ ਕੇਵਲ ਟੋਸਟ ਵਿੱਚ।
ਹੋਰ ਇੱਕ ਖਤਰਾ ਕੀਬੋਰਡ ਫ਼ਰਕ ਹਨ iOS ਅਤੇ Android ਵਿੱਚ। ਆਟੋਕਰੈਕਟ ਸਪੇਸ ਜੋੜਦਾ ਹੈ, ਕੁਝ ਕੀਬੋਰਡ quotes ਜਾਂ dashes ਬਦਲ ਦਿੰਦੇ ਹਨ, ਨੰਬਰਕੀ ਕੀਬੋਰਡ ਵੋਹ ਅੱਖਰ ਸ਼ਾਮਿਲ ਨਹੀਂ ਕਰ ਸਕਦਾ ਜੋ ਤੁਸੀਂ ਸੋਚ ਰਹੇ ਸੀ (ਜਿਵੇਂ + sign), ਅਤੇ copy-paste ਅਦೃਸ਼ਯ ਅੱਖਰ ਲਿਆ ਆ ਸਕਦਾ ਹੈ। ਵੈਧਤਾ ਤੋਂ ਪਹਿਲਾਂ ਇਨਪੁਟ ਨਾਰਮਲਾਈਜ਼ ਕਰੋ (trim, collapse repeated spaces, remove non-breaking spaces) ਅਤੇ ਬਹੁਤ ਕਠੋਰ regex ਤੋਂ ਬਚੋ ਜੋ ਸਧਾਰਨ ਟਾਈਪਿੰਗ 'ਤੇ ਸਜ਼ਾ ਦੇਵੇ।
Async ਵੈਧਤਾ ਵੀ ਦੇਰ ਨਾਲ ਹੈਰਾਨੀਆਂ ਪੈਦਾ ਕਰਦੀ ਹੈ। ਉਦਾਹਰਣ: ਤੁਸੀਂ blur 'ਤੇ "ਕੀ ਇਹ ਈਮੇਲ ਪਹਿਲਾਂ ਵਰਤੀ ਗਈ ਹੈ?" ਜਾਂਚਦੇ ਹੋ, ਪਰ ਯੂਜ਼ਰ Submit 'ਤੇ ਟੈਪ ਕਰ ਦਿੰਦਾ ਹੈ ਇਸ ਤੋਂ ਪਹਿਲਾਂ ਕਿ ਬੇਨਤੀ ਵਾਪਸ ਆਏ। ਸਕ੍ਰੀਨ ਨੈਵੀਗੇਟ ਹੋ ਜਾਂਦੀ ਹੈ, ਫਿਰ ਗਲਤੀ ਆਉਂਦੀ ਹੈ ਅਤੇ ਉਸ ਪੰਨੇ 'ਤੇ ਦਿਖਾਈ ਦਿੰਦੀ ਹੈ ਜਿਸਨੂੰ ਯੂਜ਼ਰ ਹੁਣ ਛੱਡ ਚੁੱਕਾ ਹੁੰਦਾ ਹੈ।
ਅਮਲ ਵਿੱਚ ਇਹ ਰੋਕਨ ਲਈ:
isSubmitting ਅਤੇ pendingChecks ਟਰੈਕ ਕਰਕੇਤੇਜ਼ੀ ਨਾਲ ਟੈਸਟ ਕਰਨ ਲਈ, ਹੈਪੀ-ਪਾਥ ਤੋਂ ਅੱਗੇ ਵਧੋ। ਕੁਝ ਬਰੂਟਲ ਇਨਪੁਟ ਟੈਸਟ ਕਰੋ:
ਜੇ ਇਹ ਪਾਸ ਹੁੰਦੇ ਹਨ, ਤਾਂ ਸਾਈਨਅਪ ਅਤੇ ਭੁਗਤਾਨ ਰਿਲੀਜ਼ ਤੋਂ ਪਹਿਲਾਂ ਘੱਟ ਸੰਭਾਵਨਾ ਨਾਲ ਟੁੱਟਣਗੇ।
ਪਰਮਿਸ਼ਨ "ਇਹ ਕੱਲ੍ਹ ਚੱਲ ਰਿਹਾ ਸੀ" ਵਾਲੀਆਂ ਬਗ-ਕਾਰਨਾਂ 'ਚੋਂ ਇੱਕ ਉੱਪਰਲੇ ਹਨ। ਚੈਟ-ਬਿਲਟ ਪ੍ਰੋਜੈਕਟਾਂ ਵਿੱਚ, ਇੱਕ ਫੀਚਰ ਤੇਜ਼ੀ ਨਾਲ ਜੋੜਿਆ ਜਾਂਦਾ ਹੈ ਅਤੇ ਪਲੇਟਫਾਰਮ ਨਿਯਮਾਂ ਨੂੰ ਮਿਸ ਕੀਤਾ ਜਾਂਦਾ ਹੈ। ਐਪ ਸਿਮੂਲੇਟਰ 'ਤੇ ਚੱਲਦਾ ਹੈ, ਫਿਰ ਅਸਲ ਫੋਨ 'ਤੇ ਫੇਲ ਹੁੰਦਾ ਹੈ, ਜਾਂ ਸਿਰਫ਼ ਉਪਭੋਗਤਾ "Don’t Allow" ਤੇਹੀਨ ਬਾਅਦ ਫੇਲ ਹੋ ਜਾਂਦਾ ਹੈ।
ਇੱਕ ਫੰਦਾ ਘਾਟੇ ਪਲੇਟਫਾਰਮ ਘੋਸ਼ਣਾਵਾਂ ਹਨ। iOS 'ਤੇ, ਤੁਹਾਨੂੰ ਸਪੱਸ਼ਟ usage text ਸ਼ਾਮਲ ਕਰਨਾ ਲਾਜ਼ਮੀ ਹੈ ਜੋ ਦੱਸਦਾ ਹੈ ਕਿ ਤੁਸੀਂ ਕਿਉਂ ਕੈਮਰਾ, ਲੋਕੇਸ਼ਨ, ਫੋਟੋ ਆਦਿ ਦੀ ਲੋੜ ਰੱਖਦੇ ਹੋ। ਜੇ ਇਹ ਗੈਰ-ਮੌਜੂਦ ਜਾਂ ਧੁੰਦਲਾ ਹੈ, ਤਾਂ iOS ਪ੍ਰਾਂਪਟ ਨੂੰ ਬਲਾਕ ਕਰ ਸਕਦਾ ਹੈ ਜਾਂ App Store ਰਿਵਿਊ ਬਿਲਡ ਨੂੰ ਰੀਜੈਕਟ ਕਰ ਸਕਦਾ ਹੈ। Android 'ਤੇ, ਗੈਰ-ਮੌਜੂਦ ਮੈਨਿਫ਼ੈਸਟ ਐਂਟਰੀ ਜਾਂ OS ਵਰਜਨ ਲਈ ਗਲਤ ਪਰਮਿਸ਼ਨ ਵਰਤਣਾ ਕਾਲਾਂ ਨੂੰ ਚੁਪਚਾਪ ਫੇਲ ਕਰ ਸਕਦਾ ਹੈ।
ਹੋਰ ਇੱਕ ਫੰਦਾ ਇਹ ਹੈ ਕਿ ਪਰਮਿਸ਼ਨ ਨੂੰ ਇਕ-ਵਾਰੀ ਫੈਸਲੇ ਵਜੋਂ ਲੈਣਾ। ਯੂਜ਼ਰ ਇਨਕਾਰ ਕਰ ਸਕਦੇ ਹਨ, ਬਾਅਦ ਵਿੱਚ Settings 'ਚ ਰੱਦ ਕਰ ਸਕਦੇ ਹਨ, ਜਾਂ Android 'ਤੇ "Don’t ask again" ਚੁਣ ਸਕਦੇ ਹਨ। ਜੇ ਤੁਹਾਡੀ UI ਨਤੀਜੇ ਲਈ ਬੇਇੰਤਜ਼ਾਰ ਰਹਿ ਜਾਂਦੀ ਹੈ, ਤਾਂ ਤੁਹਾਨੂੰ ਇੱਕ ਫ੍ਰੋਜ਼ਨ ਸਕ੍ਰੀਨ ਜਾਂ ਇੱਕ ਬਟਨ ਮਿਲਦਾ ਹੈ ਜੋ ਕੁਝ ਨਹੀਂ ਕਰਦਾ।
OS ਵਰਜਨਾਂ ਦੇ ਵੀ ਵੱਖ-ਵੱਖ ਵਿਹਾਰ ਹਨ। ਨੋਟੀਫਿਕੇਸ਼ਨ ਇੱਕ ਕਲਾਸਿਕ ਉਦਾਹਰਨ ਹੈ: Android 13+ runtime permission ਮੰਗਦਾ ਹੈ, ਪੁਰਾਣੇ Android ਵਰਜਨ ਨਹੀਂ। ਫੋਟੋ ਅਤੇ ਸਟੋਰੇਜ ਨੂੰ ਐਕਸੈਸ ਕਰਨ ਦੇ ਤਰੀਕੇ ਦੋਹਾਂ ਪਲੇਟਫਾਰਮਾਂ 'ਤੇ ਬਦਲੇ ਹਨ: iOS 'ਚ "limited photos" ਹਨ, ਅਤੇ Android 'ਚ ਨਵੇਂ "media" ਪਰਮਿਸ਼ਨ ਹਨ ਬਜਾਏ ਵਿਆਪਕ ਸਟੋਰੇਜ ਦੇ। ਬੈਕਗ੍ਰਾਊਂਡ ਲੋਕੇਸ਼ਨ ਦੋਹਾਂ ਪਲੇਟਫਾਰਮਾਂ 'ਤੇ ਆਪਣਾ ਵੱਖਰਾ ਸ਼੍ਰੇਣੀ ਹੈ ਅਤੇ ਆਮ ਤੌਰ 'ਤੇ ਵਧੀਕ ਕਦਮਾਂ ਅਤੇ ਵਧੀਕ ਸਪੱਸ਼ਟੀਕਰਨ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ।
ਪਰਮਿਸ਼ਨਾਂ ਨੂੰ ਇੱਕ ਛੋਟੇ ਸਟੇਟ ਮਸ਼ੀਨ ਵਾਂਗ ਹੈਂਡਲ ਕਰੋ, ਨਾ ਕਿ ਇਕ ਸਿਰਫ਼ ਹਾਂ/ਨਹੀਂ ਚੈਕ:
ਫਿਰ ਮੁੱਖ ਪਰਮਿਸ਼ਨ ਸਤਹਾਂ ਨੂੰ ਅਸਲ ਡਿਵਾਈਸਾਂ 'ਤੇ ਟੈਸਟ ਕਰੋ। ਇੱਕ ਤੇਜ਼ ਚੈੱਕਲਿਸਟ ਜ਼ਿਆਦਾਤਰ ਹੈਰਾਨੀਆਂ ਫੜ ਲੈਦਾ ਹੈ:
ਉਦਾਹਰਨ: ਤੁਸੀਂ ਚੈਟ ਸੈਸ਼ਨ ਵਿੱਚ "upload profile photo" ਜੋੜਿਆ ਅਤੇ ਇਹ ਤੁਹਾਡੇ ਫੋਨ 'ਤੇ ਕੰਮ ਕੀਤਾ। ਨਵਾਂ ਯੂਜ਼ਰ ਫੋਟੋ ਐਕਸੈਸ ਇੱਕ ਵਾਰੀ ਇਨਕਾਰ ਕਰ ਦਿੰਦਾ ਹੈ, ਅਤੇ onboarding ਅੱਗੇ ਨਹੀਂ ਵਧਦਾ। ਸੁਧਾਰ ਜ਼ਿਆਦਾ UI polish ਨਹੀਂ; ਇਹ "denied" ਨੂੰ ਇਕ ਆਮ ਨਤੀਜੇ ਵਜੋਂ ਲੈਣਾ ਹੈ ਅਤੇ ਇੱਕ fallback (photo skip, ਜਾਂ ਬਿਨਾਂ photo ਦੇ ਅੱਗੇ ਵਧੋ) ਦਿਓ, ਅਤੇ ਫੀਚਰ ਨੂੰ ਦੁਬਾਰਾ ਟਰਾਇ ਕਰਨ 'ਤੇ ਹੀ ਪਰਮਿਸ਼ਨ ਪੁਛੋ।
ਜੇ ਤੁਸੀਂ Koder.ai ਵਰਗੇ ਪਲੇਟਫਾਰਮ ਨਾਲ Flutter ਕੋਡ ਜਨਰੇਟ ਕਰ ਰਹੇ ਹੋ, ਤਾਂ ਹਰ ਫੀਚਰ ਲਈ acceptance checklist 'ਚ ਪਰਮਿਸ਼ਨ ਸ਼ਾਮਲ ਕਰੋ। ਸਹੀ ਘੋਸ਼ਣਾਵਾਂ ਅਤੇ ਸਟੇਟ ਫੌੜਾਂ ਤੁਰੰਤ ਜੋੜਨਾ ਇਸ ਤੋਂ ਤੇਜ਼ ਹੈ ਕਿ ਪଛੋਂ ਸਟੋਰ ਰੀਜੈਕਸ਼ਨ ਜਾਂ ਫਸੇ ਹੋਏ onboarding ਸਕ੍ਰੀਨ ਦਾ ਪਿੱਛਾ ਕੀਤਾ ਜਾਵੇ।
ਇੱਕ Flutter ਐਪ ਡੀਬੱਗ ਵਿੱਚ ਪर्फੈਕਟ ਲੱਗ ਸਕਦਾ ਹੈ ਅਤੇ ਫਿਰ ਵੀ ਰਿਲੀਜ਼ ਵਿੱਚ ਟੁੱਟ ਸਕਦਾ ਹੈ। ਰਿਲੀਜ਼ ਬਿਲਡ ਡੀਬੱਗ ਸਹਾਇਤਾਂ ਹਟਾਂਦੀਆਂ ਹਨ, ਕੋਡ ਘਟਾਇਆ ਜਾਂਦਾ ਹੈ, ਅਤੇ ਰਿਸੋਰਸ ਅਤੇ কੰفਿਗਰੇਸ਼ਨ ਲਈ ਕਠੋਰ ਨਿਯਮ ਲਾਗੂ ਹੁੰਦੇ ਹਨ। ਬਹੁਤ ਸਾਰੀਆਂ ਸਮੱਸਿਆਵਾਂ ਸਿਰਫ ਉਸ ਸਮੇਂ ਆਉਂਦੀਆਂ ਹਨ ਜਦੋਂ ਤੁਸੀਂ ਉਹ ਸਵਿੱਚ ਆਨ ਕਰਦੇ ਹੋ।
ਰਿਲੀਜ਼ ਵਿੱਚ, Flutter ਅਤੇ ਪਲੇਟਫਾਰਮ ਟੂਲਚੇਨ ਉਹ ਕੋਡ ਅਤੇ ਐਸੈਟ ਜਿਹੜਾ ਲਾਗੂ ਨਾ ਹੋ ਰਿਹਾ ਲਗਦਾ ਹੈ, ਹਟਾ ਸਕਦੇ ਹਨ। ਇਸ ਨਾਲ reflection-based ਕੋਡ, "ਮੈਜਿਕ" JSON parsing, ਡਾਇਨਾਮਿਕ ਆਈਕਨ ਨਾਮ, ਜਾਂ ਫੋਂਟ ਜੋ ਠੀਕ ਤਰੀਕੇ ਨਾਲ ਘੋਸ਼ਿਤ ਨਹੀਂ ਸਨ, ਤੋੜ ਸਕਦੇ ਹਨ।
ਇੱਕ ਆਮ ਪੈਟਰਨ: ਐਪ ਲਾਂਚ ਹੁੰਦੀ ਹੈ, ਫਿਰ ਪਹਿਲੀ API ਕਾਲ ਤੋਂ ਬਾਅਦ ਕਰੈਸ਼ ਹੋ ਜਾਂਦਾ ਹੈ ਕਿਉਂਕਿ ਇਕ config ਫਾਇਲ ਜਾਂ key debug-only path ਤੋਂ ਲੋਡ ਕੀਤਾ ਗਿਆ ਸੀ। ਦੂਜਾ: ਇੱਕ ਸਕ੍ਰੀਨ ਜੋ ਡਾਇਨਾਮਿਕ ਰੂਟ ਨਾਮ ਵਰਤਦੀ ਹੈ ਡੀਬੱਗ 'ਚ ਚੱਲਦੀ ਹੈ, ਪਰ ਰਿਲੀਜ਼ 'ਚ fail ਕਰਦੀ ਹੈ ਕਿਉਂਕਿ ਰੂਟ ਕਦੇ ਸਿੱਧਾ reference ਨਹੀਂ ਕੀਤਾ ਗਿਆ।
ਰਿਲੀਜ਼ ਬਿਲਡ ਜਲਦੀ ਅਤੇ ਅਕਸਰ ਚਲਾਓ, ਫਿਰ ਪਹਿਲੇ ਸਕਿੰਟਾਂ ਨੂੰ ਦੇਖੋ: startup ਵਿਵਹਾਰ, ਪਹਿਲੀ ਨੈੱਟਵਰਕ ਕਾਲ, ਪਹਿਲੀ ਨੈਵੀਗੇਸ਼ਨ। ਜੇ ਤੁਸੀਂ ਸਿਰਫ hot reload ਨਾਲ ਟੈਸਟ ਕਰਦੇ ਹੋ, ਤਾਂ ਤੁਸੀਂ cold-start ਵਿਹਾਰ ਨੂੰ ਮਿਸ ਕਰ ਰਹੇ ਹੋ।
ਟੀਮ ਅਕਸਰ dev API 'ਤੇ ਟੈਸਟ ਕਰਦੀ ਹੈ, ਫਿਰ ਮੰਨ ਲੈਂਦੀ ਹੈ ਕਿ production ਸੈਟਿੰਗਸ "ਸਿਰਫ ਠੀਕ ਹੋ ਜਾਣ"। ਪਰ ਰਿਲੀਜ਼ ਬਿਲਡਾਂ ਵਿੱਚ ਤੁਹਾਡੀ env ਫਾਇਲ ਨਹੀਂ ਹੋ ਸਕਦੀ, ਵੱਖਰਾ applicationId/bundleId ਵਰਤਿਆ ਜਾ ਸਕਦਾ ਹੈ, ਜਾਂ push notifications ਲਈ ਸਹੀ config ਨਹੀਂ ਹੋਵੇਗਾ।
ਤੇਜ਼ ਚੈਕ ਜੋ ਜ਼ਿਆਦਾਤਰ ਹੈਰਾਨੀਆਂ ਰੋਕਦੇ ਹਨ:
ਐਪ ਸਾਈਜ਼, ਆਈਕਨ, ਸਪਲੈਸ਼ ਸਕ੍ਰੀਨ ਅਤੇ ਵਰਜ਼ਨਿੰਗ ਅਕਸਰ ਮੋਢੇ 'ਤੇ ਰੱਖ ਦਿੱਤੇ ਜਾਂਦੇ ਹਨ। ਫਿਰ ਤੁਸੀਂ ਪਾ ਜਾਂਦੇ ਹੋ ਕਿ ਤੁਹਾਡੀ ਰਿਲੀਜ਼ ਵੱਡੀ ਹੈ, ਆਈਕਨ ਧੁੰਦਲਾ ਹੈ, ਸਪਲੈਸ਼ ਕੱਟਾ ਹੋਇਆ ਹੈ, ਜਾਂ ਵਰਜ਼ਨ/ਬਿਲਡ ਨੰਬਰ ਸਟੋਰ ਲਈ ਗਲਤ ਹੈ।
ਇਹਨਾਂ ਨੂੰ ਜ਼ਿਆਦਾ ਜਲਦੀ ਕਰੋ: ਠੀਕ ਐਪ ਆਈਕਨ Android ਅਤੇ iOS ਲਈ ਸੈਟ ਕਰੋ, ਸੁਨਿਸ਼ਚਤ ਕਰੋ ਕਿ ਸਪਲੈਸ਼ ਛੋਟੇ ਅਤੇ ਵੱਡੇ ਸਕ੍ਰੀਨਾਂ 'ਤੇ ਠੀਕ ਦਿਖਦਾ ਹੈ, ਅਤੇ ਵਰਜ਼ਨਿੰਗ ਨਿਯਮ ਫੈਸਲਾ ਕਰੋ (ਕੌਣ ਕਦੋਂ ਕੀ ਬੰਪ ਕਰੇਗਾ)।
ਸਬਮਿਟ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ, ਆਸਾਨੀ ਨਾਲ ਖਰਾਬ ਹਾਲਤਾਂ 'ਤੇ ਟੈਸਟ ਕਰੋ: airplane mode, ਧੀਮਾ ਨੈੱਟਵਰਕ, ਅਤੇ ਐਪ ਨੂੰ ਪੂਰੀ ਤਰ੍ਹਾਂ ਖਤਮ ਕਰਨ ਤੋਂ ਬਾਅਦ cold start। ਜੇ ਪਹਿਲੀ ਸਕ੍ਰੀਨ ਕਿਸੇ ਨੈੱਟਵਰਕ ਕਾਲ 'ਤੇ ਨਿਰਭਰ ਹੈ, ਤਾਂ ਇਹ ਸਪਸ਼ਟ ਲੋਡਿੰਗ ਸਟੇਟ ਅਤੇ ਰੀਟ੍ਰਾਈ ਦਿਖਾਉਣਾ ਚਾਹੀਦਾ ਹੈ, ਨਾ ਕਿ ਖਾਲੀ ਪੇਜ।
ਜੇ ਤੁਸੀਂ Koder.ai ਵਰਗੇ ਚੈਟ-ਡਰਾਈਵਨ ਟੂਲ ਨਾਲ Flutter ਐਪ ਜਨਰੇਟ ਕਰ ਰਹੇ ਹੋ, ਤਾਂ "release build run" ਨੂੰ ਆਪਣੀ ਨਾਰਮਲ ਲੂਪ ਵਿੱਚ ਸ਼ਾਮਲ ਕਰੋ, ਆਖਰੀ ਦਿਨ ਨਹੀਂ। ਇਹ ਛੋਟੇ ਬਦਲਾਅ ਵਕ਼ਤ ਵਿੱਚ ਅਸਲੀ ਦੁਨੀਆ ਦੀਆਂ ਸਮੱਸਿਆਵਾਂ ਫੜਨ ਦਾ ਸਭ ਤੋਂ ਤੇਜ਼ ਤਰੀਕਾ ਹੈ।
ਚੈਟ-ਜਨਰੇਟ ਕੀਤੇ Flutter ਪ੍ਰੋਜੈਕਟ ਅਕਸਰ ਦੇਰ ਨਾਲ ਟੁੱਟਦੇ ਹਨ ਕਿਉਂਕਿ ਚੈਟ ਵਿੱਚ ਬਦਲਾਅ ਛੋਟੇ ਲੱਗਦੇ ਹਨ, ਪਰ ਇੱਕ ਅਸਲੀ ਐਪ ਵਿੱਚ ਬਹੁਤ ਸਾਰੇ ਹਿੱਲ ਰਹਿੰਦੇ ਹਨ। ਇਹ ਗਲਤੀਆਂ ਮੁੱਖ ਤੌਰ 'ਤੇ ਇੱਕ ਸਾਫ ਡੈਮੋ ਨੂੰ ਗੰਦੇ ਰਿਲੀਜ਼ ਵਿੱਚ ਬਦਲ ਦਿੰਦੀਆਂ ਹਨ।
ਬਿਨਾਂ ਸਟੇਟ ਅਤੇ ਡਾਟਾ ਫਲੋ ਯੋਜਨਾ ਅਪਡੇਟ ਕੀਤੇ ਫੀਚਰ ਜੋੜਣਾ। ਜੇ ਨਵੀਂ ਸਕ੍ਰੀਨ ਨੂੰ ਉਹੀ ਡਾਟਾ ਚਾਹੀਦਾ ਹੈ, ਤਾਂ ਕੋਡ ਪੇਸਟ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਫੈਸਲਾ ਕਰੋ ਕਿ ਡਾਟਾ ਕਿੱਥੇ ਰਹੇਗਾ।
ਜਨਰੇਟ ਕੀਤੇ ਕੋਡ ਨੂੰ ਮੰਨ ਲੈਣਾ ਜੋ ਤੁਹਾਡੇ ਚੁਣੇ ਪੈਟਰਨ ਨਾਲ ਮੇਲ ਨਹੀਂ ਖਾਂਦਾ। ਜੇ ਤੁਹਾਡੀ ਐਪ ਇੱਕ routing style ਜਾਂ ਇੱਕ ਸਟੇਟ ਅਪ੍ਰੋਚ ਵਰਤਦੀ ਹੈ, ਤਾਂ ਇੱਕ ਨਵੀਂ ਸਕ੍ਰੀਨ ਨੂੰ ਦੂਜਾ ਤਰੀਕਾ ਲਿਆਉਣ ਦੀ ਆਗਿਆ ਨਾ ਦਿਓ।
ਹਰ ਸਕ੍ਰੀਨ ਲਈ "one-off" API calls ਬਣਾਉਣਾ। ਰਿਕਵੇਸਟਾਂ ਨੂੰ ਇੱਕ client/service ਦੇ ਪਿੱਛੇ ਰੱਖੋ ਤਾਂ ਕਿ ਤੁਹਾਡੇ ਕੋਲ ਪੰਜ ਥੋੜ੍ਹੇ-ਭਿੰਨ headers, base URLs, ਅਤੇ error rules ਨਾ ਹੋਣ।
ਤੁਹਾਨੂੰ ਜਿੱਥੇ ਨੋਟਿਸ ਕੀਤਾ ਉੱਥੇ ਹੀ errors ਨੂੰ ਹੈਂਡਲ ਕਰਨਾ। timeouts, offline mode, ਅਤੇ server errors ਲਈ ਇਕ consistent rule ਰੱਖੋ ਤਾਂ ਕਿ ਹਰ ਸਕ੍ਰੀਨ ਅਨੁਮਾਨ ਨਾ ਲਗਾਏ।
Warnings ਨੂੰ ਨਜ਼ਰਅੰਦਾਜ਼ ਕਰਨਾ। Analyzer hints, deprecations, ਅਤੇ "this will be removed" ਸੁਨੇਹੇ ਸ਼ੁਰੂਆਤੀ ਅਲਾਰਮ ਹਨ।
ਮੰਨ ਲੈਣਾ ਕਿ ਸਿਮੂਲੇਟਰ ਅਸਲ ਫੋਨ ਵਰਗਾ ਹੈ। ਕੈਮਰਾ, ਨੋਟੀਫਿਕੇਸ਼ਨ, ਬੈਕਗ੍ਰਾਊਂਡ resume, ਅਤੇ ਧੀਮਾ ਨੈੱਟਵਰਕ ਅਸਲ ਡਿਵਾਈਸਾਂ 'ਤੇ ਅਲੱਗ ਵਰਤੋਂ ਕਰਦੇ ਹਨ।
ਨਵੀਂ widgets ਵਿੱਚ strings, colors, ਅਤੇ spacing ਨੂੰ hardcode ਕਰਨਾ। ਛੋਟੀ ਅਸਮਰਥਤਾਵਾਂ ਇਕਠਾ ਹੋ ਜਾਂਦੀਆਂ ਹਨ, ਅਤੇ ਐਪ ਇੱਕ ਸਿਲਾਈ ਕੀਤੀ ਹੋਈ ਮਹਿਸੂਸ ਕਰਨ ਲੱਗਦੀ ਹੈ।
ਫਾਰਮ ਵੈਧਤਾ ਨੂੰ ਹਰ ਸਕ੍ਰੀਨ 'ਤੇ ਵੱਖਰਾ ਛੱਡਣਾ। ਜੇ ਇੱਕ ਫਾਰਮ spaces trim ਕਰਦਾ ਹੈ ਅਤੇ ਦੂਜਾ ਨਹੀਂ, ਤਾਂ "ਮੇਰੇ ਲਈ ਚੱਲਦਾ ਹੈ" ਤਰ੍ਹਾਂ ਦੀਆਂ ਨਾਕਾਮੀਆਂ ਆਉਣਗੀਆਂ।
ਪਰਮਿਸ਼ਨ ਬਾਦ 'ਚ ਭੁੱਲ ਜਾਣਾ। ਜੇ ਫੀਚਰ ਨੂੰ ਫੋਟੋ, ਲੋਕੇਸ਼ਨ, ਜਾਂ ਫਾਇਲੋ ਦੀ ਲੋੜ ਹੈ, ਤਾਂ ਤੱਕ ਫੀਚਰ "ਡਨ" ਨਹੀਂ ਹੈ ਜਦ ਤੱਕ ਇਹ ਪਰਮਿਸ਼ਨ deny ਅਤੇ grant ਦੋਹਾਂ ਨਾਲ ਕੰਮ ਨਾ ਕਰੇ।
ਡੀਬੱਗ-Only ਵਿਹਾਰ 'ਤੇ ਨਿਰਭਰ ਰਹਿਣਾ। ਕੁਝ ਲੌਗ, assertions, ਅਤੇ relaxed network settings ਰਿਲੀਜ਼ ਵਿੱਚ ਨਹੀਂ ਰਹਿੰਦੇ।
ਤੇਜ਼ ਪ੍ਰਯੋਗਾਂ ਤੋਂ ਬਾਅਦ ਸਫਾਈ ਨਾ ਕਰਨਾ। ਪੁਰਾਣੇ flags, unused endpoints, ਅਤੇ dead UI branches ਹਫ਼ਤਿਆਂ ਬਾਅਦ ਹੈਰਾਨੀਆਂ ਪੈਦਾ ਕਰਦੇ ਹਨ।
"ਅੰਤਿਮ ਫੈਸਲਾ" ਦੀ ਕੋਈ ਜ਼ਿੰਮੇਵਾਰੀ ਨਹੀਂ। Vibe coding ਤੇਜ਼ ਹੈ, ਪਰ ਕਿਸੇ ਨੂੰ ਨਾਮ, ਢਾਂਚਾ, ਅਤੇ "ਇਹੋਂ ਤਰੀਕੇ ਨਾਲ ਅਸੀਂ ਕਰਾਂਗੇ" ਦਾ ਫੈਸਲਾ ਕਰਨਾ ਹੁੰਦਾ ਹੈ।
ਇੱਕ ਵਿਹਾਰਕ ਤਰੀਕਾ ਤੇਜ਼ੀ ਰੱਖਣ ਲਈ ਬਿਨਾ ਅਤਿਅਵਿਵਸਥਾ ਦੇ ਛੋਟੀ ਸਮੀਖਿਆ ਹੈ: ਹਰ ਮਹੱਤਵਪੂਰਨ ਬਦਲਾਅ ਦੇ ਬਾਅਦ ਇਕ ਛੋਟੀ ਰਿਵਿਊ:
ਇੱਕ ਛੋਟੀ ਟੀਮ Koder.ai ਨਾਲ ਇੱਕ ਸਧਾਰਣ Flutter ਐਪ ਬਣਾਉਂਦੀ ਹੈ: login, ਇੱਕ profile form (name, phone, birthday), ਅਤੇ API ਤੋਂ ਲਿਆ ਗਿਆ ਆਈਟਮ ਲਿਸਟ। ਡੈਮੋ ਵਿੱਚ ਸਭ ਠੀਕ ਲੱਗਦਾ ਹੈ। ਫਿਰ ਅਸਲ-ਡਿਵਾਈਸ ਟੈਸਟਿੰਗ ਸ਼ੁਰੂ ਹੁੰਦੀ ਹੈ ਅਤੇ ਆਮ ਸਮੱਸਿਆਵਾਂ ਇੱਕੱਠੀ ਵਕਤ 'ਤੇ ਆਉਂਦੀਆਂ ਹਨ।
ਪਹਿਲੀ ਸਮੱਸਿਆ login ਤੋਂ ਬਾਅਦ ਵੇਖੀ ਜਾਂਦੀ ਹੈ। ਐਪ home ਸਕ੍ਰੀਨ push ਕਰਦਾ ਹੈ, ਪਰ back button login ਪੰਨੇ 'ਤੇ ਵਾਪਸ ਕਰ ਦਿੰਦਾ ਹੈ, ਅਤੇ ਕਦੇ-ਕਦੇ UI ਪੁਰਾਣੇ ਸਕ੍ਰੀਨ ਨੂੰ ਫਲੈਸ਼ ਕਰਦਾ ਹੈ। ਕਾਰਨ ਅਕਸਰ ਮਿਕਸਡ ਨੈਵੀਗੇਸ਼ਨ ਪੈਟਰਨ ਹੁੰਦਾ ਹੈ: ਕੁਝ ਸਕ੍ਰੀਨ push ਵਰਤੇ, ਹੋਰ replace, ਅਤੇ auth state ਦੋ ਥਾਵਾਂ 'ਤੇ ਚੈੱਕ ਕੀਤੀ ਜਾਂਦੀ ਹੈ।
ਅਗਲਾ ਆਉਂਦਾ ਹੈ API ਲਿਸਟ। ਇਹ ਇੱਕ ਸਕ੍ਰੀਨ 'ਤੇ ਲੋਡ ਹੁੰਦੀ ਹੈ, ਪਰ ਦੂਜੇ ਸਕ੍ਰੀਨ 'ਤੇ 401 ਅਰਰ ਆਉਂਦੇ ਹਨ। Token refresh ਮੌਜੂਦ ਹੈ, ਪਰ ਸਿਰਫ਼ ਇੱਕ API client ਉਹ ਵਰਤਦਾ ਹੈ। ਇੱਕ ਸਕ੍ਰੀਨ raw HTTP call ਕਰਦੀ ਹੈ, ਦੂਜੀ helper ਵਰਤਦੀ ਹੈ। ਡੀਬੱਗ ਵਿੱਚ, ਧੀਮੀ ਟਾਈਮਿੰਗ ਅਤੇ cache ਇਨਸਿੰਕ੍ਰੋਨਾਈਜ਼ੇਸ਼ਨ ਨੂੰ ਟੁਕੜਿਆ ਕਰਦੇ ਹਨ।
ਫਿਰ profile ਫਾਰਮ ਬਹੁਤ ਮਨੁੱਖੀ ਤਰੀਕੇ ਨਾਲ ਫੇਲ ਹੁੰਦੀ ਹੈ: ਐਪ ਇਕ ਐਸਾ ਫੋਨ ਫਾਰਮੈਟ ਲੈਂਦਾ ਹੈ ਜੋ ਸਰਵਰ رد ਕਰਦਾ ਹੈ, ਜਾਂ ਇਹ ਖਾਲੀ birthday ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ ਜਦ ਕਿ ਬੈਕਐਂਡ ਇਸਨੂੰ ਲਾਜ਼ਮੀ ਮੰੰਨਦਾ ਹੈ। ਯੂਜ਼ਰ Save ਦਬਾਉਂਦਾ ਹੈ, ਇੱਕ ਜਨਰਿਕ ਗਲਤੀ ਵੇਖਦਾ ਹੈ, ਅਤੇ ਰੁਕ ਜਾਂਦਾ ਹੈ।
ਇੱਕ ਪਰਮਿਸ਼ਨ ਹੈਰਾਨੀ ਦੇਰ ਨਾਲ ਆਉਂਦੀ ਹੈ: iOS notification permission ਪਹਿਲੀ ਲਾਂਚ 'ਤੇ ਆ ਜਾਂਦੀ ਹੈ, ਸਿੱਧੀ onboarding 'ਤੇ। ਬਹੁਤ ਯੂਜ਼ਰ "Don’t Allow" ਦਬਾ ਦਿੰਦੇ ਹਨ ਸਿਰਫ਼ ਅੱਗੇ ਵੱਧਣ ਲਈ, ਅਤੇ ਬਾਅਦ ਵਿੱਚ ਮਹੱਤਵਪੂਰਨ ਅਪਡੇਟ ਮਿਸ ਕਰ ਜਾਂਦੇ ਹਨ।
ਅੰਤ ਵਿੱਚ, ਰਿਲੀਜ਼ ਬਿਲਡ ਟੁਟਦਾ ਹੈ ਜਦਕਿ ਡੀਬੱਗ ਚੱਲਦਾ ਹੈ। ਆਮ ਕਾਰਨ missing production config, ਵੱਖਰਾ API base URL, ਜਾਂ build settings ਜੋ runtime 'ਤੇ ਕੁਝ ਲੋੜੀਂਦਾ ਹਟਾ ਦਿੰਦੇ ਹਨ। ਐਪ ਇੰਸਟਾਲ ਹੁੰਦਾ ਹੈ, ਫਿਰ ਚੁੱਪਚਾਪ ਫੇਲ ਜਾਂ ਵੱਖਰਾ ਵਿਹਾਰ ਕਰਦਾ ਹੈ।
ਇੱਕ ਸਪ੍ਰਿੰਟ ਵਿੱਚ ਟੀਮ ਏਸ ਨੂੰ ਨੱਕ-ਕਟੇ ਬਗਾਂ ਬਿਨਾਂ ਦੁਬਾਰਾ ਲਿਖੇ ਹੱਲ ਕਰਦੀ ਹੈ:
Koder.ai ਵਰਗੇ ਟੂਲਸ ਇੱਥੇ ਮਦਦਗਾਰ ਹਨ ਕਿਉਂਕਿ ਤੁਸੀਂ planning mode ਵਿੱਚ iteration ਕਰ ਸਕਦੇ ਹੋ, fixes ਨੂੰ ਛੋਟੇ ਪੈਚਾਂ ਦੇ ਤੌਰ 'ਤੇ ਲਾਗੂ ਕਰੋ, ਅਤੇ snapshots ਅਤੇ rollback ਵਰਤ ਕੇ ਜੋਖਮ ਘੱਟ ਰੱਖ ਸਕਦੇ ਹੋ।
ਦੇਰ-ਵਾਲੀਆਂ ਹੈਰਾਨੀਆਂ ਤੋਂ ਬਚਣ ਦਾ ਸਭ ਤੋਂ ਤੇਜ਼ ਤਰੀਕਾ ਇਹ ਹੈ ਕਿ ਹਰ ਫੀਚਰ ਲਈ ਉਹੇ ਛੋਟੇ ਚੈੱਕ ਕਰੋ, ਭਾਵੇਂ ਤੁਸੀਂ ਚੈਟ ਰਾਹੀਂ ਤੇਜ਼ੀ ਨਾਲ ਬਣਾਇਆ ਹੋ। ਜ਼ਿਆਦਾਤਰ ਸਮੱਸਿਆਵਾਂ "ਵੱਡੇ ਬੱਗ" ਨਹੀਂ ਹੁੰਦੀਆਂ। ਉਹ ਛੋਟੀ ਅਸਮਰਥਤਾਵਾਂ ਹਨ ਜੋ ਸਿਰਫ ਸਕ੍ਰੀਨ ਜੁੜਨ, ਨੈੱਟਵਰਕ ਧੀਮੀ ਹੋਣ, ਜਾਂ OS 'नाਕ' ਰਹਿਣ 'ਤੇ ਨਜ਼ਰ ਆਉਂਦੀਆਂ ਹਨ।
ਜਦ ਤੱਕ ਤੁਸੀਂ ਕਿਸੇ ਫੀਚਰ ਨੂੰ "ਡਨ" ਨਹੀਂ ਕਹੋਗੇ, ਇੱਕ ਦੋ-ਮਿੰਟ ਦਾ ਪਾਸ ਕਰੋ ਇਹ ਆਮ ਤਕਲੀਫ-ਜ਼ੋਨ ਦੇਖ ਕੇ:
ਫਿਰ ਰਿਲੀਜ਼-ਕੇਂਦਰਿਤ ਚੈੱਕ ਚਲਾਓ। ਬਹੁਤ ਸਾਰੀਆਂ ਐਪ ਡੀਬੱਗ ਵਿੱਚ ਪੂਰਨ ਲੱਗਦੀਆਂ ਹਨ ਪਰ ਸਾਈਨਿੰਗ, ਕਠੋਰ ਸੈਟਿੰਗਾਂ, ਜਾਂ ਗੁੰਮ ਹੋਏ permission text ਕਰਕੇ ਰਿਲੀਜ਼ ਵਿੱਚ ਫੇਲ ਹੁੰਦੀਆਂ ਹਨ:
Patch vs refactor: patch ਜੇ ਸਮੱਸਿਆ ਇਕੱਠੀ ਹੈ (ਇੱਕ ਸਕ੍ਰੀਨ, ਇੱਕ API call, ਇੱਕ validation rule)। refactor ਜੇ ਤੁਸੀਂ patterns ਦੇ ਦੁਹਰਾਅ ਵੇਖਦੇ ਹੋ (ਤਿੰਨ ਸਕ੍ਰੀਨਾਂ 'ਤੇ ਤਿੰਨ ਵੱਖ-ਵੱਖ clients, ਨਕਲ ਸਟੇਟ ਲਾਜਿਕ, ਜਾਂ ਨੈਵੀਗੇਸ਼ਨ ਰੂਟ ਜੋ ਇਕ-ਦੂਜੇ ਨਾਲ ਅਸਹਿਮਤੀ ਕਰਦੇ ਹਨ)।
ਜੇ ਤੁਸੀਂ Koder.ai ਵਰਤ ਰਹੇ ਹੋ, ਤਾਂ planning mode ਵੱਡੇ ਬਦਲਾਅ (ਜਿਵੇਂ state management ਜਾਂ routing ਬਦਲਣਾ) ਤੋਂ ਪਹਿਲਾਂ ਯੂਜ਼ਫੁਲ ਹੈ। snapshots ਅਤੇ rollback ਵਰਤਣਾ ਵੀ ਲਾਭਦਾਇਕ ਹੈ ਤਾਂ ਕਿ ਤੁਸੀਂ ਤੇਜ਼ੀ ਨਾਲ ਵਾਪਸ ਆ ਸਕੋ, ਛੋਟਾ ਫਿਕਸ ਸ਼ਿਪ ਕਰੋ, ਅਤੇ ਅੱਗੇ structure ਬਿਹਤਰ ਕਰੋ।
Start with a small shared frame before generating lots of screens:
push, replace, and back behavior)This keeps chat-generated code from turning into disconnected “one-off” screens.
Because a demo proves “it runs once,” while a real app must survive messy conditions:
These problems often don’t show up until multiple screens connect and you test on real devices.
Do a quick real-device pass early, not at the end:
Emulators are useful, but they won’t catch many timing, permission, and hardware-related issues.
It usually happens after an await when the user leaves the screen (or the OS rebuilds it), and your code still calls setState or navigation.
Practical fixes:
Pick one routing pattern and write down simple rules so every new screen follows them. Common pain points:
push vs pushReplacement in auth flowsMake a rule for each major flow (login/onboarding/checkout) and test back behavior on both platforms.
Because chat-generated features often create their own HTTP setup. One screen might use a different base URL, headers, timeout, or token format.
Fix it by enforcing:
Then every screen “fails the same way,” which makes bugs obvious and repeatable.
Keep refresh logic in one place and keep it simple:
Also log method/path/status and a request ID, but never log tokens or sensitive payload fields.
Align UI validation with backend rules and normalize input before validating.
Practical defaults:
isSubmitting and block double-tapsThen test “brutal” inputs: empty submit, min/max length, copy-paste with spaces, slow network.
Treat permission as a small state machine, not a one-time yes/no.
Do this:
Also make sure required platform declarations are present (iOS usage text, Android manifest entries) before calling the feature “done.”
Release builds remove debug helpers and can strip code/assets/config you accidentally relied on.
A practical routine:
If release breaks, suspect missing assets/config, wrong environment settings, or code that depended on debug-only behavior.
await, check if (!context.mounted) return;dispose()BuildContext for laterThis prevents “late callbacks” from touching a dead widget.