All Products
Search
Document Center

Alibaba Cloud DNS:Panduan pengembangan iOS SDK

Last Updated:Jun 03, 2026

Integrasikan iOS SDK HTTPDNS ke dalam aplikasi Anda untuk resolusi nama domain yang andal dengan caching bawaan.

Ikhtisar

iOS SDK ini mengenkapsulasi DoH JSON API dari HTTPDNS, menyediakan API untuk resolusi nama domain di aplikasi iOS dan domain name caching yang efisien berdasarkan kebijakan Time-to-Live (TTL) dan Least Recently Used (LRU). Dengan SDK ini, pengembang dapat dengan mudah mengintegrasikan HTTPDNS ke dalam aplikasi iOS mereka guna mengatasi masalah resolusi nama domain dan mencapai resolusi yang akurat dengan biaya rendah.

Anda juga dapat mengatur HTTPDNS sebagai resolver DNS terenkripsi default menggunakan iOS 14 Native Encrypted DNS Solution.

Manfaat utama:

  • Mudah digunakan:

    Kode minimal diperlukan untuk mengintegrasikan HTTPDNS ke dalam aplikasi Anda.

  • Latensi nol:

    Cache LRU internal menyimpan IP yang telah diselesaikan secara lokal dan memperbarui entri yang kedaluwarsa secara proaktif, sehingga memungkinkan resolusi tanpa latensi.

Proyek contoh Objective-C: kode sumber proyek contoh alidns_ios_demo.

Proyek contoh Swift: kode sumber proyek contoh DNSResolverSwiftDemo.

Integrasi SDK

Impor SDK

CocoaPods

  1. Dalam Podfile Anda, tentukan lokasi repositori. Pastikan untuk menyertakan repositori master.

    source 'https://github.com/CocoaPods/Specs.git'
    source 'https://github.com/aliyun/aliyun-specs.git'
  2. Tambahkan dependensi untuk target proyek Anda:

    pod 'AlicloudPDNS'

Manual

  1. Unduh iOS SDK dari SDK Download.

  2. Setelah Anda mendapatkan framework SDK pdns-sdk-ios.framework, tambahkan secara manual ke dalam proyek Anda.

  3. Impor library sistem yang diperlukan:

    • Foundation.framework

    • SystemConfiguration.framework

    • CoreFoundation.framework

    • CoreTelephony.framework

  4. Dalam Build Settings proyek Anda, tambahkan flag -ObjC ke Other Linker Flags.

Inisialisasi SDK

Daftarkan aplikasi Anda di Konsol untuk mendapatkan Account ID dan kredensial AccessKey sebelum inisialisasi.

Penting

Untuk mencegah kegagalan resolusi, inisialisasi SDK sedini mungkin dalam siklus hidup aplikasi Anda.

Inisialisasi SDK dalam metode application:didFinishLaunchingWithOptions:.

DNSResolver *resolver = [DNSResolver share];
// setAccountId:@"******": Ganti tanda bintang dengan Account ID dari halaman Konfigurasi Akses di Konsol.
// andAccessKeyId:@"********": Ganti tanda bintang dengan AccessKey ID dari kunci yang Anda buat di halaman Konfigurasi Akses.
// andAccesskeySecret:@"********": Ganti tanda bintang dengan AccessKey Secret dari kunci yang Anda buat di halaman Konfigurasi Akses.
[resolver setAccountId:@"******" andAccessKeyId:@"********" andAccesskeySecret:@"********"];
// Tentukan domain untuk pembaruan cache otomatis. Array dapat berisi maksimal 10 domain.
[resolver setKeepAliveDomains:@[@"your_domain_1", @"your_domain_2"]];
// Pra-selesaikan domain yang kemungkinan akan Anda gunakan nanti.
[resolver preloadDomains:@[@"domain1", @"domain2", @"domain3"] complete:^{
// Semua domain telah dipra-selesaikan.
}];

Referensi API

Pengaturan umum

1. Account ID dan autentikasi

Wajib. Konsol menghasilkan Account ID unik saat Anda mendaftarkan aplikasi. Buat Pasangan Kunci Akses untuk membuat AccessKey guna autentikasi, lalu konfigurasikan:

// setAccountId:@"******": Ganti tanda bintang dengan Account ID dari halaman Konfigurasi Akses di Konsol.
// andAccessKeyId:@"********": Ganti tanda bintang dengan AccessKey ID dari kunci yang Anda buat di halaman Konfigurasi Akses.
// andAccesskeySecret:@"********": Ganti tanda bintang dengan AccessKey Secret dari kunci yang Anda buat di halaman Konfigurasi Akses.
[[DNSResolver share] setAccountId:@"******" andAccessKeyId:@"********" andAccesskeySecret:@"********"];
Peringatan
  • Untuk mencegah Account ID, AccessKey ID, atau AccessKey Secret Anda terekspos dalam log atau data lain yang dihasilkan oleh aplikasi yang sedang berjalan, nonaktifkan logging debug SDK pada rilis produksi Anda.

  • Sebagai contoh, kode sampel melewatkan Account ID, AccessKey ID, dan AccessKey Secret secara langsung. Kredensial ini digunakan untuk penagihan. Untuk mencegahnya terekspos melalui dekompilasi jahat, jangan hardcode kredensial dalam teks biasa di aplikasi produksi Anda. Sebaliknya, encode atau enkripsi kredensial tersebut dan decode atau dekripsi hanya saat diperlukan. Kami juga merekomendasikan agar Anda mengacak dan memperkuat kode aplikasi Anda. Jika tidak, Account ID, AccessKey ID, dan AccessKey Secret Anda berisiko dikompromikan.

2. Atur protokol resolusi

Atur protokol resolusi (HTTP atau HTTPS) menggunakan properti scheme.

