RubyMotion: रूबी में देशी iOS एप्लिकेशन (अनुवाद)


2007 में, एक Apple डेवलपर, लॉरेंट संसेनेटी ने एक ओपन सोर्स प्रोजेक्ट MacRuby की स्थापना की। उनका लक्ष्य ऑब्जेक्टिव-सी रनटाइम के ऊपर एक रूबी दुभाषिया बनाना था जो रूबी और कोको ओएस एक्स पारिस्थितिकी तंत्र के बीच एक पारदर्शी बातचीत प्रदान करेगा - और वह सफल रहा। अब, Sansonetti iOS पर कुछ ऐसा ही करने की उम्मीद करता है।


हाल ही में, सेनसोनेट्टी ने Apple छोड़ दिया, जहां उन्होंने हिपबाइट नामक अपना स्टार्टअप स्थापित करने के लिए पिछले सात वर्षों तक काम किया। उन्होंने आज [ 3 मई - लगभग] अपने पहले उत्पाद की घोषणा की ट्रांस। ] रूबीमोशन नामक एक विकास उपकरण है जो रूबी प्रोग्रामिंग भाषा में देशी आईओएस अनुप्रयोगों को लिखने की संभावनाओं को खोलेगा।

मैंने मार्च से रूबीमोशन का परीक्षण किया जब संसेनेट्टी ने मुझे एक जल्दी बंद बीटा उत्पाद तक पहुंच प्रदान की। इस लेख में, मैं RubyMotion की एक विशेष प्रथम-स्तरीय समीक्षा प्रस्तुत करूंगा और यह वर्णन करूंगा कि इसका उपयोग iOS सॉफ्टवेयर लिखने के लिए कैसे किया जा सकता है। इस लेख में एक सरल iOS डेमो के लिए सभी स्रोत कोड शामिल हैं जो मैंने बनाया था जो रेडिट पर शीर्ष पदों की एक सूची प्रदर्शित करता है।

RubyMotion

RubyMotion बहुत ही Objective-C Ruby कार्यान्वयन के शीर्ष पर बनाया गया है जो MacRuby के पीछे खड़ा है लेकिन रूबी कोड को अनुकूलित देशी कोड में बदलने के लिए नए LLVM कंपाइलर का उपयोग करता है। रूबीमोशन संकलक प्रभावी देशी अनुप्रयोगों की पैदावार करता है जिनमें नियमित रूबी कोड में निहित प्रदर्शन सीमाएँ नहीं होती हैं।



रूबीमोशन के साथ बनाए गए मोबाइल एप्लिकेशन ऑब्जेक्टिव-सी पर उनके समकक्षों के रूप में तेजी से चलते हैं और हार्डवेयर संसाधनों की एक कम मात्रा का उपयोग करते हैं। इसके अलावा, RubyMotion एप्लिकेशन पूरी तरह से ऐप्पल के ऐप स्टोर की आवश्यकताओं को पूरा करते हैं। सेनसोनेट्टी के अनुसार, ऐप्प स्टोर में कई रूबीमोशन एप्लिकेशन पहले ही स्वीकार किए जा चुके हैं, जो सत्यापन के सभी चरणों को पारित कर चुके हैं।

सभी मानक आईओएस एपीआई रूबीमोशन में उपलब्ध हैं, जिसका अर्थ है कि ऑब्जेक्टिव-सी डेवलपर्स की सभी सुविधाएँ रूबी डेवलपर्स के लिए उपलब्ध हैं। इसके अलावा, रूबीमोशन एप्लिकेशन बाकी प्लेटफॉर्म के लुक से मेल खा सकते हैं, जैसा कि UIKit से विजेट के मानक सेट का उपयोग करें।

रूबीमोशन के साथ सॉफ्टवेयर डेवलपमेंट

Apple के IDE में RubyMotion को एम्बेड करने की कोशिश करने के बजाय, Sansonetti ने रूबी के लिए अधिक पारंपरिक तरीके से जाने का फैसला किया - कमांड लाइन टूल का उपयोग करने के लिए। मोशन कंसोल टीम एक नए प्रोजेक्ट का निर्माण करती है जिसमें एक कोड का उपयोग किया जाता है जिसमें कोड, ग्राफिक्स और अन्य संसाधनों के लिए फ़ोल्डर के साथ एक एप्लिकेशन रिक्त होता है। कोई भी .rb फ़ाइल जो अनुप्रयोग निर्देशिका में है, स्वचालित रूप से अंतिम असेंबली में संकलित की जाएगी। RubyMotion में, आवश्यकता कीवर्ड का उपयोग करने की कोई आवश्यकता नहीं है।

