Sebagian besar model di aplikasi iOS saya meminta server web. Saya ingin memiliki file konfigurasi yang menyimpan URL dasar server. Ini akan terlihat seperti ini:
// production
// static NSString* const baseUrl = "http://website.com/"
// testing
static NSString* const baseUrl = "http://192.168.0.123/"
Dengan mengomentari satu baris atau lainnya, saya dapat langsung mengubah server mana yang ditunjuk oleh model saya. Pertanyaan saya adalah, apa praktik terbaik untuk menyimpan konstanta global di iOS? Dalam pemrograman Android, kami memiliki file sumber daya string bawaan ini . Dalam Aktivitas apa pun (setara dengan UIViewController ), kita bisa mengambil konstanta string tersebut dengan:
String string = this.getString(R.string.someConstant);
Saya ingin tahu apakah iOS SDK memiliki tempat analog untuk menyimpan konstanta. Jika tidak, apa praktik terbaik di Objective-C untuk melakukannya?
"constants.h"
pendekatan, mendeklarasikanstatic
variabel berdasarkan#ifdef VIEW_CONSTANTS ... #endif
. Jadi saya memiliki satu file konstanta di seluruh aplikasi, tetapi masing-masing file kode saya yang lain#define
memiliki kumpulan konstanta yang berbeda untuk disertakan sebelum#include
-ing file konstanta (menghentikan semua peringatan kompilator yang "ditentukan tetapi tidak digunakan").#decalare
, saya mendapat kesalahan kompilasi yang mengatakan " deklarasi direktif preprocessing tidak valid ". Jadi saya mengubahnya menjadi#define
sebagai gantinya. Masalah lainnya adalah menggunakan konstanta. Saya ingin membuat konstanta lain denganstatic NSString* const fullUrl = [NSString stringWithFormat:@"%@%@", kbaseUrl, @"script.php"]
, tetapi tampaknya ilegal untuk membuat konstanta dengan ekspresi. Saya mendapatkan kesalahan " elemen penginisialisasi tidak konstan ".#define kBaseURL @"http://192.168.0.123/";
Nah, Anda ingin deklarasi lokal ke antarmuka yang terkait - file konstanta di seluruh aplikasi bukanlah hal yang baik.
Selain itu, lebih baik untuk mendeklarasikan
extern NSString* const
simbol, daripada menggunakan#define
:SomeFile.h
SomeFile.m
Terlepas dari penghilangan deklarasi Extern yang kompatibel dengan C ++, inilah yang biasanya Anda lihat digunakan dalam kerangka kerja Obj-C Apple.
Jika konstanta perlu terlihat hanya untuk satu file atau fungsi, maka
static NSString* const baseUrl
Anda*.m
sudah baik.sumber
@"foo"
tidak sama dengan[[NSString alloc] initWithCString:"foo"]
.#define
digunakan (yaitu persamaan pointer bisa gagal) - bukan bahwa ekspresi literal NSString menghasilkan sementara setiap kali dijalankan.Cara saya mendefinisikan konstanta global:
AppConstants.h
AppConstants.m
Kemudian di file {$ APP} -Prefix.pch Anda:
Jika Anda mengalami masalah apa pun, pertama-tama pastikan bahwa Anda memiliki opsi Precompile Prefix Header yang disetel ke NO.
sumber
Anda juga bisa menggabungkan konstanta string seperti ini:
sumber
Saya pikir cara lain untuk melakukan ini jauh lebih sederhana dan Anda hanya akan memasukkannya ke dalam file yang Anda perlukan, bukan SEMUA file, seperti dengan file awalan .pch:
Setelah itu Anda memasukkan file header ini ke dalam file header yang Anda inginkan. Anda memasukkannya ke dalam file header untuk kelas tertentu yang Anda inginkan untuk disertakan:
sumber
"error: use of undeclared identifier .."
#define BASEURl @"http://myWebService.appspot.com/xyz/xx"
lalu di mana saja dalam proyek untuk menggunakan BASEURL:
Diperbarui: Di Xcode 6 Anda tidak akan menemukan file .pch default yang dibuat dalam proyek Anda. Jadi silakan gunakan File PCH di Xcode 6 untuk memasukkan file .pch dalam proyek Anda.
Pembaruan: Untuk SWIFT
& Segera deklarasikan / definisikan anggota
Contoh:
sumber
Deklarasi global menarik, tetapi bagi saya, yang sangat mengubah cara saya membuat kode adalah memiliki contoh kelas global. Saya butuh beberapa hari untuk benar-benar memahami cara bekerja dengannya, jadi saya segera meringkasnya di sini
Saya menggunakan contoh kelas global (1 atau 2 per proyek, jika diperlukan), untuk mengelompokkan kembali akses data inti, atau beberapa logika perdagangan.
Misalnya jika Anda ingin memiliki objek pusat yang menangani semua tabel restoran yang Anda buat, objek Anda saat startup dan hanya itu. Objek ini dapat menangani akses database ATAU menanganinya dalam memori jika Anda tidak perlu menyimpannya. Ini terpusat, Anda hanya menampilkan antarmuka yang berguna ...!
Ini sangat membantu, berorientasi pada objek, dan cara yang baik untuk mendapatkan semua barang Anda di tempat yang sama
Beberapa baris kode:
dan implementasi objek:
untuk menggunakannya sangat sederhana:
sumber
Jawaban yang diterima memiliki 2 kelemahan. Pertama, seperti yang ditunjukkan orang lain adalah penggunaan
#define
yang lebih sulit untuk di-debug, gunakanextern NSString* const kBaseUrl
struktur sebagai gantinya . Kedua, ini mendefinisikan satu file untuk konstanta. IMO, ini salah karena sebagian besar kelas tidak memerlukan akses ke konstanta tersebut atau untuk mengakses semuanya ditambah file bisa menjadi membengkak jika semua konstanta dideklarasikan di sana. Solusi yang lebih baik adalah dengan memodulasi konstanta pada 3 lapisan berbeda:Lapisan sistem:
SystemConstants.h
atauAppConstants.h
yang mendeskripsikan konstanta dalam lingkup global, yang dapat diakses oleh semua kelas dalam sistem. Deklarasikan di sini hanya konstanta yang harus diakses dari kelas berbeda yang tidak terkait.Lapisan modul / sub-sistem:,
ModuleNameConstants.h
menjelaskan sekumpulan konstanta yang khas untuk sekumpulan kelas terkait, di dalam modul / sub-sistem.Lapisan kelas: Konstanta berada di dalam kelas dan hanya digunakan olehnya.
Hanya 1,2 yang terkait dengan pertanyaan tersebut.
sumber
Pendekatan yang saya gunakan sebelumnya adalah membuat file
Settings.plist
dan memuatnya ke dalamNSUserDefaults
saat peluncuran menggunakanregisterDefaults:
. Anda kemudian dapat mengakses isinya dengan yang berikut:Meskipun saya belum melakukan pengembangan Android apa pun, sepertinya ini analog dengan file sumber daya string yang Anda jelaskan. Satu-satunya downside adalah Anda tidak dapat menggunakan preprocessor untuk berpindah antar pengaturan (misalnya dalam
DEBUG
mode). Saya kira Anda dapat memuat file yang berbeda.NSUserDefaults
dokumentasi.sumber
NSString
,NSNumber
, dll). Tentu, Anda dapat membungkus#define
s Anda untuk melakukan hal yang sama, tetapi itu tidak mudah untuk diedit. Theplist
antarmuka mengedit baik, juga. :) Meskipun saya setuju bahwa Anda tidak boleh meletakkan hal-hal super rahasia seperti kunci enkripsi di sana, saya tidak terlalu khawatir tentang pengguna yang mencari-cari di tempat-tempat yang seharusnya tidak mereka kunjungi — jika mereka merusak aplikasi, itu adalah kesalahan mereka sendiri .#define
s saya untuk mengembalikan tipe yang benar, tetapi saya terbiasa mengedit file konstanta seperti itu, karena saya selalu belajar untuk meletakkan konstanta global seperti ini dalam file konstanta terpisah, sejak saya mempelajari Pascal di 286 lama :) Dan untuk pengguna yang melihat-lihat di mana-mana, saya setuju juga, itu salah mereka. Ini hanya soal selera, kok.Untuk nomor Anda bisa menggunakannya seperti
sumber
Saya akan menggunakan objek konfigurasi yang diinisialisasi dari a
plist
. Mengapa repot-repot kelas lain dengan hal-hal eksternal yang tidak relevan?Saya menciptakan
eppz!settigns
soley untuk alasan ini. Lihat artikel Cara lanjutan namun sederhana untuk menyimpan ke NSUserDefaults untuk memasukkan nilai default dari aplist
.sumber