İçeriğe geç
academia.sh

Ders 03 / 12

Alan Çerçeveleri

İstenen izinlerin verilenlerle kesiştiğinin, aygıtta bulunmayan yeteneğin ret verdiğinin ve iznin kapsamının kuralı değiştirmediğinin ölçümü.

Yayın Güncelleme

Bu derste

  • Alan çerçevesini tek bir alana ayrılmış sistem çerçevesi olarak tanımlar
  • İstenen izinler ile verilen izinlerin kesişimini ölçer
  • Aygıtta bulunmayan yeteneğin ret verdiğini ölçer
  • İzin kapsamının buluşmanın sınıfını değiştirmediğini gösterir
İçindekiler

Önceki ders iki modülün aynı adı açmasını ölçtü; buluşan şey bir addı. Bu derste buluşan şey bir yetkidir: uygulamanın istediği ile kullanıcının verdiği. Soru aynı kalır: bu iki tanım buluşunca nasıl çözülüyor? Bu derste bakılan çözüm kesişim: sonuçta yalnız iki tarafın da içerdiği yetkiler kalır.

Sistem çerçevelerinin bir bölümü genel amaçlıdır: koleksiyonlar, tarih, dosya, ağ. Bir bölümü ise tek bir alana ayrılmıştır ve alan çerçevesi (domain framework) diye anılır. Konum çerçevesi (Core Location) aygıtın nerede olduğunu verir; harita çerçevesi (MapKit) onu haritada gösterir; sağlık çerçevesi (HealthKit) sağlık verilerini okur ve yazar; medya çerçevesi (AVFoundation) ses ve görüntü yakalama ile oynatmayı yönetir; grafik çerçeveleri çizim işini üstlenir; artırılmış gerçeklik çerçevesi (ARKit) kameradan gelen görüntüyü ortamın bir modeline çevirir; aygıt üstü model çerçevesi (Core ML) eğitilmiş bir modeli aygıtta çalıştırır. Bu çerçevelerin ortak yanı, çoğunun kullanıcının verisine ya da aygıtın bir yeteneğine dokunmasıdır. Dokunduğu şey iki ayrı yerde tanımlıdır: uygulama ne istediğini bildirir, kullanıcı ve aygıt ne sunduğunu belirler.

// Meeting.swift — iki tanim bulusunca nasil cozuldugunu siniflandirir
struct Meeting {
    let label: String
    let first: Set<String>
    let second: Set<String>
    let result: Set<String>?

    init(_ label: String, first: Set<String>, second: Set<String>, result: Set<String>?) {
        self.label = label
        self.first = first
        self.second = second
        self.result = result
    }

    var resolution: String {
        if first.isEmpty || second.isEmpty
            || first.isSubset(of: second) || second.isSubset(of: first) {
            return "olcum-disi"
        }
        guard let result, !result.isEmpty else { return "ret" }
        if result == first.union(second) { return "birlesim" }
        if result == first.intersection(second) { return "kesisim" }
        if result == first || result == second { return "oncelik" }
        return "kural-disi"
    }

    static func list(_ values: Set<String>) -> String {
        values.isEmpty ? "bos" : values.sorted().joined(separator: ",")
    }

    func report() {
        let outcome = result.map(Meeting.list) ?? "yok"
        print("\(label): ilk \(Meeting.list(first)) | ikinci \(Meeting.list(second)) | sonuc \(outcome) -> \(resolution)")
    }
}

func summarize(_ meetings: [Meeting]) {
    for resolution in ["oncelik", "kesisim", "birlesim", "ret"] {
        let count = meetings.filter { $0.resolution == resolution }.count
        print("\(resolution): \(count)")
    }
}

İzin, Yetki Bildirimi ve Aygıt Yeteneği