SDK menggunakan dan merekomendasikan protokol HTTPS secara default karena memberikan keamanan yang lebih baik. HTTPDNS ditagih berdasarkan jumlah permintaan resolusi. Permintaan HTTPS ditagih lima kali lipat dibandingkan permintaan HTTP. Pilih jenis skema sesuai kebutuhan bisnis Anda. Atur properti sebagai berikut:

[DNSResolver share].scheme = DNSResolverSchemeHttps;

3. Aktifkan atau nonaktifkan caching

Jika diaktifkan, hasil resolusi di-cache secara lokal sehingga pencarian berikutnya langsung mengembalikan hasil dari cache.

Caching diaktifkan secara default. Untuk menonaktifkannya, gunakan kode berikut:

[DNSResolver share].cacheEnable=NO;

4. Atur caching keep-alive untuk domain

Jika diaktifkan, SDK memperbarui entri cache untuk domain tertentu secara proaktif sebelum kedaluwarsa. Ini menjaga data tetap mutakhir tetapi meningkatkan jumlah permintaan resolusi dan lalu lintas jaringan. Tanpa fitur ini, pembaruan cache hanya terjadi saat metode resolusi dipanggil.

// Array dapat berisi maksimal 10 domain.
[[DNSResolver share] setKeepAliveDomains:@[@"www.taobao.com",@"www.aliyun.com"]];
Catatan
  • Keuntungan:

    • Catatan diperbarui tepat waktu (sebelum TTL kedaluwarsa).

    • Jika dikombinasikan dengan pra-resolusi, dapat mengurangi latensi resolusi awal hingga 0 ms.

  • Kerugian: Meminta ulang pada 75% TTL catatan menimbulkan biaya tambahan.

5. Pra-resolusi

Pra-selesaikan domain saat startup aplikasi sehingga pencarian berikutnya langsung mengenai cache dengan latensi mendekati nol.

Contoh kode:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
   // Titik override untuk kustomisasi setelah peluncuran aplikasi.
   
   DNSResolver *resolver = [DNSResolver share];
   // setAccountId:@"******": Ganti tanda bintang dengan Account ID dari halaman Konfigurasi Akses di Konsol.
   // andAccessKeyId:@"********": Ganti tanda bintang dengan AccessKey ID dari kunci yang Anda buat di halaman Konfigurasi Akses.
   // andAccesskeySecret:@"********": Ganti tanda bintang dengan AccessKey Secret dari kunci yang Anda buat di halaman Konfigurasi Akses.
   [resolver setAccountId:@"******" andAccessKeyId:@"********" andAccesskeySecret:@"********"];
   resolver.cacheEnable = YES;
   // Pra-selesaikan domain yang kemungkinan akan Anda gunakan nanti.
   [resolver preloadDomains:@[@"domain1", @"domain2", @"domain3"] complete:^{
       // Semua domain telah dipra-selesaikan.
       
   }];
   
   return YES;
}

Pengaturan lanjutan

1. Aktifkan akses IPv6 sisi server

Layanan HTTPDNS mendukung akses dual-stack (IPv4 dan IPv6). Secara default, SDK menggunakan IPv4.

Untuk menggunakan IPv6, pastikan jaringan Anda mendukungnya dan aktifkan fitur ini:

[DNSResolver share].ipv6Enable = YES;

2. Mode pendek

DoH JSON API HTTPDNS mengembalikan JSON lengkap atau array IP yang disederhanakan. SDK menggunakan JSON lengkap secara default.

Untuk menggunakan format array IP yang disederhanakan:

[DNSResolver share].shortEnable = YES;

3. Atur ukuran cache

Jika caching diaktifkan, Anda dapat menyesuaikan jumlah domain yang di-cache. Rentang yang didukung adalah 100 hingga 500.

Ukuran cache default adalah 100 domain. Untuk mengatur ukuran cache khusus, gunakan properti cacheCountLimit:

[DNSResolver share].cacheCountLimit = 200;

4. Aktifkan atau nonaktifkan uji kecepatan IP

Saat IP speed test diaktifkan, hasil resolusi diurutkan berdasarkan latensi, dengan IP tercepat dikembalikan pertama kali.

IP speed test dinonaktifkan secara default. Untuk mengaktifkannya, gunakan kode berikut:

[DNSResolver share].speedTestEnable=YES;

5. Atur metode uji kecepatan IP

Konfigurasikan metode probing: atur ke 0 untuk probing ICMP, atau ke nomor port (80, 443, dll.) untuk probing socket pada port tersebut.

Nilai default adalah 443.

[DNSResolver share].speedPort = 80;

6. Aktifkan atau nonaktifkan caching nama domain spesifik ISP

Jika diaktifkan, entri cache diisolasi per jaringan ISP. Jika dinonaktifkan, semua jaringan berbagi satu cache.

domain name caching spesifik ISP diaktifkan secara default.

[DNSResolver share].ispEnable = YES;

7. Atur TTL maksimum untuk cache negatif

Atur TTL maksimum untuk negative cache, yang menyimpan hasil untuk pencarian yang gagal.

Nilai default adalah 30 detik. Untuk mengatur TTL maksimum khusus untuk negative cache, gunakan kode berikut:

[DNSResolver share].maxNegativeCache = 30;

8. Atur TTL cache maksimum

Atur TTL cache maksimum untuk membatasi masa berlaku entri terlepas dari nilai TTL yang disediakan server.

Nilai default adalah 3600 detik. Untuk mengatur TTL cache maksimum khusus, gunakan kode berikut:

[DNSResolver share].maxCacheTTL= 3600;

9. Aktifkan cache immutable

[DNSResolver share].immutableCacheEnable = NO;// Cache immutable dinonaktifkan secara default.
Penting

