كيفية إنشاء آلة حاسبة في Swift 5

استعدادًا لبدء الدورة الأساسية "مطور iOS" ، ننشر مقالًا كتبه مؤلفنا المستقل.







مرحبا! مر أكثر من عام على إصدار Swift 5 ، والذي جلب الكثير من الأشياء الجديدة للمطورين. في هذه المقالة أريد أن أتحدث عن تطوير الأجهزة المحمولة لـ IOS وكيف يعمل وما هو مطلوب لهذا وأكثر من ذلك بكثير. المقال مخصص للأشخاص الذين بدأوا للتو برمجتهم في Swift 5 .



متطلبات نظام التشغيل والأجهزة



بطريقة أو بأخرى ، من أجل إنشاء تطبيق لـ IOS من أي إصدار ، فأنت بحاجة إلى جهاز كمبيوتر يعمل بنظام التشغيل Mac OS (ويفضل أن يكون أحدث إصدار ، وإلا فقد يبدأ جزء من أدوات المطور و Xcode في العمل بشكل غير متوقع تمامًا). إن الحاجة إلى نظام يعمل بنظام التشغيل Mac OS هي سبب الجدل والكراهية من المطورين الآخرين الذين لم يعتادوا على محدودية قدراتهم بسبب نظام التشغيل. في أغلب الأحيان ، هناك عدة طرق: شراء أو تجميع Hackintosh (ومع ذلك ، في حالة التجميع الذاتي ، أريد أن أحذرك من أنه لن يكون من السهل تجميع مثل هذا الكمبيوتر دون مشكلة ثابتة في السائق). لقد رأيت كلاً من تثبيت صورة نظام التشغيل في جهاز افتراضي ، وتشغيل نظام التشغيل Mac OS على كمبيوتر محمول عادي ، دون أي مشاكل في برنامج التشغيل.ومع ذلك ، سيتطلب هذا المسار بعض مهارات الأجهزة منك ويهدد بنقص الدعم بنسبة 100٪ للإصدارات المستقبلية من نظام التشغيل Mac OS.



هناك طريقة بديلة ، بالطبع ، وهي شراء جهاز كمبيوتر أصلاً من Apple. إذا كنت تريد جهاز كمبيوتر محمول ، فمن المحتمل أنك تعرف ما يجب فعله (لكنني أريد أن أحذرك على الفور من أن Xcode يأخذ على الفور حوالي 25 غيغابايت ، ويمكن أن يستهلك بسهولة كل 44 غيغابايت إذا قمت بتنزيل أجهزة محاكاة إضافية على الأجهزة. يجب أن يكون حجم 128 جيجا بايت فقط لتطوير IOS بدون أي أجزاء إضافية مثل node_modules و Pycharm و Unity cache و homebrew وأشياء أخرى للمطورين ، والتي تشغل مساحة كبيرة من القرص. إذا كنت ستفعل شيئًا آخر ، فستحتاج إلى قرص على الأقل من 256 جيجا أو أكثر).



تطوير خيارات البيئة



بالإضافة إلى الطريقة الكلاسيكية إلى حد ما لتطوير التطبيقات في Xcode باستخدام Swift واستخدام مكتبات Cocoa و CocoaTouch ، يوجد الآن الكثير من الطرق الأخرى للتطوير تقريبًا بدون استخدام Xcode (فقط بدون Xcode لم يعد بإمكانك إنشاء تطبيق). هناك عدة تقنيات:



  • زامارين . التطبيقات على هذا النظام الأساسي مكتوبة باستخدام C #. باستخدام Xamarin ، يمكنك إنشاء أي تطبيق Android أصلي أو تطبيق IOS. يمكن أن يتم التطوير باستخدام Visual Studio. على الرغم من هذه المزايا ، على الأرجح. ستحتاج إلى كتابة بعض أجزاء التطبيق بشكل منفصل لكل منصة
  • React Native. React , -. . , - , - . , .
  • Flutter. , Flutter Dart Google. , , . , Flutter — React Native, . Dart, -
  • PhoneGap/Cordova. Nitobi, Adobe. , PhoneGap, Apache Cordova, WebView,
  • Unity. IOS, . , . gamedev.