रूबीमोशन में निर्माण प्रक्रिया ज्यादातर रूबी प्रोग्रामर से परिचित रेक टूल पर निर्भर करती है। निर्भरता और अन्य एप्लिकेशन सेटिंग्स को निर्दिष्ट करने के लिए रेक बिल्ड विकल्पों का उपयोग किया जाता है। जब रेक कमांड लाइन से शुरू होता है, तो एप्लिकेशन को आईओएस सिम्युलेटर पर संकलित और लॉन्च किया जाएगा।

सिम्युलेटर में एप्लिकेशन लॉन्च करने के अलावा, आरईपीएल टर्मिनल में उपलब्ध है, जो आपको रूबी अभिव्यक्तियों का उपयोग करके रनिंग एप्लिकेशन के साथ इंटरेक्टली इंटरैक्ट करने की अनुमति देता है। परीक्षण पर और त्रुटियों का पता लगाने पर विजेट के गुणों और आंतरिक डेटा संरचनाओं में परिवर्तन करने की क्षमता बेहद उपयोगी है।



आप अपने डिवाइस पर एक एप्लिकेशन लॉन्च करने के लिए रेक में लक्ष्य का उपयोग कर सकते हैं या एक .ipa पैकेज बना सकते हैं और इसे ऐप स्टोर में वितरित कर सकते हैं। डिजिटल कोड साइनिंग पर प्रतिबंध के कारण, उपकरणों पर आपके एप्लिकेशन का परीक्षण करने के लिए आपके पास Apple डेवलपर प्रोग्राम की सदस्यता होनी चाहिए।

मेरे रूबीमोशन सिम्युलेटर पर रेडिट डेमो को संकलित और चलाना मैकबुक एयर 2011 में लगभग पांच सेकंड का समय लगा। संकलन का समय बहुत लंबा नहीं है, लेकिन यह रूबी डेवलपर्स के लिए असामान्य दिखता है, जो बदलाव करने के तुरंत बाद परिणाम देखने के लिए उपयोग किए जाते हैं। संकलक के अलावा, रूबीमोशन अपने स्वयं के ruby कमांड के साथ आता है, जो आपको रूबीमिशन वातावरण में रूबी स्क्रिप्ट चलाने की अनुमति देता है।

रूबीमोशन पर विकास की प्रक्रिया काफी आरामदायक है। मैं Vim में कोड लिखता हूं और प्रोग्राम को जांचने के लिए Rake शुरू करके टर्मिनल को खुला रखता हूं। Xcode की तुलना में एक प्रमुख दोष दृश्य इंटरफ़ेस डिज़ाइन टूल का उपयोग करने में असमर्थता है। यह नौसिखिया डेवलपर्स के लिए समस्या पैदा कर सकता है क्योंकि उन्हें UIKit एपीआई में तल्लीन करना होगा।

संनसोती से बात करो

मैंने उनसे Xcode विज़ुअल टूल्स के साथ असंगति के बारे में पूछा, उन्होंने जवाब दिया कि Xcode के साथ एकीकरण लागू किया जाएगा, लेकिन निकट भविष्य में नहीं।

इसके बजाय, वह प्रोग्रामैटिक रूप से iOS इंटरफेस बनाने के लिए रूबी लाइब्रेरी का एक सेट बनाता है। ये लाइब्रेरी UIKit API पर उच्च-स्तरीय आवरण होंगे, जिनका उपयोग करना बहुत आसान है। यह तरीका MacRuby के लिए HotCocoa लाइब्रेरी के समान है, लेकिन उच्च स्तर के अमूर्त के साथ।

“हम RubyMotion के लिए उच्च-स्तरीय रूबी रत्नों का एक सेट बनाने पर ध्यान केंद्रित कर रहे हैं। उनमें से एक UIKit पर एक हल्का आवरण है, “संसेनेति ने मुझे बताया। “हमने एक विषय-उन्मुख भाषा का उपयोग करके सीएसएस की तरह एक इंटरफ़ेस मार्कअप प्रणाली को लागू करने का निर्णय लिया, इसलिए रूबी डेवलपर्स घर पर सही महसूस करेंगे। हमारा विचार कोको ऑटो लेआउट के समान है [ कोको ऑटो लेआउट - लगभग। ट्रांस। ], जो ASCII जैसी भाषा में बनाया गया है, लेकिन हम इसे रूबी में भी बेहतर कर सकते हैं। हमारा मानना ​​है कि यह इंटरफ़ेस बिल्डर की तुलना में UI बनाने का एक अधिक विश्वसनीय तरीका है, क्योंकि आप कोड में यह सब देख सकते हैं। ”