SDK menyediakan tiga mekanisme pembaruan cache:

  • Cache immutable: Saat fitur ini diaktifkan, cache dianggap selalu valid selama runtime aplikasi. SDK melewatkan pemeriksaan dan pembaruan kedaluwarsa, yang meminimalkan jumlah permintaan resolusi.

    Untuk mengaktifkannya, panggil: [DNSResolver share].immutableCacheEnable = YES

  • Pembaruan cache aktif: Ini membantu memastikan bahwa permintaan resolusi menggunakan cache terbaru. Saat catatan otoritatif domain berubah, mekanisme ini memungkinkan permintaan mendapatkan manfaat dari hit cache berlatensi rendah sekaligus memastikan catatan yang di-cache tetap mutakhir. Array dibatasi maksimal 10 domain.

    Untuk mengaktifkannya, panggil: [[DNSResolver share] setKeepAliveDomains:@[@"your_domain_1",@"your_domain_2"]]

  • Pembaruan cache pasif: Cache diperbarui secara pasif saat Anda memanggil salah satu dari dua metode berikut untuk mendapatkan hasil resolusi:

    • Metode - (void)getIpv4DataWithDomain:(NSString *)domain complete:(void(^)(NSArray<NSString *> *dataArray))complete mendapatkan array alamat IPv4 untuk suatu domain. Jika cache tidak kosong dan entri masih dalam TTL-nya, metode ini langsung mengembalikan hasil cache. Jika tidak, metode ini mengambil hasil terbaru melalui jaringan, mengembalikannya, dan memperbarui cache. Gunakan metode ini dalam skenario yang memerlukan akurasi tinggi.

    • Metode - (NSArray<NSString *> *)getIpv4ByCacheWithDomain:(NSString *)domain andExpiredIPEnabled:(BOOL)enable mengambil hasil resolusi IPv4 dari cache. Perilaku metode ini bergantung pada parameter enable.

      Deskripsi parameter: Jika enable bernilai YES, metode ini mengembalikan catatan kedaluwarsa meskipun cache sudah kedaluwarsa (atau nil jika cache kosong), lalu memperbarui cache secara asinkron. Jika NO, metode ini mengembalikan nil saat cache kedaluwarsa atau kosong, lalu memperbarui cache secara asinkron.

10. Timeout

Properti timeout mengatur timeout permintaan untuk resolusi. Default: 3 detik. Rentang yang direkomendasikan: 2–5 detik.

API Layanan

Contoh kode:

/// Pra-selesaikan informasi domain. Panggil metode ini saat startup aplikasi. Hasilnya disimpan dalam cache untuk mempercepat resolusi berikutnya.
/// Secara otomatis mendeteksi lingkungan jaringan (IPv4-only, IPv6-only, atau dual-stack) untuk mendapatkan IP yang sesuai dengan jaringan saat ini.
/// @param domainArray Array nama domain.
/// @param complete Callback yang dieksekusi setelah resolusi selesai.
- (void)preloadDomains:(NSArray<NSString *> *)domainArray complete:(void(^)(void))complete;

/// Mendapatkan array alamat IP untuk suatu domain. Metode ini secara otomatis mendeteksi lingkungan jaringan (IPv4-only, IPv6-only, atau dual-stack) untuk mendapatkan IP yang sesuai.
/// Jika caching diaktifkan, metode ini mengembalikan data dari cache terlebih dahulu. Jika cache kosong atau kedaluwarsa, metode ini mengambil IP melalui jaringan. Jika caching dinonaktifkan, metode ini selalu mengambil IP melalui jaringan.
/// @param domain Nama domain.
/// @param complete Callback yang mengembalikan semua alamat IP.
- (void)getIpsDataWithDomain:(NSString *)domain complete:(void(^)(NSArray<NSString *> *dataArray))complete;

/// Mendapatkan array alamat IP langsung dari cache tanpa menunggu. Metode ini secara otomatis mendeteksi lingkungan jaringan (IPv4-only, IPv6-only, atau dual-stack).
/// Mengembalikan nil jika cache kosong. Jika cache tidak kosong dan `enable` diatur ke YES, metode ini mengembalikan data cache. Jika data kedaluwarsa, metode ini memperbarui cache secara asinkron. Jika cache tidak kosong dan `enable` diatur ke NO, metode ini mengembalikan nil untuk entri kedaluwarsa dan memperbarui cache secara asinkron.
/// @param domain Nama domain.
/// @param enable Menentukan apakah akan mengembalikan alamat IP kedaluwarsa.
- (NSArray<NSString *> *)getIpsByCacheWithDomain:(NSString *)domain andExpiredIPEnabled:(BOOL)enable;

/// Mendapatkan array objek informasi IPv4 untuk suatu domain.
/// Jika caching diaktifkan, metode ini mengembalikan data dari cache terlebih dahulu. Jika cache kosong atau kedaluwarsa, metode ini mengambil IP melalui jaringan. Jika caching dinonaktifkan, metode ini selalu mengambil IP melalui jaringan.
/// @param domain Nama domain.
/// @param complete Callback yang mengembalikan semua objek informasi domain.
- (void)getIpv4InfoWithDomain:(NSString *)domain complete:(void(^)(NSArray<DNSDomainInfo *> *domainInfoArray))complete;

/// Mendapatkan array objek informasi IPv6 untuk suatu domain.
/// Jika caching diaktifkan, metode ini mengembalikan data dari cache terlebih dahulu. Jika cache kosong atau kedaluwarsa, metode ini mengambil IP melalui jaringan. Jika caching dinonaktifkan, metode ini selalu mengambil IP melalui jaringan.
/// @param domain Nama domain.
/// @param complete Callback yang mengembalikan semua objek informasi domain.
- (void)getIpv6InfoWithDomain:(NSString *)domain complete:(void(^)(NSArray<DNSDomainInfo *> *domainInfoArray))complete;