توصي Apple باستخدام لغة البرمجة Swift لتطوير التطبيقات. Swift هي لغة برمجة جديدة نسبيًا لم يتم إصدارها رسميًا حتى عام 2014. يمكن استخدامه للتطوير لنظام التشغيل Mac OS و IOS ، وهناك أيضًا دعم لنظام Linux (لذلك إذا كان لديك ، على سبيل المثال ، نظام Linux غير محدد للغاية ، فيمكنك تنزيل اللغة وتجربتها بأمان ، على سبيل المثال ، من هذا الرابط).



Swift نفسها هي لغة الجيل الجديد النموذجية ، مثل Golang.

في البداية ، تم تصميم اللغة على أنها لغة أسهل في القراءة ومقاومة للأخطاء للمبرمج من لغة الهدف C. وفي الوقت نفسه ، يمكن لـ Swift العمل في نفس المشروع مع كل من C و Objective C.



بدلاً من محاولة إعطاء وصف لهذه اللغة (التي للوهلة الأولى هي C ++ ، تم تعديلها لتلائم الحقائق الحديثة مع وظيفة الكتابة التلقائية العصرية) ، أقترح على القارئ دراسة الوثائق الرائعة من Apple ، والتي تصف بالتفصيل كيفية عمل اللغة وما هو تركيبها. يمكن العثور على النسخة الإنجليزية هنا ، ويمكن العثور على الترجمة الروسية هنا . بعد التعرف على أساسيات لغة Swift ، يمكننا الانتقال إلى ما نحن عليه هنا اليوم - إنشاء الآلة الحاسبة البسيطة الخاصة بنا باستخدام Xcode.



إنشاء آلة حاسبة



لإنشاء تطبيق ، نحتاج إلى Xcode ، والذي يمكن تنزيله مجانًا من AppStore. لا تخيف من تصنيفها - على الرغم من حقيقة أن المراجعات الخمس الأولى تعطي نجمة واحدة ، فإن هذا لا يعني أنك ستصاب بالصدمة. ربما لم يتم تضمين بناء الجملة والتلميحات بسرعة كبيرة عند التحرير - ولكن بشكل عام ، ترك لي Xcode مرات ظهور أكثر ملاءمة من نفس Android Studio (على الرغم من أنني ربما لا أعرف كيف أطبخه). إذا كان لديك فجأة رغبة في تجربة التطوير خارج Xcode وكنت تفضل منتجات JetBrains ، فيمكنك تجربة AppCode - فهو يدعم إمكانية التشغيل البيني مع Xcode ، والعمل مع Swift و Objective C ، والعديد من الميزات الرائعة الأخرى. أنا شخصياً لم أجربها ، ولكن إذا كان لديك اشتراك في جميع البرامج من JetBrains - فلماذا لا تقوم بتنزيلها وتشغيلها.



لذلك قمت بتثبيت Xcode. الآن يمكنك البدء في التطوير. ابدأ مشروعًا جديدًا وحدد تطبيق صفحة واحدة:







بعد ذلك ، سيُطلب منك إدخال بيانات حول تطبيقك. إذا كانت هذه هي المرة الأولى التي تقوم فيها بتشغيل Xcode ، فستحتاج إلى إدخال معرف Apple هناك. بعد ذلك ، يجب عليك ملء المعلومات حول اسم مشروعك (في حالتنا ، فقط الحاسبة) واسم شركتك وتطبيقك. يمكنك كتابة ما تريد هنا إذا كنت لا تنوي نشر هذا التطبيق في المستقبل. اخترت Swift كلغة ، و Storyboard كواجهة مستخدم. لقد ألغيت الاختبارات حتى الآن لأنني رائع ، لأنه لا يوجد شيء لاختباره هنا حقًا.







