Menggunakan Bahasa Skrip CSCS Untuk Pengembangan Lintas-Platform

Diterbitkan: 2022-03-10
Ringkasan cepat Dalam artikel ini, Vassili Kaplan menjelaskan bagaimana Anda dapat menggunakan bahasa skrip untuk mengembangkan aplikasi seluler lintas platform. Anda akan menemukan contoh di iOS dan Android yang mencakup penempatan widget di layar, SQLite, Permintaan Web, dan penguraian JSON.
Tujuan kami bukan untuk membangun platform; itu harus menyeberangi mereka semua.

- Mark Zuckerberg

CSCS (Customized Scripting in C#) adalah bahasa scripting open-source yang diimplementasikan dalam C#. Secara sintaksis sangat mirip dengan JavaScript, tetapi juga memiliki beberapa kesamaan dengan Python. Beberapa kesamaan ini adalah kata kunci dalam konstruk if…elif…else terkenal, dan juga memiliki definisi cakupan variabel yang sama seperti di Python (misalnya variabel yang didefinisikan di dalam blok if atau di dalam loop juga akan terlihat di luar) .

Berbeda dengan JavaScript dan Python, variabel dan fungsi dalam CSCS tidak peka huruf besar-kecil. Tujuan utama CSCS adalah membiarkan pengembang menulis kode sesedikit mungkin . Juga, kode yang sama digunakan untuk pengembangan iOS dan Android. Selain itu, CSCS dapat digunakan untuk pengembangan Windows, Mac, dan Unity.

Catatan : Anda dapat membaca lebih lanjut tentang bagaimana Microsoft menggunakan CSCS dalam produk Maquette mereka (berdasarkan Unity) di sini.

CSCS dapat ditambahkan ke proyek Anda dengan menyematkan kode sumber C# ke dalam proyek Visual Studio Xamarin. Tidak seperti kebanyakan bahasa lain, Anda memiliki kepemilikan penuh atas kode sumber CSCS dan dapat dengan mudah menambah atau mengubah fungsinya. Saya akan membagikan contoh ini nanti di artikel.

Selain itu, kita akan mempelajari cara memulai CSCS dan menggunakan beberapa fitur lanjutan yang telah dibahas di artikel lain. Di antara fitur-fitur ini, kami akan mengakses Layanan Web melalui Permintaan Web dengan penguraian string JSON, dan kami juga akan menggunakan SQLite di iOS dan Android.

Cara termudah untuk memulai adalah mengunduh contoh proyek menggunakan CSCS dan mulai bermain dengan file start.cscs . Inilah yang akan kita lakukan di bagian selanjutnya: membuat aplikasi iOS/Android dengan GUI dan acara dasar.

Lebih banyak setelah melompat! Lanjutkan membaca di bawah ini

"Halo Dunia!" Di CSCS

Mari kita mulai dengan contoh kode CSCS yang relatif sederhana yang membuat layar dengan beberapa widget:

 AutoScale(); SetBackgroundColor("light_green"); locLabelText = GetLocation("ROOT", "CENTER", "ROOT", "TOP"); AddLabel(locLabelText, "labelText", "Welcome " + _DEVICE_INFO_ + " " + _VERSION_INFO_ + " User!", 600, 100); locTextEdit = GetLocation("ROOT", "LEFT", labelText, "BOTTOM"); AddTextEdit(locTextEdit, "textEdit", "Your name", 320, 80); locButton = GetLocation(textEdit,"RIGHT",textEdit, "CENTER"); AddButton(locButton, "buttonHi", "Hello", 160, 80); function buttonHi_click(sender, arg) { name = getText(textEdit); msg = name != "" ? "Hello, "+ name + "!" : "Hello, World!"; AlertDialog("My Great App", msg); }

Gambar di bawah menunjukkan antarmuka pengguna yang dihasilkan pada iPhone serta perangkat Android setelah mengklik tombol "Halo" dan tidak mengetik apa pun di bidang "Edit Teks":

Halo Dunia!" di iPhone (kiri) dan Android (kanan)
"Halo Dunia!" di iPhone (kiri) dan Android (kanan) (Pratinjau besar)

Mari kita bahas kode di atas secara singkat. Ini dimulai dengan pemanggilan fungsi AutoScale() , dan yang dilakukannya adalah memberi tahu parser bahwa ukuran widget relatif terhadap ukuran layar, yaitu ukurannya akan diubah secara otomatis (widget akan terlihat lebih besar pada layar yang lebih besar dan lebih kecil pada layar yang lebih kecil layar). Pengaturan ini juga dapat diganti per widget.

Perhatikan bahwa tidak perlu membuat handler khusus pada klik tombol. Jika Anda mendefinisikan sebuah fungsi dengan nama widgetName_click() , itu akan digunakan sebagai handler ketika pengguna mengklik widget yang disebut widgetName (tidak harus berupa tombol, itu sebenarnya bisa berupa widget apa saja). Itu sebabnya fungsi buttonHi_click() akan dipicu segera setelah pengguna mengklik tombol.

Anda mungkin telah memperhatikan bahwa GUI dibangun sepenuhnya dalam kode. Ini dilakukan dengan menyediakan lokasi widget relatif saat menambahkannya. Format umum dari perintah lokasi adalah sebagai berikut:

 location = GetLocation(WidgetX, HorizontalPlacement, WidgetY, VerticalPlacement, deltaX=0, deltaY=0, autoResize=true);

Jadi, Anda dapat menempatkan widget relatif terhadap widget lain di layar. Kasus khusus widget adalah widget "ROOT", yang berarti layar utama.

Setelah membuat lokasi, Anda perlu memberikannya sebagai argumen untuk salah satu fungsi berikut:

  • AddLabel ,
  • AddButton ,
  • AddCombobox ,
  • AddStepper ,
  • AddListView ,
  • AddTextView ,
  • AddStepper ,
  • AddImageView ,
  • AddSlider ,
  • AddPickerView ,
  • dan seterusnya.

Semua hal di atas memiliki struktur yang sama:

 AddButton(location, newWidgetname, initialValue, width, height);

Lebar dan tinggi widget akan relatif terhadap ukuran layar jika perintah CSCS AutoScale() dijalankan sebelumnya. Juga, nilai awal (dalam kasus tombol) adalah teks yang ditampilkan di atasnya. Ini dapat diubah kapan saja dengan menjalankan SetText(widgetName, newText) .

Menggunakan Kode Visual Studio Untuk Debug CSCS

Kami juga dapat menggunakan Visual Studio Code untuk men-debug skrip CSCS. Jika Anda ingin mengembangkan aplikasi untuk Android dan iOS, Anda perlu menggunakan Mac. Setelah menginstal Visual Studio Code, instal ekstensi CSCS Debugger dan REPL.

Untuk menggunakan ekstensi, tambahkan baris kode ini di mana saja di skrip CSCS start.cscs Anda:

 StartDebugger();

Gambar berikut di bawah ini menunjukkan bagaimana Anda dapat menggunakan Visual Studio Code untuk men-debug dan mengubah fungsionalitas "Hello, World!" aplikasi yang kami kembangkan di bagian sebelumnya. Dalam contoh yang akan datang, kami akan menambahkan label dan tombol dengan cepat ke tata letak yang ada.

Untuk melakukan ini, kita tinggal memilih kode yang akan dieksekusi oleh parser dan tekan Ctrl + 8 . Akibatnya, label dan tombol akan ditambahkan di tengah layar. Kami juga menambahkan pengendali tombol yang akan memperbarui label baru dengan waktu saat ini pada setiap klik tombol.

Mengubah Tata Letak dengan cepat dengan Visual Studio Code
Mengubah Tata Letak dengan cepat dengan Visual Studio Code (Pratinjau besar)

Menggunakan SQLite Di CSCS

SQLite adalah tipe ACID (Atomicity, Consistency, Isolation, Durability) dari database relasional, dan dikembangkan oleh Richard Hipp (versi pertama dirilis pada tahun 2000). Berbeda dengan database relasional lainnya, seperti Microsoft SQL Server atau Oracle Database, itu tertanam. (Tertanam tidak hanya ke dalam perangkat, tetapi juga ke dalam program akhir.) Ini termasuk dalam program sebagai perpustakaan yang sangat ringkas, yang berukuran kurang dari 500 KB. Tetapi dua aplikasi (dirilis oleh pengembang yang sama) dapat membaca DB SQLite yang sama jika jalur file DB diketahui oleh kedua aplikasi.

Kelebihan SQLite adalah dapat digunakan tanpa instalasi tambahan di perangkat iOS atau Android. Kerugiannya adalah jelas tidak dapat menampung data sebanyak DB "normal" dan juga tipenya lemah (yaitu Anda dapat memasukkan string alih-alih bilangan bulat — ia kemudian akan diubah menjadi bilangan bulat atau 0 jika gagal). Di sisi lain, yang terakhir juga dapat dilihat sebagai keuntungan juga.

SQLite dapat dengan mudah digunakan dari CSCS tanpa pernyataan impor tambahan. Berikut adalah tabel yang akan membantu Anda mendapatkan gambaran umum tentang fungsi SQLite utama yang digunakan di CSCS:

Memerintah Keterangan
SQLInit(DBName) Inisialisasi database atau set database untuk digunakan dengan pernyataan DB konsekuen.
SQLDBExists(DBName) Memeriksa apakah DB telah diinisialisasi. Juga mengatur database yang akan digunakan dengan pernyataan DB konsekuen.
SQLQuery(query) Mengeksekusi kueri SQL (pernyataan pilih). Mengembalikan tabel dengan catatan.
SQLNonQuery(nonQuery) Mengeksekusi non-query SQL, misalnya memperbarui, membuat, atau menghapus pernyataan. Mengembalikan jumlah record yang terpengaruh.
SQLInsert(tableName, columnList, data) Menyisipkan tabel data rekaman yang diteruskan ke tabel DB yang ditentukan. Argumen columnList memiliki struktur berikut: colName1,colName2,…,colNameN

Tabel 1: Perintah SQLite di CSCS

Beginilah cara fungsi SQLInit() dan SQLDBExists() biasanya digunakan:

 DBName = "myDB.db1"; if (!SQLDBExists(DBName)) { create = "CREATE TABLE [Data] (Symbol ntext, Low real, High real, Close real, Volume real, Stamp text DEFAULT CURRENT_TIMESTAMP)"; SQLNonQuery(create); } SQLInit(DBName);

Kita akan melihat lebih banyak contoh bagaimana Anda dapat memilih dan memasukkan data ke dalam database SQLite nanti. Saya akan menunjukkan contoh cara menulis data stok yang telah diekstraksi dari Layanan Web ke dalam database SQLite lokal.

Menambahkan Fungsi Kustom Ke CSCS

Di bagian ini, kita akan melihat bagaimana Anda dapat memperluas fungsionalitas CSCS. Sebagai contoh, kita akan melihat implementasi fungsi CSCS Sleep yang ada di bawah ini.

Untuk menambahkan fungsionalitas khusus, yang perlu Anda lakukan adalah membuat kelas baru dengan menurunkan dari kelas ParserFunction , mengganti metode Evaluate() , dan mendaftarkan kelas ini dengan parser. Ini versi singkatnya (tanpa pemeriksaan kesalahan):

 class SleepFunction : ParserFunction { protected override Variable Evaluate(ParsingScript script) { List args = script.GetFunctionArgs(); int sleepms = Utils.GetSafeInt(args, 0); Thread.Sleep(sleepms); return Variable.EmptyInstance; } } class SleepFunction : ParserFunction { protected override Variable Evaluate(ParsingScript script) { List args = script.GetFunctionArgs(); int sleepms = Utils.GetSafeInt(args, 0); Thread.Sleep(sleepms); return Variable.EmptyInstance; } }

Registrasi kelas dengan parser dapat dilakukan di mana saja dalam tahap inisialisasi melalui perintah berikut:

 ParserFunction.RegisterFunction("Sleep", new SleepFunction());

Itu dia! Sekarang metode Evaluate() dari kelas SleepFunction akan dipanggil segera setelah token "Sleep" diekstraksi oleh parser.

Perhatikan bahwa CSCS tidak peka huruf besar/kecil (kecuali pernyataan aliran kontrol inti: if , elif , else , for , while , function , include , new , class , return , try , throw , catch , break , continue ). Ini berarti Anda dapat mengetikkan "sleep(100)" atau "Sleep(100)" — kedua panggilan akan menangguhkan utas yang sedang dieksekusi selama 100 milidetik.

Memproses JSON Dalam CSCS

JSON (JavaScript Object Notation) adalah format pertukaran data yang ringan, terdiri dari pasangan atribut-nilai dan pasangan tipe array. Ini dikembangkan oleh Douglas Crockford pada awal 2000-an (sekitar waktu yang sama ketika SQLite juga muncul).

Di bagian ini, kita akan mempelajari cara mengurai JSON menggunakan CSCS.

Fungsi CSCS untuk mengurai string JSON adalah GetVariableFromJSON(jsonText) . Fungsi ini mengembalikan tabel hash di mana kuncinya adalah atribut dari string JSON.

Perhatikan contoh string JSON berikut:

 jsonString = '{ "eins" : 1, "zwei" : "zweiString", "mehr" : { "uno": "dos" }, "arrayValue" : [ "une", "deux" ] }';

Setelah memohon:

 a = GetVariableFromJSON();

Variabel a akan menjadi tabel hash dengan nilai berikut:

 a["eins"] = 1 a["zwei"] = "zweiString" a["mehr"]["uno"] = "dos" a["arrayValue"][0] = "une" a["arrayValue"][1] = "deux"

Di bagian selanjutnya, kita akan melihat contoh lain dari penguraian string JSON dari Layanan Web.

Contoh Aplikasi Dengan SQLite, Permintaan Web, dan JSON

Untuk aplikasi yang menggunakan SQLite, Web Service dan JSON parsing, kita akan menggunakan Alpha Vantage Web Service. Anda bisa mendapatkan Kunci API secara gratis tetapi versi gratisnya memungkinkan mengakses layanan web mereka tidak lebih dari 5 kali per menit.

Menggunakan Alpha Vantage, Anda dapat mengekstrak berbagai kumpulan data keuangan — termasuk harga saham. Inilah yang akan kita lakukan di aplikasi sampel kita.

Gambar di bawah ini menunjukkan bagaimana aplikasi Stocks terlihat di iOS dan di perangkat Android.

Mengekstrak Saham dari Layanan Web Alpha Vantage di iOS (kiri) dan Android (kanan)
Mengekstrak Saham dari Layanan Web Alpha Vantage di iOS (kiri) dan Android (kanan) (Pratinjau besar)

Kode CSCS untuk membangun GUI adalah sebagai berikut:

 locLabel = GetLocation("ROOT","CENTER", "ROOT","TOP", 0,30); AddLabel(locLabel, "labelRefresh", "", 480, 60); locSFWidget = GetLocation("ROOT","CENTER", labelRefresh,"BOTTOM"); AddSfDataGrid(locSFWidget, "DataGrid", "", graphWidth, graphHeight); listCols = {"Symbol","string", "Low","number", "High", "number", "Close","number", "Volume","number"}; AddWidgetData(DataGrid, listCols, "columns"); colWidth = {17, 19, 19, 19, 26}; AddWidgetData(DataGrid, colWidth, "columnWidth"); locButton = GetLocation("ROOT","CENTER",DataGrid,"BOTTOM"); AddButton(locButton, "buttonRefresh", "Refresh", 160, 80); locLabelError = GetLocation("ROOT","CENTER","ROOT","BOTTOM"); AddLabel(locLabelError, "labelError", "", 600, 160); SetFontColor(labelError, "red"); AlignText(labelError, "center"); getDataFromDB();

Metode getDataFromDB() akan mengekstrak semua data dari database SQLite. Ini menggunakan kueri SQL yang didefinisikan sebagai berikut:

 query = "SELECT Symbol, Low, High, Close, Volume, DATETIME(Stamp, 'localtime') as Stamp FROM Data ORDER BY Stamp DESC LIMIT 5;";

Lihatlah kode di bawah ini untuk implementasi getDataFromDB() .

 function getDataFromDB() { results = SQLQuery(query); for (i = 1; i < results.Size; i++) { vals = results[i]; stock = vals[0]; low = Round(vals[1], 2); high = Round(vals[2], 2); close = Round(vals[3], 2); volume = Round(vals[4], 2); refresh = vals[5]; stockData = {stock, low, high, close, volume}; AddWidgetData(DataGrid, stockData, "item"); } SetText(labelRefresh, "DB Last Refresh: " + refresh); lockGui(false); }

Sekarang mari kita lihat bagaimana kita mendapatkan data dari Layanan Web Alpha Vantage. Pertama, kami menginisialisasi data:

 baseURL = "https://www.alphavantage.co/query? " + "function=TIME_SERIES_DAILY&symbol="; apikey = "Y12T0TY5EUS6BC5F"; stocks = {"MSFT", "AAPL", "GOOG", "FB", "AMZN"}; totalStocks = stocks.Size;

Selanjutnya, kami memuat stok satu per satu segera setelah pengguna mengklik tombol "Segarkan":

 function buttonRefresh_click(object, arg) { lockGui(); SetText(labelRefresh, "Loading ..."); SetText(labelError, ""); ClearWidget(DataGrid); loadedStocks = 0; getData(stocks[loadedStocks]); } function getData(symbol) { stockUrl = baseURL + symbol + "&apikey=" + apikey; WebRequest("GET", stockUrl, "", symbol, "OnSuccess", "OnFailure"); }

Berikut adalah fungsi utama CSCS yang digunakan untuk mendapatkan data dari Layanan Web:

 WebRequest("GET", stockUrl, "", symbol, "OnSuccess", "OnFailure");

Dua parameter terakhir adalah fungsi untuk dipanggil pada penyelesaian permintaan web. Misalnya, jika terjadi kegagalan, fungsi CSCS berikut akan dipanggil:

 function OnFailure(object, errorCode, text) { SetText(labelError, text); lockGui(false); }

Akibatnya, pengguna akan mendapatkan pesan kesalahan seperti yang ditunjukkan di bawah ini:

Terjadi kesalahan saat meminta data web
Kesalahan saat meminta data web (Pratinjau besar)

Tapi, jika semuanya baik-baik saja, kita akan mengurai string JSON dan memasukkan isinya ke dalam SQLite DB.

 function OnSuccess(object, errorCode, text) { jsonFromText = GetVariableFromJSON(text); metaData = jsonFromText[0]; result = jsonFromText[1]; symbol = metaData["2. Symbol"]; lastRefreshed = metaData["3. Last Refreshed"]; allDates = result.keys; dateData = result[allDates[0]]; high = Round(dateData["2. high"], 2); low = Round(dateData["3. low"], 2); close = Round(dateData["4. close"], 2); volume = dateData["5. volume"]; stockData = {symbol, low, high, close, volume}; SQLInsert("Data","Symbol,Low,High,Close,Volume",stockData); if (++loadedStocks >= totalStocks) { getDataFromDB(); } else { getData(stocks[loadedStocks]); } }

Untuk memahami bagaimana kita mengakses bidang yang berbeda dalam tabel hash di atas, mari kita lihat string aktual yang diterima dari permintaan web Alpha Vantage:

 { "Meta Data": { "1. Information": "Daily Prices (open, high, low, close) and Volumes", "2. Symbol": "MSFT", "3. Last Refreshed": "2019-10-02 14:23:20", "4. Output Size": "Compact", "5. Time Zone": "US/Eastern" }, "Time Series (Daily)": { "2019-10-02": { "1. open": "136.3400", "2. high": "136.3700", "3. low": "133.5799", "4. close": "134.4100", "5. volume": "11213086" }, … } }

Seperti yang Anda lihat, kami mendapatkan tanggal terbaru sebagai elemen pertama dari array allDates yang terdiri dari semua tanggal yang diekstraksi.

Kesimpulan

Menambahkan CSCS ke proyek Anda sangatlah mudah. Yang perlu Anda lakukan hanyalah menyematkan kode sumber CSCS sebagai modul untuk proyek Anda — seperti yang dilakukan dalam contoh proyek Xamarin.

Apakah Anda menggunakan dan memperluas bahasa skrip CSCS dalam proyek Anda? Tinggalkan komentar di bawah — saya akan senang mendengar kabar dari Anda!

Bacaan lebih lanjut

Jika Anda ingin menjelajahi bahasa CSCS sedikit lebih banyak, berikut adalah beberapa artikel yang saya tulis tentang topik tersebut:

  • “A Split-and-Merge Expression Parser dalam C#,” Majalah MSDN (Okt. 2015)
  • “Scripting yang Dapat Disesuaikan dalam C#,” Majalah MSDN (Feb. 2016)
  • “Menulis Aplikasi Seluler Asli Menggunakan Bahasa Skrip yang Dapat Disesuaikan,” Majalah MSDN (Feb. 2018)
  • “CSCS: Skrip yang Disesuaikan dalam C#,” GitHub
  • “Mengembangkan Aplikasi Asli Lintas-Platform dengan Bahasa Skrip Fungsional,” Majalah CODE
  • “Menerapkan Bahasa Kustom Secara Ringkas” (eBook)
  • “Menulis Aplikasi Seluler Asli dalam Bahasa Fungsional dengan Ringkas” (eBook)

Sebagai sumber tambahan, saya juga merekomendasikan untuk membaca bagaimana Anda dapat meningkatkan kinerja CSCS dengan melakukan prakompilasi fungsinya.