/// Mendapatkan satu objek informasi IPv4 acak untuk suatu domain.
/// Jika caching diaktifkan, metode ini mengembalikan data dari cache terlebih dahulu. Jika cache kosong atau kedaluwarsa, metode ini mengambil IP melalui jaringan. Jika caching dinonaktifkan, metode ini selalu mengambil IP melalui jaringan.
/// @param domain Nama domain.
/// @param complete Callback yang mengembalikan satu objek informasi domain acak.
- (void)getRandomIpv4InfoWithDomain:(NSString *)domain complete:(void(^)(DNSDomainInfo *domainInfo))complete;

/// Mendapatkan satu objek informasi IPv6 acak untuk suatu domain.
/// Jika caching diaktifkan, metode ini mengembalikan data dari cache terlebih dahulu. Jika cache kosong atau kedaluwarsa, metode ini mengambil IP melalui jaringan. Jika caching dinonaktifkan, metode ini selalu mengambil IP melalui jaringan.
/// @param domain Nama domain.
/// @param complete Callback yang mengembalikan satu objek informasi domain acak.
- (void)getRandomIpv6InfoWithDomain:(NSString *)domain complete:(void(^)(DNSDomainInfo *domainInfo))complete;

/// Mendapatkan array alamat IPv4 untuk suatu domain.
/// Jika caching diaktifkan, metode ini mengembalikan data dari cache terlebih dahulu. Jika cache kosong atau kedaluwarsa, metode ini mengambil IP melalui jaringan. Jika caching dinonaktifkan, metode ini selalu mengambil IP melalui jaringan.
/// @param domain Nama domain.
/// @param complete Callback yang mengembalikan semua alamat IP.
- (void)getIpv4DataWithDomain:(NSString *)domain complete:(void(^)(NSArray<NSString *> *dataArray))complete;

/// Mendapatkan array alamat IPv6 untuk suatu domain.
/// Jika caching diaktifkan, metode ini mengembalikan data dari cache terlebih dahulu. Jika cache kosong atau kedaluwarsa, metode ini mengambil IP melalui jaringan. Jika caching dinonaktifkan, metode ini selalu mengambil IP melalui jaringan.
/// @param domain Nama domain.
/// @param complete Callback yang mengembalikan semua alamat IP.
- (void)getIpv6DataWithDomain:(NSString *)domain complete:(void(^)(NSArray<NSString *> *dataArray))complete;

/// Mendapatkan satu alamat IPv4 acak untuk suatu domain.
/// Jika caching diaktifkan, metode ini mengembalikan data dari cache terlebih dahulu. Jika cache kosong atau kedaluwarsa, metode ini mengambil IP melalui jaringan. Jika caching dinonaktifkan, metode ini selalu mengambil IP melalui jaringan.
/// @param domain Nama domain.
/// @param complete Callback yang mengembalikan satu alamat IP acak.
- (void)getRandomIpv4DataWithDomain:(NSString *)domain complete:(void(^)(NSString *data))complete;

/// Mendapatkan satu alamat IPv6 acak untuk suatu domain.
/// Jika caching diaktifkan, metode ini mengembalikan data dari cache terlebih dahulu. Jika cache kosong atau kedaluwarsa, metode ini mengambil IP melalui jaringan. Jika caching dinonaktifkan, metode ini selalu mengambil IP melalui jaringan.
/// @param domain Nama domain.
/// @param complete Callback yang mengembalikan satu alamat IP acak.
- (void)getRandomIpv6DataWithDomain:(NSString *)domain complete:(void(^)(NSString *data))complete;

/// Pra-selesaikan informasi IPv4 untuk domain. Panggil ini saat startup aplikasi. Hasilnya disimpan dalam cache untuk mempercepat resolusi berikutnya.
/// @param domainArray Array nama domain.
/// @param complete Callback yang dieksekusi setelah resolusi selesai.
- (void)preloadIpv4Domains:(NSArray<NSString *> *)domainArray complete:(void(^)(void))complete;

/// Pra-selesaikan informasi IPv6 untuk domain. Panggil ini saat startup aplikasi. Hasilnya disimpan dalam cache untuk mempercepat resolusi berikutnya.
/// @param domainArray Array nama domain.
/// @param complete Callback yang dieksekusi setelah resolusi selesai.
- (void)preloadIpv6Domains:(NSArray<NSString *> *)domainArray complete:(void(^)(void))complete;

/// Mendapatkan array alamat IPv4 langsung dari cache tanpa menunggu.
/// Mengembalikan nil jika cache kosong. Jika cache tidak kosong dan `enable` diatur ke YES, metode ini mengembalikan data cache. Jika data kedaluwarsa, metode ini memperbarui cache secara asinkron. Jika cache tidak kosong dan `enable` diatur ke NO, metode ini mengembalikan nil untuk entri kedaluwarsa dan memperbarui cache secara asinkron.
/// @param domain Nama domain.
/// @param enable Menentukan apakah akan mengembalikan alamat IP kedaluwarsa.
- (NSArray<NSString *> *)getIpv4ByCacheWithDomain:(NSString *)domain andExpiredIPEnabled:(BOOL)enable;

/// Mendapatkan array alamat IPv6 langsung dari cache tanpa menunggu.
/// Mengembalikan nil jika cache kosong. Jika cache tidak kosong dan `enable` diatur ke YES, metode ini mengembalikan data cache. Jika data kedaluwarsa, metode ini memperbarui cache secara asinkron. Jika cache tidak kosong dan `enable` diatur ke NO, metode ini mengembalikan nil untuk entri kedaluwarsa dan memperbarui cache secara asinkron.
/// @param domain Nama domain.
/// @param enable Menentukan apakah akan mengembalikan alamat IP kedaluwarsa.
- (NSArray<NSString *> *)getIpv6ByCacheWithDomain:(NSString *)domain andExpiredIPEnabled:(BOOL)enable;