रूबिनमोशन में इन पुस्तकालयों को एम्बेड करने के बजाय, संसेनेटेटी उन्हें लाइसेंस लाइसेंस के तहत गिटहब पर डालने जा रहा है। उनका मानना ​​है कि रूबीमोशन समर्थक विभिन्न शैलियों के साथ अपने स्वयं के मार्कअप पुस्तकालयों का निर्माण करेंगे। और एप्लिकेशन डेवलपर्स के पास एक व्यापक विकल्प होगा - देशी रैपर या तीसरे पक्ष के लोगों का उपयोग करें।

मैंने संसेनेटी से मैक्रूबी परियोजना के बारे में उनकी बातचीत के बारे में पूछा, जिसे उन्होंने Apple के ओपन सोर्स प्रोजेक्ट के रूप में स्थापित किया, और रूबीमोशन को विकसित करने पर ध्यान केंद्रित करने के बाद अब यह परियोजना कैसे विकसित होगी। उन्होंने समझाया कि मैकब्रुबी पर काम करना जारी रखने की इच्छा उनके एप्पल से हटने और उनकी कंपनी के निर्माण का मुख्य कारण थी।

"Apple में कोर OS टीम के मुख्य डेवलपर के रूप में, मैंने MacRuby को बनाया और विकसित किया, लेकिन MacRuby मेरी सभी जिम्मेदारियों का केवल एक हिस्सा था," उन्होंने कहा। “मैक्रूबी काफी स्थिर हो जाने के बाद, मुझे एहसास हुआ कि मुझे इसके विकास को छोड़ना होगा। मैं इस परियोजना और इसके अद्भुत समुदाय को छोड़ना नहीं चाहता था, इसलिए कुछ समय के लिए इसके बारे में सोचने के बाद, मुझे एहसास हुआ कि रूबीमोशन स्टार्टअप बनाना सबसे अच्छा होगा जो मैं कर सकता था - मैं MacRuby पर काम करना जारी रखूंगा और एक ही समय में जीवित रहूंगा। ”

हालाँकि उन्हें Apple छोड़ने के बाद छह महीने की संक्रमण अवधि के दौरान मैक्रूबी के विकास में अस्थायी रूप से भाग लेने से रोकने के लिए मजबूर किया गया था, अब वह वापस लौट आया है और काम करना बंद नहीं करने वाला है। वह वर्तमान में अपनी नई कंपनी का एकमात्र कर्मचारी है, लेकिन "मैकराबी समुदाय के कई सदस्यों को वर्ष के अंत के करीब है।"

अकेले रूबीमोशन बनाना एक कठिन तकनीकी कार्य था। हमने उनसे कुछ बिंदुओं का वर्णन करने के लिए कहा, जिन्हें उन्हें विकास के दौरान दूर करना था।

"सबसे कठिन हिस्सा रूबीमोशन के लिए पूरी तरह से नए स्थिर संकलक और मेमोरी मॉडल का कार्यान्वयन था," उन्होंने कहा। “एआरएम एबीआई और निम्न-स्तरीय प्रोटोकॉल का कार्यान्वयन भी जटिल था। इससे उपकरणों पर निष्पादन की गति को ठीक करने में काफी समय लगा। "

Sansonetti ने अपने दृष्टिकोण को भी साझा किया कि रूबी कैसे अभिव्यंजक और लचीली है, विकास की गति में सुधार कर सकती है।

“सबसे महत्वपूर्ण फ़िच में से एक इंटरएक्टिव वातावरण है जो माणिक के लिए दी जाती है, जो कई अन्य प्लेटफार्मों पर गायब है। डिबगिंग और एप्लिकेशन का परीक्षण करते समय वास्तविक समय में परिवर्तनों को देखने में सक्षम होना बहुत उपयोगी है, ”उन्होंने कहा। “रूबी एक संक्षिप्त और अभिव्यंजक भाषा है। एक रूबी आईओएस एप्लीकेशन में एक समान ऑब्जेक्टिव-सी एप्लिकेशन की तुलना में कोड की काफी कम लाइनें होंगी। कम कोड का अर्थ है छोटा विकास चक्र, कम बग, आसान रखरखाव, जिसका मतलब है कि स्किरीम खेलने के लिए अधिक समय। "