Üç kavramı ayıralım. Yetki bildirimi (usage description), uygulamanın özellik listesinde (Info.plist) bir izin için kullanıcıya gösterilecek gerekçedir; bildirim yoksa izin sorusu kullanıcıya hiç ulaşmaz. İzin (permission), kullanıcının uygulamaya verdiği ya da vermediği yetkidir ve uygulamanın isteğinden bağımsız olarak değişebilir. Aygıt yeteneği (device capability) ise donanımın sunduğu bir özelliktir: kamera, ivmeölçer ya da derinlik algılayıcı gibi. Uygulama istediğini, kullanıcı verdiğini, aygıt sunduğunu söyler; uygulamanın bir özelliği ancak üç taraf aynı fikirdeyse çalışır.

Konum izni istenirken yetki bildirimi özellik listesine bir anahtar olarak yazılır ve kod yalnızca kullanımdayken yetkiyi ister. Aşağıdaki iki parça platform çerçevesine dayandığı için kaynak olarak durur ve çıktısı iddia edilmez.

<key>NSLocationWhenInUseUsageDescription</key>
<string>Yakindaki duraklari gostermek icin konum kullanilir.</string>
// Kaynak parca: konum izni yalniz uygulama kullanimdayken istenir
import CoreLocation

let manager = CLLocationManager()
manager.requestWhenInUseAuthorization()

Aşağıdaki yardımcı bu üç tarafın ikisini modeller: istenen izinlerin hangilerinin verildiğini bulan süzme ve istenen yeteneklerin hangilerinin aygıtta bulunduğunu bulan süzme. İkisi de bir kümeyi ötekine göre süzer, dolayısıyla sonuç iki kümenin kesişimidir. Bu dosyanın çıktısı yoktur.

// Permissions.swift — istenen izinleri ve yetenekleri verilenlere gore suzer
func granted(requested: Set<String>, grants: [String: String]) -> Set<String> {
    requested.filter { grants[$0] != nil }
}

func usable(requested: Set<String>, hardware: Set<String>) -> Set<String> {
    requested.filter { hardware.contains($0) }
}

İstenen ile Verilen

Aşağıdaki ölçümde uygulamanın yeni sürümü üç izin ister: kamera, konum ve sağlık. Kullanıcı kamera istemini reddetmiştir; konum ve sağlık izinlerini vermiştir. Mikrofon ise uygulamanın önceki sürümünün istediği ve kullanıcının o zaman verdiği bir izindir: yeni sürüm mikrofonu artık istemez, ama verilmiş izin aygıtta uygulamanın kaydında kalır. Böylece iki tarafın da ötekinde olmayan bir elemanı vardır.

// main.swift — istenen izinler verilenlerle kesisir
let requested: Set = ["kamera", "konum", "saglik"]
let grants = ["konum": "kullanirken", "mikrofon": "verildi", "saglik": "verildi"]

let request = Meeting("izin-istegi",
                      first: requested,
                      second: Set(grants.keys),
                      result: granted(requested: requested, grants: grants))
request.report()
izin-istegi: ilk kamera,konum,saglik | ikinci konum,mikrofon,saglik | sonuc konum,saglik -> kesisim

İstenen ama reddedilen kamera düştü; önceki sürümden kalan ve yeni sürümün istemediği mikrofon da düştü. Kalan iki ad iki tarafta da var: uygulamanın kullanabildiği yetki kümesi, bu sürümde istediğinin ve kullanıcının kaydında verilmiş olanın ortak kısmıdır. Tek bir sürüm içinde verilen izinler istenenlerin alt kümesidir; kayıttaki fazlalık yalnız istek kümesi sürümler arasında değiştiğinde oluşur. Önceki dersteki birleşimden farkı yönündedir: orada ad sayısı büyüyordu, burada küçülüyor.

PY7. Bu ölçüm üç istek ve kayıtta üç verilmiş izinden oluşan tek bir durum için. İzinlerin sonradan geri alınması, kullanıcının izni sormadan reddetmesi ve bir iznin yalnız bir kez verilmesi ölçülmedi.