/// Mengumpulkan statistik permintaan.
-(NSArray *)getRequestReportInfo;

Contoh penggunaan API

1. Atur informasi dasar

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
   // Titik override untuk kustomisasi setelah peluncuran aplikasi.
   // Metode inisialisasi
   DNSResolver *resolver = [DNSResolver share];
   // setAccountId:@"******": Ganti tanda bintang dengan Account ID dari halaman Konfigurasi Akses di Konsol.
   // andAccessKeyId:@"********": Ganti tanda bintang dengan AccessKey ID dari kunci yang Anda buat di halaman Konfigurasi Akses.
   // andAccesskeySecret:@"********": Ganti tanda bintang dengan AccessKey Secret dari kunci yang Anda buat di halaman Konfigurasi Akses.
   [resolver setAccountId:@"******" andAccessKeyId:@"********" andAccesskeySecret:@"********"];
   // Tentukan domain untuk pembaruan cache otomatis. Array dapat berisi maksimal 10 domain.
	 [resolver setKeepAliveDomains:@[@"your_domain_1",@"your_domain_2"]];
   // Pra-selesaikan domain untuk mendapatkan hasil resolusi lebih awal dan menyimpannya dalam cache.
   [resolver preloadDomains:@[@"domain1", @"domain2", @"domain3"] complete:^{
       // Semua domain telah dipra-selesaikan.
       
   }];
   return YES;
}

2. Gunakan API resolusi nama domain

SDK menyediakan beberapa metode untuk resolusi nama domain, yang dapat Anda temukan di file header DNSResolver.h. Contoh berikut menunjukkan metode yang secara otomatis menyesuaikan dengan lingkungan jaringan (IPv4-only, IPv6-only, atau dual-stack).

Deklarasi API:

/// Mendapatkan array alamat IP untuk suatu domain. Metode ini secara otomatis menyesuaikan dengan lingkungan jaringan (IPv4-only, IPv6-only, atau dual-stack).
/// Jika caching diaktifkan, metode ini mengembalikan data dari cache terlebih dahulu. Jika cache kosong atau kedaluwarsa, metode ini mengambil IP melalui jaringan. Jika caching dinonaktifkan, metode ini selalu mengambil IP melalui jaringan.
/// @param domain Nama domain.
/// @param complete Callback yang mengembalikan semua alamat IP.
- (void)getIpsDataWithDomain:(NSString *)domain complete:(void(^)(NSArray<NSString *> *dataArray))complete;

Contoh pemanggilan API:

[[DNSResolver share] getIpsDataWithDomain:@"www.taobao.com" complete:^(NSArray<NSString *> *dataArray) {
    // dataArray adalah array alamat IP untuk www.taobao.com.
   if (dataArray.count > 0) {
       //TODO: Gunakan alamat IP untuk koneksi URL.
   }    
}];

3. Dapatkan hasil resolusi langsung dari cache

Deklarasi API:

/// Mendapatkan array alamat IP langsung dari cache tanpa menunggu. Metode ini secara otomatis menyesuaikan dengan lingkungan jaringan (IPv4-only, IPv6-only, atau dual-stack).
/// Mengembalikan nil jika cache kosong. Jika cache tidak kosong dan `enable` diatur ke YES, metode ini mengembalikan data cache. Jika data kedaluwarsa, metode ini memperbarui cache secara asinkron. Jika cache tidak kosong dan `enable` diatur ke NO, metode ini mengembalikan nil untuk entri kedaluwarsa dan memperbarui cache secara asinkron.
/// @param domain Nama domain.
/// @param enable Menentukan apakah akan mengembalikan alamat IP kedaluwarsa.
- (NSArray<NSString *> *)getIpsByCacheWithDomain:(NSString *)domain andExpiredIPEnabled:(BOOL)enable;

Contoh pemanggilan:

NSArray *result = [[DNSResolver share] getIpsByCacheWithDomain:@"your_domain" andExpiredIPEnabled:YES];
// Gunakan hasil cache.
if (result.count > 0) {
   //TODO: Gunakan alamat IP untuk koneksi URL.
   
}

Catatan: Mengambil hasil langsung dari cache sangat cepat, tetapi metode ini mengembalikan nil jika cache kosong, atau jika cache kedaluwarsa dan enable diatur ke NO.

4. Hapus cache

Deklarasi API:

/// `hostArray` adalah array hostname yang akan dihapus dari cache. Untuk menghapus semua data, berikan nil atau array kosong.
-(void)clearHostCache:(NSArray <NSString *>*)hostArray;

Contoh pemanggilan:

[[DNSResolver share] clearHostCache:@[@"domain1", @"domain2"]];

5. Kumpulkan statistik

Deklarasi API:

/// Mengumpulkan statistik permintaan.
-(NSArray *)getRequestReportInfo;

Contoh pemanggilan:

NSArray *array = [[DNSResolver share] getRequestReportInfo];

Format data:

 (
      {
         avgRtt = "1";                                // Waktu rata-rata resolusi domain (ms)
         cacheDnsNum = 0;                             // Jumlah hit cache                       
         domain = "www.taobao.com";                   // Domain yang diselesaikan
         gobackLocaldnsNum = 0;                       // Jumlah fallback ke DNS lokal
         localErro = 0;                               // Jumlah kegagalan resolusi DNS lokal
         maxRtt = "60";                               // Waktu resolusi domain maksimum (ms)
         noPermissionErro = 0;                        // Jumlah kegagalan autentikasi
         noResponseErro = 0;                          // Jumlah error tanpa respons          
         requestPDnsNum = 1;                          // Jumlah query rekursif
         sp = "China Mobile";                         // Nama ISP
         successNum = 1;                              // Jumlah resolusi berhasil
         timeoutErro = 0;                             // Jumlah error timeout jaringan
         type = 28;                                   // Jenis IP: 1 untuk IPv4, 28 untuk IPv6
         urlParameterErro = 0;                        // Jumlah error format parameter URL
         urlPathErro = 0;                             // Jumlah error path URL
      }
         ......
 );