पुलों का निर्माण

इससे पहले कि हम एक कामकाजी एप्लिकेशन बनाएं, आइए एक नज़र डालते हैं कि रूबीमोशन रूबी और ऑब्जेक्टिव-सी रनटाइम को कैसे पुल करता है।

ऑब्जेक्टिव-सी एक सी एक्सटेंशन है जो वैकल्पिक गतिशील टाइपिंग और ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग जैसी सुविधाओं को जोड़ता है। NeXT ने इस प्रोग्रामिंग लैंग्वेज को Stepstone से लाइसेंस लिया, जो कि भाषा के स्रोत पर था, और इसका उपयोग NeXTstep OS के लिए चौखटे बनाने के लिए किया, जो बाद में Mac OS X बन गया। तब से, Apple ने Objective-C को परिष्कृत और बेहतर करना जारी रखा है।

ऑब्जेक्टिव-सी में रूबी के साथ कई सामान्य गुण हैं जो भाषाओं के बीच बातचीत की सुविधा प्रदान करते हैं। रूबी और ऑब्जेक्टिव-सी में स्मॉलटाक से एक समान विधि मंगलाचरण है - जो संदेश भेज रहा है। उनके ऑब्जेक्ट मॉडल समान हैं कि वे एकल विरासत का निरीक्षण करते हैं और महान आत्मनिरीक्षण क्षमता रखते हैं। ऑब्जेक्टिव-सी को हाल ही में रूबी ब्लॉक के समान हल्के अनाम फ़ंक्शन बनाने के लिए एक नया वाक्यविन्यास तंत्र प्राप्त हुआ है।

इस तथ्य के बावजूद कि रूबीमोशन को विकसित करते समय ये विशेषताएं आपको परिचित करती हैं, मरहम में एक मक्खी है। सबसे बड़ी बाधा ऑब्जेक्टिव-सी और उनके कॉल में विधि हस्ताक्षरों की प्रस्तुति है, जो डेवलपर्स को अन्य सामान्य प्रोग्रामिंग भाषाओं में देखने से मौलिक रूप से अलग है।

ऑब्जेक्टिव-सी में तरीके इसलिए बनाए गए हैं ताकि पैरामीटर उनके नाम का हिस्सा हों। पहली नज़र में, यह एक नामकरण सम्मेलन की तरह लग सकता है, लेकिन व्यवहार में यह अलग है (उद्देश्य-सी विधियों के वाक्यविन्यास का विवरण इस लेख के दायरे से परे है, लेकिन विस्तृत विवरण के साथ कई संसाधन हैं)।

रूबीमोशन उपयोगकर्ताओं के लिए मुख्य निष्कर्ष यह है कि ऑब्जेक्टिव-सी एपीआई को रूबी पर उपयोग किए जाने पर थोड़ा असामान्य प्रारूप में प्रस्तुत किया जाता है। समस्या का वर्णन करने के लिए, मैं आपको UIKit से एक उदाहरण दिखाने जा रहा हूं जिसका उपयोग लेख में बाद में डेमो रेडिट एप्लिकेशन में किया जाएगा। इस एप्लिकेशन में, मुझे एक तालिका में एक पंक्ति को अचयनित करने की आवश्यकता है। ऑब्जेक्टिव-सी में, यह इस तरह दिखता है:

 [tableView deselectRowAtIndexPath:indexPath animated:YES] 


वास्तविक विधि का नाम deselectRowAtIndexPath:animated । पैरामीटर के मान जो NSIndexPath * और BOOL प्रकार के होते हैं, उन्हें फ़ंक्शन के नाम पर उस जगह पर एम्बेड किया जाता है जिसे वे कहते हैं। रूबी में यह वाक्य-विन्यास नहीं है। आप अभी भी नामित मापदंडों पर कन्वेंशन का पालन करते हैं, लेकिन कोष्ठक के साथ एक अधिक पारंपरिक शैली में:

 tableView.deselectRowAtIndexPath(indexPath, animated:true) 