Aygıtta Bulunmayan Yetenek

Yetenek tarafında kesişim kendi içinde iki biçimde ortaya çıkar. Uygulama iki yetenek ister ve aygıt yalnız birini sunar: sonuç kesişimdir ve uygulama kalan yetenekle çalışır. Uygulama yalnız aygıtta bulunmayan yeteneği ister: kesişim boş kalır ve çözüm ret olur. Aşağıdaki ölçüm bu iki durumu yan yana kurar.

// main.swift — aygitta olmayan yetenek kesisimi bosaltir
let hardware: Set = ["ivmeolcer", "kamera"]

let cases = [
    Meeting("yetenek-kismi",
            first: ["derinlik-algilayici", "kamera"],
            second: hardware,
            result: usable(requested: ["derinlik-algilayici", "kamera"], hardware: hardware)),
    Meeting("yetenek-yok",
            first: ["derinlik-algilayici"],
            second: hardware,
            result: usable(requested: ["derinlik-algilayici"], hardware: hardware)),
]

for item in cases {
    item.report()
}
summarize(cases)
yetenek-kismi: ilk derinlik-algilayici,kamera | ikinci ivmeolcer,kamera | sonuc kamera -> kesisim
yetenek-yok: ilk derinlik-algilayici | ikinci ivmeolcer,kamera | sonuc bos -> ret
oncelik: 0
kesisim: 1
birlesim: 0
ret: 1

yetenek-kismi bir yetenek kaybıyla sürer; yetenek-yok ise sonuçsuzdur. İkisi aynı kuraldan çıkar, çünkü ikisi de aynı süzmeyle üretilir ve fark yalnız istenen kümenin aygıta ne kadar yaklaştığındadır. Ret burada bir hata değil bir bilgidir: uygulama o yeteneğe ihtiyaç duyuyorsa bunu aygıta kurulmadan önce bildirmek, kurulduktan sonra beklenmedik bir boşlukla karşılaşmaktan iyidir. Bir yeteneğin zorunlu mu isteğe bağlı mı olduğu ayrı bir karardır ve burada ölçülmedi.

PY8. Bu ölçüm iki yeteneklik bir aygıt ve tek yeteneklik bir istek için. Yeteneğin sürüme ya da bölgeye bağlı olarak değişmesi ölçülmedi.

Alan Çerçevelerinin Sunduğu ve İstediği

Alan çerçevelerinin her biri farklı bir şey sunar ve farklı bir şey ister. Aşağıdaki özet kavramsaldır; hiçbir sayı ya da sürüm iddiası taşımaz.

Konum çerçevesi aygıtın coğrafi konumunu verir. Kullanıcının verisine dokunduğu için bir izin ister ve izin iki kapsamda verilebilir: yalnız uygulama kullanılırken ya da her zaman. Harita çerçevesi konumu haritada gösterir; haritayı çizmek için ayrıca bir izin gerekmez, ama kullanıcının kendi konumunu göstermek konum çerçevesinin iznine bağlıdır. Sağlık çerçevesi sağlık verilerini okur ve yazar; her veri tipi için okuma ve yazma izni ayrı ayrı sorulur ve kullanıcı bunlardan yalnız bazılarını verebilir. Medya çerçevesi kamera ve mikrofon gibi yakalama aygıtlarına ve ses ile görüntü oynatmaya erişir; yakalama bir izin ister, oynatma çoğu durumda istemez. Grafik çerçeveleri çizim işini üstlenir ve kullanıcının verisine dokunmadığı için izin istemez. Artırılmış gerçeklik çerçevesi kamera görüntüsünü ortamın bir modeline çevirir; kamerayı kullandığı için kamera iznine bağlıdır ve ayrıca aygıtın bu işi yapabilecek donanımı taşıması gerekir. Aygıt üstü model çerçevesi eğitilmiş bir modeli aygıtta çalıştırır; model yerel olarak çalıştığı sürece izin istemez, ama modelin girdisi kameradan ya da mikrofondan geliyorsa o girdinin izni gerekir.