بعد إنشاء تطبيقنا ، يمكنك الانتقال إلى الملف فيCalculator.xcodeprojوقم بتعديل أي إعدادات إذا كنت ترى ذلك مناسبًا. في الوقت الحالي ، تركت كل شيء على ما هو عليه ، وأنا أطور أحدث إصدار من IOS 13.6 لأجهزة iPhone و Ipad. من حيث المبدأ ، يمكنك استبعاد iPad في الوقت الحالي - على الأرجح لن تبدو واجهتنا جيدة جدًا عليه. ومع ذلك ، أود أن أحذرك من أنه إذا نشرت فجأة - يقوم موظفو Apple باختبار تطبيقات Iphone للتحقق ، بحيث تعمل على الأقل على Ipad. ولكن قبل ذلك ، لا يزال يتعين عليك إنفاق 99 دولارًا على مفاتيح المطور).



بعد إنشاء التطبيق ، يمكنك الاتصال بالمحاكي على الفور لتتبع ما يحدث. للقيام بذلك ، يمكنك ببساطة الضغط على مجموعة مفاتيح CMD + R. في أعلى اليسار ، يمكنك تحديد الأجهزة التي تقوم بتشغيل المحاكي عليها ، ويمكنك أيضًا توصيل جهازك المادي الحقيقي عبر كابل واختباره على الفور).



هناك العديد من الطرق لإنشاء واجهة وعناصر واجهة مستخدم فيها ، سأستخدم خيارًا محايدًا - إنشاء حامل رئيسي ، ووضعه على الشاشة بأكملها ، ثم البدء في وضع أدواتي برمجيًا. لذلك ، نذهب أولاً إلى الملف Main.storyboardونجعل العرض الرئيسي أسود ، من أجل وضع عناصرنا بشكل أكثر ملاءمة:







بعد ذلك ، سنضيف طريقة عرض سنعمل بها بشكل أساسي. للقيام بذلك ، انقر فوق علامة الجمع في أعلى اليمين ، والتي من خلالها يمكنك إضافة عناصر واجهة مستخدم ، وإضافة عنصر واجهة مستخدم جديد ، اكتب uiview في البحث :







بعد ذلك ، نقوم بسحب هذه الأداة إلى الشاشة الرئيسية ، ونحتاج إلى توسيعها إلى ملء الشاشة. لهذا نحن بحاجة للعمل مع constaint. للقيام بذلك ، انقر فوق الرمز الموجود في الجزء السفلي الأيسر ، والذي يشبه قليلاً سفينة Darth Vader ، وقم بتعيين 0 على كل جانب:







بعد ذلك ، سيتم توسيع عنصر واجهة المستخدم الجديد الخاص بك ليلائم الشاشة بأكملها. بعد ذلك ، تمامًا مثل المرة السابقة ، نحتاج إلى تغيير لون عنصر واجهة المستخدم الخاص بنا ، الآن فقط إلى Clear Color حتى لا يتداخل معنا ويمكننا وضع عناصر واجهة المستخدم فيه.



الآن يمكنك الذهاب إلى الملفViewController.swift، حيث سيكون لدينا كل ما تبقى من البرمجة. أولاً ، نحتاج إلى استخدام علامة خاصة @IBOutletحتى نتمكن من ربط Storyboard بكودنا. للقيام بذلك ، يجب أن نكتب السطر التالي:



@IBOutlet var holder: UIView!


الآن يمكننا ربط الكود بالقطعة. للقيام بذلك ، في الواقع ، تحتاج إلى توصيل حاملنا بالحامل. للقيام بذلك ، انقر بزر الماوس الأيمن viewControllerواسحب الحامل إلى شاشتنا:







أخيرًا ، انتهينا من ربط الكود بلوحة العمل ويمكننا بدء البرمجة.