MacRuby और RubyMotion में एक हाइब्रिड सिस्टम है जो उन्हें ऑब्जेक्टिव-सी के बराबर होने की अनुमति देता है। इस संकर प्रणाली में, सभी मानक रूबी प्रकार मानक ऑब्जेक्टिव-सी प्रकार के शीर्ष पर कार्यान्वित किए जाते हैं। उदाहरण के लिए, सभी रूबी ऑब्जेक्ट NSObject से विरासत में मिलते हैं, और Ruby में कोई भी स्ट्रिंग NSMutableString है। आप MacRuby एप्लिकेशन कंसोल में String.ancestors कमांड को कॉल करके इसका क्या अर्थ है, इसका अंदाजा लगा सकते हैं:

 => [String, NSMutableString, NSString, Comparable, NSObject, Kernel] 


रनटाइम के ढांचे के भीतर इस प्रकार की समतुल्यता बहुत प्रभावी है। रूबी और ऑब्जेक्टिव-सी एपीआई के बीच जटिल डेटा प्रकारों को परिवर्तित करने के लिए भारी कंप्यूटिंग करने की आवश्यकता नहीं है।

एक और लाभ यह है कि इन आधार वर्गों के साथ आने वाले सभी आमतौर पर उपयोग किए जाने वाले और उपयोगी तरीके सार्वभौमिक रूप से उपलब्ध हो गए हैं। कंटेनरों के साथ काम करते समय यह एक बड़ा फायदा देता है, उदाहरण के लिए, जब ब्लॉक किए गए तरीकों NSMutableArray map , group_by और sort_by करते हैं।

डेमो आवेदन

पिछले एक महीने में, मैंने रूबीमोशन पर कई एप्लिकेशन बनाए हैं, और इसे सरल मैकआरबी एप्लिकेशन को आईओएस में पोर्ट करने के लिए भी उपयोग किया है। इस लेख में, मैं आपको एक सरल डेमो एप्लिकेशन दिखाना चाहता हूं जो मैंने कुछ यूआईसीआईटी एपीआई के साथ काम करते समय लिखा था।

यह एप्लिकेशन Reddit वेबसाइट के लिए एक सरल क्लाइंट है। यह Reddit JSON API के माध्यम से वर्तमान शीर्ष पदों की सूची को डाउनलोड करता है, फिर डेटा को पार्स करता है और इसे स्क्रीन पर तालिका के रूप में प्रदर्शित करता है। जब उपयोगकर्ता सूची में किसी आइटम पर टैप करता है, तो संबंधित लिंक मोबाइल सफारी में खुलता है।

 class RedditPost attr_accessor :title, :url, :author attr_accessor :comments, :score attr_accessor :subreddit def initialize(data) @url = data["url"] @title = data["title"] @author = data["author"] @comments = data["num_comments"] @link = data["permalink"] @score = data["score"] @subreddit = data["subreddit"] end end class RedditController < UITableViewController def viewDidLoad @posts = [] view.dataSource = view.delegate = self refresh "top.json" end def tableView(tv, numberOfRowsInSection:section) @posts.size end def tableView(tv, cellForRowAtIndexPath:indexPath) cid = "PostCell" cell = tv.dequeueReusableCellWithIdentifier(cid) || UITableViewCell.alloc.initWithStyle( UITableViewCellStyleSubtitle, reuseIdentifier:cid) p = @posts[indexPath.row] cell.textLabel.text = p.title cell.detailTextLabel.text = "Posted by #{p.author} in #{p.subreddit}" cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator cell end def tableView(tv, didSelectRowAtIndexPath:indexPath) url = NSURL.URLWithString @posts[indexPath.row].url UIApplication.sharedApplication.openURL url tv.deselectRowAtIndexPath(indexPath, animated:true) end def get(address) err = Pointer.new_with_type "@" url = NSURL.URLWithString address raise "Loading Error: #{err[0].description}" unless data = NSData.alloc.initWithContentsOfURL( url, options:0, error:err) raise "Parsing Error: #{err[0].description}" unless json = NSJSONSerialization.JSONObjectWithData( data, options:0, error:err) json end def refresh(endpoint) Dispatch::Queue.concurrent.async do begin response = get "http://reddit.com/#{endpoint}" data = response["data"]["children"].map {|i| RedditPost.new i["data"] } Dispatch::Queue.main.sync { @posts = data; view.reloadData } rescue Exception => msg puts "Loading Failed: #{msg}" end end end end class AppDelegate def application(app, didFinishLaunchingWithOptions:launchOptions) @win = UIWindow.alloc.initWithFrame( UIScreen.mainScreen.applicationFrame) @win.rootViewController = RedditController.alloc.initWithStyle( UITableViewStylePlain) @win.rootViewController.wantsFullScreenLayout = true @win.makeKeyAndVisible return true end end 