Bu liste iki şeyi gösterir. Birincisi, izin çerçevenin değil, çerçevenin dokunduğu verinin özelliğidir: aynı kamera iznini iki farklı çerçeve paylaşabilir. İkincisi, bir çerçevenin izin istememesi onun her aygıtta çalışacağı anlamına gelmez; aygıt yeteneği ayrı bir koşuldur.

Yetki Bildirimi

Yetki bildirimi (usage description), uygulamanın özellik listesinde yazdığı, izin iletişim kutusunda kullanıcıya gösterilen açıklama metnidir. İzin istenen her veri tipi için bu açıklama zorunludur ve eksikse platform izin istemini hiç göstermez ya da uygulamayı sonlandırır. Açıklama, uygulamanın bu veriyi ne için istediğini kullanıcıya söyler. İyi bir açıklama somuttur ve yalnız o özelliği anlatır; geniş ve belirsiz bir açıklama kullanıcının izni reddetmesine yol açar.

Önemli bir ayrım: yetki bildirimi bir izin değildir. Bildirim, izin istemini göstermenin ön koşuludur. Uygulamanın istediği ile kullanıcının verdiği arasındaki buluşma, bildirimin yazılmasından sonra, izin istemi gösterildiğinde yapılır. Bu yüzden önceki ölçümler istenen ve verilen kümeleri buluşturur, bildirimi ayrı bir taraf olarak saymaz.

İzin Kapsamı

İzin kapsamı (permission scope), verilen iznin ne kadar geniş olduğudur. Konum örneğinde iki kapsam vardır: yalnız kullanırken ve her zaman. Kapsam arttıkça uygulamanın yapabildiği işler artar; bu farkın buluşma kuralına yansıyıp yansımadığını dersin sonundaki sınırlayıcı ölçüm gösterir. Kapsam bir pazarlık değildir; kullanıcı ayarlardan kapsamı daraltabilir ve uygulama bunu çalışırken görür. Uygulama kapsam daraldığında yapabildiği işlerin azaldığını varsaymalı ve çalışma anında verilen kapsamı yeniden sormalıdır; başlangıçta bir kez okunan kapsam, uygulama çalışırken geçerliliğini yitirebilir.

Kapsamın iki sonucu vardır. Uygulama istediği kapsamı en dar tutarsa, kullanıcı izni daha rahat verir ve uygulama daha az iş için sorumlu olur. Uygulama kapsamı geniş istemişse, platform bunu belirli aralıklarla kullanıcıya hatırlatabilir. Her iki durumda da çözüm kesişimdir: uygulamanın istediği ile kullanıcının verdiği kümenin ortak kısmı.

İzin İstemini Ne Zaman Göstermek

İzin isteminin zamanı, izin verilme ihtimalini etkiler. Uygulama açılır açılmaz üç izni birden isteyen bir akış, kullanıcıya henüz neden gerektiklerini göstermemiştir; kullanıcı reddeder ve ret çoğu durumda kalıcıdır. Konum iznini haritada “yakınımdaki yerler” düğmesine dokunulduğunda, kamera iznini ilk fotoğraf çekilirken istemek, isteğin bağlamını kullanıcıya gösterir ve yetki bildirimindeki açıklamayı somutlaştırır.

Reddedilen izin de bir sonuçtur ve uygulama bunu işlemelidir. İzin verilmediğinde uygulamanın geri kalanı çalışmaya devam etmeli, yalnız o özellik devre dışı kalmalıdır. Konum reddedilmişse harita yine açılır, ama kullanıcıdan bir adres girmesi istenir. Kullanıcı kararını sonradan değiştirmek isterse yolu ayarlara yönlendirmektir; platform aynı izni ikinci kez iletişim kutusuyla sormaz. Bu da iznin neden iki taraflı bir buluşma olduğunu gösterir: kullanıcının cevabı, uygulamanın bir sonraki adımını belirler. yetenek-yok ölçümündeki ret de buna benzer bir durumdur: ortak bir sonuç çıkmadığında uygulama yedek bir yol sunmalıdır.