بعد ذلك ، سنضيف متغيرين ، أولهما سيكون مجرد رقم يمكن كتابة القيمة الأولى فيه ، والثاني سيكون القيمة الناتجة. سيكون المتغير الثالث أكثر تحديدًا ، لأننا سنستخدم إعلانًا اختياريًا (يمكنك قراءة نوع الحيوان ، يمكنك قراءة المزيد هنا). اختياري يمكن أن يحتوي على أي قيمة أو لا شيء. تضمن الاختيارات أيضًا معالجة القيم الصفرية بشكل صريح. بالإضافة إلى ذلك ، سنضيف منذ البداية قائمة بالعمليات الحسابية التي تدعمها الآلة الحاسبة:



    var firstNumber = 0
    var resultNumber = 0
    var currentOperations: Operation?
        enum Operation {
        case add, subtract, multiply, divide
    }


بعد ذلك ، يتعين علينا إنشاء ملصق ، نعرض فيه الأرقام ونتائج الحسابات. بشكل افتراضي ، سيكون هناك 0 وخط كبير إلى حد ما. أعتقد أن كل شيء آخر واضح تمامًا:



    private var resultLabel: UILabel = {
        let label = UILabel()
        label.text = "0"
        label.textColor = .white
        label.textAlignment = .right
        label.font = UIFont(name: "Helvetica", size: 100)
        return label
    }()



بعد ذلك ، تخطي الطريقة المضمنة التي تستدعي التقديم (أتحدث عنها viewDidLoad) ، نحتاج إلى استدعاء طريقة ستستدعي وظيفة ترسم جميع الأزرار التي ستتوقف وظائف المعالج عليها.



    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()

        setupNumberPad() //,      
    }