पूरे एप्लिकेशन को कोड की 100 से कम लाइनों के साथ एक .rb फ़ाइल के रूप में डिज़ाइन किया गया है। AppDelegate वर्ग में application विधि को तब शुरू किया जाता है जब आवेदन शुरू होता है। हम इस पद्धति का उपयोग उस दृश्य का उदाहरण बनाने और प्रदर्शित करने के लिए करते हैं, जिसे हम उपयोगकर्ता को स्टार्टअप पर दिखाना चाहते हैं।

RedditController क्लास में लगभग सभी एप्लिकेशन लॉजिक को लागू किया गया है, जो UITableViewController का एक उपवर्ग है। viewDidLoad विधि, जिसे तब कहा जाता है जब वर्ग को उपयोगकर्ता इंटरफ़ेस में लोड किया जाता है, उदाहरण चर पोस्ट वाले सेट करता है, और फिर refresh विधि को कॉल करता है, जो डेटा लोड करता है।

refresh मेथड कॉल्स get , जो JSON फॉर्मेट में डेटा डाउनलोड करने के लिए NSData क्लास का उपयोग करता है और इसे आसानी से इस्तेमाल होने वाले डेटा स्ट्रक्चर में बदलने के लिए NSJSONSerialization का उपयोग करता है। आपने देखा होगा कि refresh पद्धति बैकग्राउंड स्ट्रीम में डेटा को लोड और परिवर्तित करने के लिए ग्रैंड सेंट्रल डिस्पैच (जीसीडी) का उपयोग करती है।

RedditController क्लास में कई RedditController विधियाँ व्यवहार के विभिन्न पहलुओं को संभालती हैं। tableView:cellForRowAtIndexPath उपयोग पंक्ति वस्तुओं को बनाने और उन्हें डेटा के साथ पॉप्युलेट करने के लिए किया जाता है। tableView:didSelectRowAtIndexPath को उस समय कहा जाता है जब उपयोगकर्ता तालिका में किसी तत्व पर टैप करता है। इस पद्धति का कोड यह निर्धारित करता है कि किस ऑब्जेक्ट को चुना गया था और ब्राउज़र में इस ऑब्जेक्ट का URL खोलता है, और फिर ऑब्जेक्ट से चयन हटाता है।

निष्कर्ष

RubyMotion iOS एप्लिकेशन डेवलपर्स को बिना समझौता किए रूबी की शक्ति और अभिव्यक्ति प्रदान करता है। IOS के लिए देशी एप्लिकेशन विकसित करने के लिए अधिक आकर्षक तरीके की कल्पना करना मुश्किल है। रूबीमोशन का कार्यान्वयन वास्तव में प्रभावशाली है, और अंतर्निहित प्रौद्योगिकियां परिपक्व हैं।

कुछ समय रूबिनमोशन के साथ विकासशील अनुप्रयोग बिताए जाने के बाद, एकमात्र दोष यह था कि यूजर इंटरफेस बनाने के लिए Xcode के साथ एकीकरण की कमी थी। UIKit के साथ अनुभव के बिना डेवलपर्स के लिए, मैन्युअल रूप से कोड लिखना समय लेने और जटिल हो सकता है।

हालांकि यह दोष रूबी के साथ काम करने की उत्पादकता से इनकार नहीं करता है, नए डेवलपर्स को प्रशिक्षण के प्रारंभिक चरण से गुजरना होगा, इससे पहले कि वे रूबीमोशन से पूरी तरह से लाभ उठा सकें। सौभाग्य से, उच्च-स्तरीय पुस्तकालय जो जल्द ही आ रहे हैं, उन्हें इसे ठीक करना चाहिए।

रूबीमोशन लाइसेंस, जिसमें वार्षिक अपडेट समर्थन शामिल है, की कीमत $ 199.99 है। अब इसे $ 149.99 की छूट पर खरीदा जा सकता है। अधिक जानकारी उत्पाद की आधिकारिक वेबसाइट पर देखी जा सकती है। वहां आप प्रैग्मेटिक स्टूडियो से ओपनिंग स्क्रैनेस्ट देख सकते हैं।

यह लेख एक अनुवाद है। मूल यहाँ उपलब्ध है

Source: https://habr.com/ru/post/In143332/


All Articles