Praktik terbaik untuk resolusi nama domain

Kombinasikan pra-resolusi dengan stale-while-revalidate untuk kinerja optimal.

Pra-selesaikan domain kunci saat startup untuk mengisi cache sehingga pencarian berikutnya menghindari round-trip jaringan, mencapai resolusi dengan latensi mendekati nol.

Cache bawaan SDK melayani permintaan resolusi berikutnya untuk domain yang telah dipra-selesaikan secara langsung, yang menghindari round-trip jaringan dan sangat meningkatkan pengalaman pengguna.

1. Pra-resolusi

Aktifkan caching dan pra-selesaikan domain kunci saat startup aplikasi.

Dalam metode AppDelegate application:didFinishLaunchingWithOptions:, pra-selesaikan nama domain yang digunakan dalam aplikasi Anda, dan simpan hasilnya dalam memori lokal.

1. Untuk skenario IPv4-only

//******** Untuk skenario IPv4-only *******
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
   DNSResolver *resolver = [DNSResolver share];
   // setAccountId:@"******": Ganti tanda bintang dengan Account ID dari halaman Konfigurasi Akses di Konsol.
   // andAccessKeyId:@"********": Ganti tanda bintang dengan AccessKey ID dari kunci yang Anda buat di halaman Konfigurasi Akses.
   // andAccesskeySecret:@"********": Ganti tanda bintang dengan AccessKey Secret dari kunci yang Anda buat di halaman Konfigurasi Akses.
   [resolver setAccountId:@"******" andAccessKeyId:@"********" andAccesskeySecret:@"********"];
   // Aktifkan caching. Default adalah YES.
   resolver.cacheEnable = YES;
   // Pra-selesaikan informasi IPv4 untuk domain yang kemungkinan akan Anda gunakan nanti.
   [resolver preloadIpv4Domains:@[@"domain1", @"domain2", @"domain3"] complete:^{
       // Semua domain telah dipra-selesaikan.
   }];
   return YES;
}

2. Untuk skenario IPv6

//******** Untuk skenario dual-stack yang mendukung IPv6 *******
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
   DNSResolver *resolver = [DNSResolver share];
   // setAccountId:@"******": Ganti tanda bintang dengan Account ID dari halaman Konfigurasi Akses di Konsol.
   // andAccessKeyId:@"********": Ganti tanda bintang dengan AccessKey ID dari kunci yang Anda buat di halaman Konfigurasi Akses.
   // andAccesskeySecret:@"********": Ganti tanda bintang dengan AccessKey Secret dari kunci yang Anda buat di halaman Konfigurasi Akses.
   [resolver setAccountId:@"******" andAccessKeyId:@"********" andAccesskeySecret:@"********"];
   // Aktifkan caching. Default adalah YES.
   resolver.cacheEnable = YES;
   // Aktifkan resolusi domain melalui jaringan IPv6. Default adalah NO.
   resolver.ipv6Enable = YES;
   // Aktifkan uji kecepatan IP. Default adalah NO.
   resolver.speedTestEnable = YES;
   // Pra-selesaikan domain. Ini secara otomatis mendeteksi jaringan (IPv4-only, IPv6-only, atau dual-stack) dan mendapatkan IP yang sesuai.
   [resolver preloadDomains:@[@"domain1", @"domain2", @"domain3"] complete:^{
       // Semua domain telah dipra-selesaikan.
   }];
   return YES;
}

2. Izinkan respons kedaluwarsa

Sebelum membuat permintaan jaringan, ambil IP dari cache dengan mengizinkan catatan kedaluwarsa (andExpiredIPEnabled:YES). Ini mengembalikan hasil segera selama cache terisi, bahkan jika TTL telah kedaluwarsa, mencapai resolusi tanpa latensi.

1. Untuk skenario IPv4-only

    //******** Untuk skenario IPv4-only *******
      __weak typeof(self) ws = self;
    // Utamakan mengambil IP dari cache, mengizinkan catatan kedaluwarsa namun masih dapat digunakan.
    NSArray<NSString *> *cachedIPs = [[DNSResolver share] getIpv4ByCacheWithDomain:domain andExpiredIPEnabled:YES];
    if (cachedIPs && cachedIPs.count > 0) {
        NSString *ip = cachedIPs.firstObject;
        NSLog(@"Hit cache cepat. Domain %@ diselesaikan ke IP: %@", domain, ip);
        [self requestWithIP:ip domain:domain]; // Hubungkan langsung menggunakan IP.
    } else {
        // Cache miss. Lakukan resolusi asinkron.
        [[DNSResolver share] getIpv4DataWithDomain:domain complete:^(NSArray<NSString *> *resolvedIPs) {
            if (resolvedIPs && resolvedIPs.count > 0) {
                NSString *ip = resolvedIPs.firstObject;
                NSLog(@"Resolusi asinkron selesai. Domain %@ diselesaikan ke IP: %@", domain, ip);
                [ws requestWithIP:ip domain:domain]; // Hubungkan langsung menggunakan IP.
            } else {
                NSLog(@"Resolusi domain gagal. Beralih ke domain asli.");
                [ws requestWithIP:domain domain:domain]; // Fallback: Gunakan domain asli.
            }
        }];
    }