بعد ذلك ، لدينا الوظيفة setupNumberPad. في البداية ، سأقوم بتعيين ثابت لحجم الخط لدينا ، بحيث يمكنك لاحقًا ، إذا كان هناك أي شيء ، زيادة / تقليل حجم الخط في التطبيق على الفور ، لأنني أعمل بدون تخطيط. بعد ذلك سوف أقوم بإنشاء حجم زر - سيكون عرضه مساويًا لربع حجم شاشة تطبيقنا.



    private func setupNumberPad() {
        let FontSize:CGFloat = 25 
        //      
        let buttonSize: CGFloat = view.frame.size.width / 4 
        //    1/4
        let zeroButton = UIButton(frame: CGRect(x: 0, y: holder.frame.size.height-buttonSize, width: buttonSize*3, height: buttonSize))
        //  UIButton     
        zeroButton.setTitleColor(.black, for: .normal) 
        //    
        zeroButton.backgroundColor = .white
        //   
        zeroButton.setTitle("0", for: .normal) 
        //    0
        zeroButton.titleLabel?.font = UIFont(name: "Helvetica", size: FontSize)
        // , family    
        zeroButton.tag = 1 
        //         
        holder.addSubview(zeroButton)  //    holder 
        zeroButton.addTarget(self, action: #selector(zeroTapped), for: .touchUpInside) 
        //       
 


0 يشغل ثلث الشاشة حتى نتمكن من الانتقال إلى العمود الأيمن للمعاملات الرياضية. بعد ذلك ، نحتاج إلى عرض جميع الأزرار بطريقة ما. بالطبع ، سيكون من الممكن رسمها واحدة تلو الأخرى ، ولكن بعد ذلك ستصبح طويلة وكئيبة. لان سيكون لدينا فقط سلسلة من الأرقام من 1 إلى 9 ، ثم يكون قرار استخدام الدورات ظاهريًا تمامًا. سأقدم الدورة الأولى مع التعليقات ، ومنذ ذلك الحين الاثنان الآخران هما في الأساس تكرار ، سأعطيهما مباشرة تحت الخفض:



        for x in 0..<3 {
            let button_row_1 = UIButton(frame: CGRect(x: buttonSize * CGFloat(x), y: holder.frame.size.height-(buttonSize*2), width: buttonSize, height: buttonSize))
            //   x     x
            button_row_1.setTitleColor(.black, for: .normal) //
            button_row_1.backgroundColor = .white // 
            button_row_1.setTitle("\(x+1)", for: .normal) //  
            holder.addSubview(button_row_1) //    
            button_row_1.tag = x+2 // .. 1  ,   2
            button_row_1.addTarget(self, action: #selector(numberPressed(_:)), for: .touchUpInside)
            // 
        }


باقي كود أرقامنا




       for x in 0..<3 {
            let button_row_2 = UIButton(frame: CGRect(x: buttonSize * CGFloat(x), y: holder.frame.size.height-(buttonSize*3), width: buttonSize, height: buttonSize))
            button_row_2.setTitleColor(.black, for: .normal)
            button_row_2.backgroundColor = .white
            button_row_2.setTitle("\(x+4)", for: .normal)
            button_row_2.addSubview(button_row_2)
            button_row_2.tag = x+5
            button_row_2.addTarget(self, action: #selector(numberPressed(_:)), for: .touchUpInside)
        }
        
        for x in 0..<3 {
            let button_row_3 = UIButton(frame: CGRect(x: buttonSize * CGFloat(x), y: holder.frame.size.height-(buttonSize*4), width: buttonSize, height: buttonSize))
            button_row_3.setTitleColor(.black, for: .normal)
            button_row_3.backgroundColor = .white
            button_row_3.setTitle("\(x+7)", for: .normal)
            holder.addSubview(button_row_3)
            button_row_3.tag = x+8
            button_row_3.addTarget(self, action: #selector(numberPressed(_:)), for: .touchUpInside)
        }
    




بعد ذلك ، نحتاج إلى وضع زر CE الخاص بنا ، والذي سنعيد ضبط البيانات التي تم إدخالها. سنضعه في الأعلى ، وسنصف حمله الوظيفي بعد ذلك بقليل. في الوقت الحالي ، نحتاج فقط إلى وضعه وتوصيل المعالجات:



        let clearButton = UIButton(frame: CGRect(x: 0, y: holder.frame.size.height-(buttonSize*5), width: view.frame.size.width - buttonSize, height: buttonSize))
        clearButton.setTitleColor(.black, for: .normal)
        clearButton.backgroundColor = .init(red: 0, green: 2, blue: 0.8, alpha: 1) //       rgb
         clearButton.titleLabel?.font = UIFont(name: "Helvetica", size: FontSize-4) //     
        clearButton.setTitle("CE", for: .normal)
        holder.addSubview(clearButton) //     holder
        clearButton.addTarget(self, action: #selector(clearResult), for: .touchUpInside) //  


لقد انتهينا من هذا الجزء المتكرر الممل ، والآن نحن جاهزون لشيء آخر - معاملاتنا التي يمكننا من خلالها إجراء العمليات الحسابية. بادئ ذي بدء ، نضع المعاملات الضرورية داخل المصفوفة ، ومن أين سنأخذها. سنضع أزرار المعامل نفسها في عمود ونضيف وظيفة معالج تتفاعل مع الضغط على معاملاتنا. سأجعل الأزرار بلون لطيف من المفاجأة الطفولية ، والأصفر ، والحجم أكبر قليلاً من أرقامنا.



        let operations = ["=","+", "-", "x", "÷"] //  

        for x in 0..<5 {
            let button_operand = UIButton(frame: CGRect(x: buttonSize * 3, y: holder.frame.size.height-(buttonSize * CGFloat(x+1)), width: buttonSize, height: buttonSize))
            button_operand.setTitleColor(.black, for: .normal)
            button_operand.backgroundColor = .init(red: 2, green: 0.8, blue: 0, alpha: 1) // 
            button_operand.setTitle(operations[x], for: .normal)
            holder.addSubview(button_operand)
            button_operand.tag = x+1 
            // ,       
            button_operand.titleLabel?.font = UIFont(name: "Helvetica", size: FontSize)
            button_operand.addTarget(self, action: #selector(operationPressed(_:)), for: .touchUpInside)
        }


بعد هذه العمليات العالمية ، نحتاج فقط إلى وضع التسمية ، حيث سنكتب النتيجة ، ونغلق الوظيفة:



    resultLabel.frame = CGRect(x: 20, y: clearButton.frame.origin.y - 110.0, width: view.frame.size.width - 40, height: 100)
    holder.addSubview(resultLabel)
} //    


الآن يمكنك الانتقال إلى المعالجات:



العمل مع المتعاملين



كل هذا كان في الأساس مجرد تخطيط ، والآن علينا أن نتنفس المنطق في التطبيق. للقيام بذلك ، سنستخدم طرقًا من وقت تشغيل الهدف C لتبسيط التعليمات البرمجية الخاصة بنا. إذا كنت لا تفهم ما يحدث ، يمكنني أن أوصي لك بقراءة هذه المقالة.



إذن ، ها هي وظائفنا:



    @objc func clearResult() {
        resultLabel.text = "0" //    0
        currentOperations = nil //    
        firstNumber = 0 //      0
    }
    
    @objc func zeroTapped() {
        //    
        if resultLabel.text != "0" {
            if let text = resultLabel.text {
                resultLabel.text = "\(text)\(0)" //  
            }
        }
    }


بعد ذلك ، نحتاج إلى إضافة وظيفة معالج إلى أزرارنا:



    @objc func numberPressed(_ sender: UIButton) {
        let tag = sender.tag - 1
        
        if resultLabel.text == "0" {
            resultLabel.text = "\(tag)"
        }
        else if let text = resultLabel.text {
        //   
            resultLabel.text = "\(text)\(tag)"
        }
    }



التالي هو أهم منطق عمل لتطبيقنا. سنستخدم بنية التبديل للتحكم في عمليات الرياضيات لدينا:



 @objc func operationPressed(_ sender: UIButton) {
        let tag = sender.tag
        
        if let text = resultLabel.text, let value = Int(text), firstNumber == 0 {
            //   
            firstNumber = value
            resultLabel.text = "0"
        }
        
        if tag == 1 {
            if let operation = currentOperations {
                var secondNumber = 0
                if let text = resultLabel.text, let value = Int(text) {
                    secondNumber = value
                }
                
                switch operation {
                case .add:
                    
                    firstNumber = firstNumber + secondNumber
                    secondNumber = 0 //  
                    resultLabel.text = "\(firstNumber)" 
                    currentOperations = nil
                    firstNumber = 0 //     Label 
                    
                    break
                    
                case .subtract:
                    firstNumber = firstNumber - secondNumber
                    secondNumber = 0
                    resultLabel.text = "\(firstNumber)"
                    currentOperations = nil
                    firstNumber = 0
                    
                    break
                    
                case .multiply:
                    firstNumber = firstNumber * secondNumber
                    secondNumber = 0
                    resultLabel.text = "\(firstNumber)"
                    currentOperations = nil
                    firstNumber = 0
                    
                    break
                    
                case .divide:
                    firstNumber = firstNumber / secondNumber
                    secondNumber = 0
                    resultLabel.text = "\(firstNumber)"
                    currentOperations = nil
                    firstNumber = 0
                    break
                }
            }
        }
        else if tag == 2 {
            currentOperations = .add 
            //     .    ,    
        }
        else if tag == 3 {
            currentOperations = .subtract
        }
        else if tag == 4 {
            currentOperations = .multiply
        }
        else if tag == 5 {
            currentOperations = .divide
        }
    }
}



هذا كل شئ! يمكن العثور على الكود المصدري لهذا التطبيق على هذا الرابط. نتيجة لذلك ، ظهر المظهر على النحو التالي:







وفقًا للتقاليد ، سأقدم العديد من الموارد المفيدة التي قد تكون مفيدة لمطور IOS المبتدئ:








بداية سريعة لتطوير iOS. ندوة مجانية على الويب







All Articles