Sınırlayıcı Ölçüm

Konum izni iki kapsamda verilebilir: yalnızca uygulama kullanımdayken ve her zaman. Kapsamın kullanıcı için önemi büyüktür, ama buluşma kuralı için önemi yoktur: kural iki kümenin ortak elemanlarına bakar ve eleman olarak izin adını görür, iznin hangi kapsamda verildiğini görmez. Aşağıdaki ölçüm aynı isteği iki farklı kapsamdaki konum izniyle kurar.

// main.swift — izin kapsami kesisimi degistirmez
let requested: Set = ["kamera", "konum", "saglik"]
let whenInUse = ["konum": "kullanirken", "mikrofon": "verildi", "saglik": "verildi"]
let always = ["konum": "her-zaman", "mikrofon": "verildi", "saglik": "verildi"]

let scopes = [
    Meeting("konum-kullanirken",
            first: requested,
            second: Set(whenInUse.keys),
            result: granted(requested: requested, grants: whenInUse)),
    Meeting("konum-her-zaman",
            first: requested,
            second: Set(always.keys),
            result: granted(requested: requested, grants: always)),
]

for item in scopes {
    item.report()
}
konum-kullanirken: ilk kamera,konum,saglik | ikinci konum,mikrofon,saglik | sonuc konum,saglik -> kesisim
konum-her-zaman: ilk kamera,konum,saglik | ikinci konum,mikrofon,saglik | sonuc konum,saglik -> kesisim

İki satır etiketi dışında aynıdır: iki ölçüm aynı sonucu ve aynı sınıfı verir. Kapsamın getirdiği fark, yani her zaman verilen konum izninin kullanırken verilene göre daha çok işe yetmesi, iznin anlamındadır ve bu ölçümün dışında kalır. Kuralın sınıfı kapsamdan etkilenmez; kapsamı okumak için sonucu ayrıca incelemek gerekir. Bu yüzden “yalnız kullanımdayken” izni kesişim sayımına girer ama iznin neye yettiğini söylemez; bir sonucu “izin var” diye okumak ile “izin her koşulda var” diye okumak arasındaki fark sınıflandırmanın dışında kalır.

PY9. Bu ölçüm yalnız iki kapsam ve tek bir izin adı için. Kapsamın arka planda konum alımı gibi bir davranışı değiştirmesi bu modelde yoktur ve ölçülmedi.

Özet

  • Alan çerçevesi tek bir alana ayrılmış sistem çerçevesidir: konum, sağlık, medya, grafik, artırılmış gerçeklik ve aygıt üstü model örnekleridir.
  • Uygulama izin ister, kullanıcı verir, aygıt yetenek sunar; kullanılabilir olan, istenen ile verilenin ortak kısmıdır.
  • İstenen izinler ile verilenler kesişir: kamera düştü, konum ve sağlık kaldı.
  • Aygıtta bulunmayan yetenek kesişimi boşaltır ve çözüm ret olur.
  • İznin kapsamı (yalnız kullanımdayken ya da her zaman) kuralın sınıfını değiştirmez; kural kümeye bakar, kapsamı okumaz.
  • Bu dersin çözümü: kesişim.

Sonraki Adım

Buraya kadar iki tanım bir kümenin iki yüzüydü. Sıradaki derste ikisi de aynı olayı işleyen iki temsilci olur: uygulama temsilcisi ile sahne temsilcisi. İkisi de aynı olay için bir işleyici tanımlarsa hangisinin çalışacağını ölçeriz; çözüm öncelik.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ ↵ Esc gezin · aç · kapat