2. Untuk skenario IPv6

    //******** Untuk skenario dual-stack yang mendukung IPv6 *******
      __weak typeof(self) ws = self;
    // Utamakan mengambil IP dari cache, mengizinkan catatan kedaluwarsa namun masih dapat digunakan.
    NSArray<NSString *> *cachedIPs = [[DNSResolver share] getIpsByCacheWithDomain:domain andExpiredIPEnabled:YES];
    if (cachedIPs && cachedIPs.count > 0) {
        NSString *ip = cachedIPs.firstObject;
        NSLog(@"Hit cache cepat. Domain %@ diselesaikan ke IP: %@", domain, ip);
        [self requestWithIP:ip domain:domain]; // Hubungkan langsung menggunakan IP.
    } else {
        // Cache miss. Lakukan resolusi asinkron.
        [[DNSResolver share] getIpsDataWithDomain:domain complete:^(NSArray<NSString *> *resolvedIPs) {
            if (resolvedIPs && resolvedIPs.count > 0) {
                NSString *ip = resolvedIPs.firstObject;
                NSLog(@"Resolusi asinkron selesai. Domain %@ diselesaikan ke IP: %@", domain, ip);
                [ws requestWithIP:ip domain:domain]; // Hubungkan langsung menggunakan IP.
            } else {
                NSLog(@"Resolusi domain gagal. Beralih ke domain asli.");
                [ws requestWithIP:domain domain:domain]; // Fallback: Gunakan domain asli.
            }
        }];
    }

Catatan penggunaan

  1. pdns-sdk-ios.framework memerlukan versi iOS minimum 9.0.

  2. Saat Anda membuat permintaan melalui HTTP, Anda harus mengatur App Transport Security Settings->Allow Arbitrary Loads ke YES dalam file Info.plist Anda.

  3. Setelah menyelesaikan IP dari HTTPDNS, atur Header HTTP Host ke nama domain asli saat membuat permintaan layanan.

    Contoh:

    // `ip` adalah alamat IP yang diselesaikan dari nama domain asli.
    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"https://%@", ip]];
    NSMutableURLRequest *mutableReq = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval: 10];
    // Atur host.
    [mutableReq setValue:@"original_domain" forHTTPHeaderField:@"host"];
  4. Implementasikan mekanisme fallback: jika SDK tidak mengembalikan IP, buat permintaan menggunakan nama domain asli.

    NSArray *array = [[DNSResolver share] getIpsByCacheWithDomain:@"original_domain" andExpiredIPEnabled:YES];
    if (array && array.count > 0 && array.firstObject.length > 0) {
        // Ganti host dalam URL dengan IP dan buat permintaan.
        
    } else {
        // Implementasikan logika fallback (gunakan URL asli untuk permintaan).
    }
  5. Saat proxy HTTP perantara ada, permintaan klien menggunakan URL absolut dalam baris permintaannya. Saat Anda mengaktifkan HTTPDNS dan menggunakan URL IP, proxy perantara mengidentifikasi alamat IP dari URL dan meneruskannya ke server target sebagai informasi Host. Akibatnya, server target tidak dapat memproses permintaan HTTP yang tidak memiliki informasi Host sebenarnya. Kami merekomendasikan agar Anda memeriksa apakah proxy jaringan diaktifkan di perangkat Anda. Jika perangkat Anda dalam modus proxy, jangan gunakan HTTPDNS untuk resolusi nama domain.

DNS On-premises

Mulai dari v2.3.0, iOS SDK HTTPDNS mendukung DNS on-premises untuk penyebaran privat.

Mode on-premises DNS cocok untuk skenario dengan kepatuhan data ketat dan kebijakan resolusi khusus, seperti keuangan, pemerintahan, atau perusahaan besar. SDK mendukung empat mode penyebaran: cloud publik saja, on-premises DNS saja, dan dua mode hibrida primary/backup di mana cloud publik dan on-premises DNS saling menjadi fallback.

Fitur inti

  • Dukungan penyebaran privat: Konfigurasikan endpoint server on-premises DNS menggunakan alamat IPv4/IPv6 atau hostname.

  • Otentikasi mutual: Gunakan accessKeyId dan accessKeySecret khusus Anda untuk menandatangani permintaan dan mengamankan komunikasi.

  • Pemutusan sirkuit dan pemeriksaan kesehatan: Jika node DNS on-premises gagal tiga kali berturut-turut atau lebih, pemutusan sirkuit dipicu secara otomatis. Setelah itu, sistem memeriksa ketersediaannya setiap menit menggunakan healthCheckDomain yang ditentukan. Node tersebut secara otomatis diaktifkan kembali setelah pulih.

  • Kontrol validasi sertifikat: Aktifkan atau nonaktifkan validasi sertifikat TLS. Kami sangat merekomendasikan mengaktifkannya di lingkungan produksi.

  • Failover cerdas: Secara otomatis beralih ke DNS cadangan saat DNS primer (cloud publik atau on-premises) mencapai ambang batas kegagalan, memastikan ketersediaan tinggi untuk resolusi.

  • Kompatibilitas API mulus: Pemanggilan API resolusi tetap sama baik Anda menggunakan DNS cloud publik maupun on-premises DNS, sehingga tidak perlu mengubah logika bisnis Anda.

Contoh konfigurasi

1. Gunakan hanya DNS cloud publik

Mode ini untuk pengguna SaaS standar yang belum menyebar on-premises DNS.

DNSResolver *resolver = [DNSResolver share];
[resolver setAccountId:@"******" 
        andAccessKeyId:@"********" 
    andAccesskeySecret:@"********"];

2. Gunakan hanya DNS on-premises (penyebaran privat)

Mode ini untuk pelanggan yang sepenuhnya mengandalkan on-premises DNS mereka.

DNSResolver *resolver = [DNSResolver share];
[resolver setFusionDNSWithIPv4:@[@"1.1.X.X", @"2.2.X.X"]
                            IPv6:nil
                           Host:nil
                           Port:@"443"
              HealthCheckDomain:@"check.example.com"
                    accessKeyId:@"your_fusion_ak"
                accesskeySecret:@"your_fusion_sk"];
// Opsional: Nonaktifkan validasi sertifikat (hanya untuk lingkungan pengujian).
// [resolver setEnableCertificateValidation:NO];

3. Cloud publik primer, on-premises cadangan

Jika HTTPDNS publik Alibaba Cloud primer gagal, resolusi secara otomatis beralih ke on-premises DNS.

DNSResolver *resolver = [DNSResolver share];

// Primer: DNS cloud publik
[resolver setAccountId:@"******" 
        andAccessKeyId:@"********" 
    andAccesskeySecret:@"********"];
    
// Cadangan: DNS on-premises
[resolver setFusionDNSWithIPv4:@[@"1.1.X.X", @"2.2.X.X"]
                            IPv6:nil
                           Host:nil
                           Port:@"443"
              HealthCheckDomain:@"check.example.com"
                    accessKeyId:@"your_fusion_ak"
                accesskeySecret:@"your_fusion_sk"];
// Opsional: Nonaktifkan validasi sertifikat (hanya untuk lingkungan pengujian).
// [resolver setEnableCertificateValidation:NO];

4. On-premises primer, cloud publik cadangan

Jika on-premises DNS primer gagal, resolusi secara otomatis beralih ke HTTPDNS publik Alibaba Cloud.

DNSResolver *resolver = [DNSResolver share];

// Primer: DNS on-premises
[resolver setFusionDNSWithIPv4:@[@"1.1.X.X", @"2.2.X.X"]
                            IPv6:nil
                           Host:nil
                           Port:@"443"
              HealthCheckDomain:@"check.example.com"
                    accessKeyId:@"your_fusion_ak"
                accesskeySecret:@"your_fusion_sk"];
// Opsional: Nonaktifkan validasi sertifikat (hanya untuk lingkungan pengujian).
// [resolver setEnableCertificateValidation:NO];

// Cadangan: DNS cloud publik
[resolver setAccountId:@"******" 
        andAccessKeyId:@"********" 
    andAccesskeySecret:@"********"];

API layanan baru

SDK mencakup tiga API inti untuk penyebaran privat dan pemulihan bencana ketersediaan tinggi untuk on-premises DNS. API ini mengonfigurasi layanan on-premises DNS, mengontrol kebijakan keamanan, dan menerapkan failover primer/cadangan otomatis.

1. Konfigurasi DNS on-premises

/** Ini terkait dengan DNS on-premises untuk penyebaran privat. Jangan panggil metode ini jika Anda hanya menggunakan DNS publik.
 *
 * Atur alamat server DNS on-premises dan informasi autentikasi.
 * Gunakan antarmuka ini untuk memberikan alamat server DNS privat dan kredensial autentikasi Anda.
 * SDK akan menggunakan informasi ini untuk memulai permintaan.
 * @param ipv4 Array alamat IPv4 (bisa nil).
 * @param ipv6 Array alamat IPv6 (bisa nil).
 * @param host Array hostname (bisa nil).
 * @param port Port layanan (misalnya, @"443"). Jika nil, port default digunakan.
 * @param healthCheckDomain Domain untuk pemeriksaan kesehatan setelah pemutusan sirkuit. Jika layanan resolusi gagal lebih dari tiga kali berturut-turut, sirkuit terputus, dan IP layanan memasuki status healthCheck. Permintaan berikutnya tidak akan menggunakan layanan ini. Timer kemudian memeriksa healthCheckDomain ini setiap menit untuk memastikan layanan tersedia. Jika pemeriksaan berhasil, status layanan dipulihkan ke alive dan dapat menerima permintaan lagi.
 * @param accessKeyId accessKeyId privat Anda untuk autentikasi.
 * @param accesskeySecret accesskeySecret privat Anda untuk autentikasi.
 */
- (void)setFusionDNSWithIPv4:(NSArray<NSString *> * _Nullable)ipv4
                        IPv6:(NSArray<NSString *> * _Nullable)ipv6
                        Host:(NSArray<NSString *> * _Nullable)host
                        Port:(NSString * _Nullable)port
           HealthCheckDomain:(NSString * _Nonnull)healthCheckDomain
                 accessKeyId:(NSString * _Nonnull)accessKeyId
             accesskeySecret:(NSString * _Nonnull)accesskeySecret;

2. Validasi sertifikat TLS

/** Ini terkait dengan DNS on-premises untuk penyebaran privat. Jangan panggil metode ini jika Anda hanya menggunakan DNS publik.
 *
 * Aktifkan atau nonaktifkan validasi sertifikat untuk DNS on-premises. Default adalah YES. Jika server Anda tidak dikonfigurasi dengan sertifikat domain atau IP, Anda dapat mengatur ini ke NO untuk pengujian. Untuk lingkungan produksi, atur ini ke YES untuk menghindari risiko keamanan.
 * @param enable YES untuk mengaktifkan (default), NO untuk menonaktifkan.
 */
- (void)setEnableCertificateValidation:(BOOL)enable;

3. Ambang batas failover otomatis

/** Saat DNS cloud publik dan DNS on-premises keduanya dikonfigurasi, ini mengatur jumlah kegagalan DNS primer yang memicu failover otomatis ke DNS cadangan. Jika hanya satu jenis DNS yang dikonfigurasi, jangan panggil metode ini.
 *
 * Atur jumlah kegagalan DNS primer sebelum secara otomatis beralih ke DNS cadangan. Jika hanya satu jenis DNS yang dikonfigurasi, jangan panggil metode ini.
 * @param fallbackThreshold Jumlah kegagalan. Default adalah 4 saat DNS cloud publik sebagai primer, dan 2 saat DNS on-premises sebagai primer.
 * Rentang valid adalah [0-4]. Nilai 0 berarti failover terjadi segera. Maksimum adalah 4.
 */
- (void)setFallbackThreshold:(NSInteger)fallbackThreshold;

FAQ

FAQ Terkait SDK/API