Swift ile Alt Sınıf UIA Uygulaması


92

Amaç C'de basitti: main.m dosyasını güncellemek ve UIApplicationMain () parametrelerini değiştirmek yeterliydi

return UIApplicationMain(argc, argv, NSStringFromClass([CustomUIApplication class]), NSStringFromClass([AppDelegate class]));

Ancak, hızlı bir şekilde ana.m dosyası yok, çünkü kılavuz

"Genel kapsamda yazılan kod, programın giriş noktası olarak kullanılır, bu nedenle bir ana işleve ihtiyacınız yoktur."

Öyleyse, hızlı bir şekilde UIApplication alt sınıfı nasıl yapılır? Herhangi bir öneri?


1
UIApplicationMain()Sınıf adını NSPrincipalClassapp-info.plist altına eklemek yerine parametreleri değiştirmek neden tercih edilebilir ?
Andreas

Yanıtlar:


173

NOT sözdizimi, Haziran 2019'da XCode 10.1 ve Swift 5 için güncellendi (matt'ın cevabına verilen krediler burada && Tung Fam'ın cevabı burada ), önceki sözdizimlerini arıyorsanız düzenleme bölümüne bakın.

Tamam, çözümü buldum

İlk olarak, AppDelegate.swift dosyasının en üstünde şu satır olduğunu fark ettim:

@UIApplicationMain

Bu satır herhangi bir kapsamın dışında olduğu için (dosya seviyesinde), hemen çalıştırılır ve derleyicinin bunu standart bir ana fonksiyona çevirdiğini varsayıyorum.

Bunu yeni bir Swift-Only uygulamasından başlayarak yaptım:

  • yorum yaptı @UIApplicationMain
  • buna benzer bir main.swift dosyası ekledi (FLApplication benim alt sınıfımdır).
    ÖNEMLİ , dosyanın adı main.swift OLMALIDIR, çünkü üst düzey ifadeler diğer dosyalarda desteklenmez! UIApplicationMain () çağrısını başka bir dosyanın içine ekleyemezsiniz, aksi takdirde şu hatayı alırsınız:

Üst düzeyde ifadelere izin verilmez

Bu main.swift dosyasıdır

UIApplicationMain(
    CommandLine.argc, CommandLine.unsafeArgv, 
    NSStringFromClass(FLApplication.self), NSStringFromClass(AppDelegate.self)
)

Ardından, şu kodla UIApplication alt sınıfı FLApplication.swift için bir hızlı dosya oluşturun:

import UIKit
import Foundation

class FLApplication: UIApplication {
    override func sendEvent(_ event: UIEvent) {
        super.sendEvent(event)
        print("send event")
    }
}

şimdi, UIApplication doğru bir şekilde alt sınıflandırılmıştır ve günlükte "olay gönder" mesajlarını göreceksiniz


ESKİ DÜZENLEMELER
Referans için, bu sürüm 1'den sürüm 3'e çok değiştiğinden, burada önceki tüm düzenlemeleri bırakıyorum


DÜZENLEME - MART 2015

Hu UIApplicationMainJunfeng tarafından yorumlandığı gibi, şimdi ve main.swift dosyası hakkındaki açıklamalar , Swift Dili Referansının Öznitelikler bölümünde belgelenmiştir: Bağlantı

Thomas Verbeek tarafından yorumlandığı gibi XCode 6.3 Beta'da, C_ARGC ve C_ARGV'nin sırasıyla Process.argc ve Process.unsafeArgv olarak yeniden adlandırıldığını görebilirsiniz. Main.swift dosyasındaki UIApplicationMain çağrınızın şu şekilde güncellenmesi gerekecek:

UIApplicationMain(Process.argc, Process.unsafeArgv, NSStringFromClass(FLApplication), NSStringFromClass(AppDelegate))

XCode 8 öncesi sözdizimi

import Foundation
import UIKit

UIApplicationMain(C_ARGC, C_ARGV, NSStringFromClass(FLApplication), NSStringFromClass(AppDelegate))

DÜZENLEME - ARALIK 2016

Beta 6'dan önceki Xcode 8 için çözüm

import Foundation
import UIKit

UIApplicationMain(
    CommandLine.argc,
    UnsafeMutableRawPointer(CommandLine.unsafeArgv)
        .bindMemory( 
            to: UnsafeMutablePointer<Int8>.self, 
            capacity: Int(CommandLine.argc)),
    NSStringFromClass(FLApplication.self),
    NSStringFromClass(AppDelegate.self)
)

UIApplicationMain () 'i doğrudan AppDelegate.swift dosyasında çağırmanın mümkün olup olmadığını anlamaya çalışıyorum, çünkü bu yöntemin "hızlı sürümü" var gibi görünüyor, ancak derleyici hatam var, bazı testler yapacağım "sadece hızlı" bir çözüm arıyor
LombaX

İnanılmaz derecede havalı. sendEvent:Bugünlerde geçersiz kılmak için kullanım durumunun ne olduğunu merak ediyorum (bunu iOS 3'te yapmak zorunda olduğumu hatırlıyorum ...)
matt

2
Birinin bilmek istemesi UIApplicationMainve main.swiftSwift Dil Referansının Nitelikler bölümünde belgelenmesi durumunda. developer.apple.com/library/ios/documentation/Swift/Conceptual/…
hujunfeng

İpucu için teşekkürler, Swift kılavuzunun ilk sürümünde belgelenmediğine% 99 eminim :-) ancak bilgilerinizi ekleyerek cevabı güncelleyeceğim.
LombaX

5
Mükemmel cevap. XCode 6.3 Beta olarak, fark edebilirsiniz C_ARGCve C_ARGVyeniden adlandırıldı edilmiş Process.argcve Process.unsafeArgvsırasıyla. Main.swift dosyasındaki UIApplicationMain çağrınızın şu şekilde güncellenmesi gerekecekUIApplicationMain(Process.argc, Process.unsafeArgv, NSStringFromClass(KBApplication), NSStringFromClass(AppDelegate))
Thomas Verbeek

4

Alternatiflerden biri, UIApplicationonu alt sınıflara ayırmak yerine genişletmektir . Apple tarafından yayınlanan iBook'a göre, Swift'deki uzantılar şunları yapabilir:

Hesaplanan özellikler ve hesaplanmış statik özellikler ekleyin Örnek yöntemlerini ve tür yöntemlerini tanımlayın Yeni başlatıcılar sağlayın Alt simgeler tanımlayın Yeni iç içe türler tanımlayın ve kullanın Mevcut bir türü bir protokole uygun hale getirin

Alıntı: Apple Inc. “The Swift Programlama Dili.

Alt sınıflamadaki ihtiyaçlarınız UIApplicationbu yetenekler tarafından karşılanıyorsa, bir Uzantı sizin için doğru yol olabilir.


5
güzel tavsiye - cevap
verme imho

1
  1. Bir alt sınıf oluşturun UIApplicationve mantığınızı ekleyin

    import UIKit
    
    class CustomUIApplication: UIApplication {
        override func sendEvent(_ event: UIEvent) {
            super.sendEvent(event)
        }
    }
    
  2. Uygulamanızın işletim sistemi tarafından çağrılan yeni giriş noktası olan global işlevi [Hakkında]main.swift çağıran bir dosya oluşturun . Bu işlev çağrılan işlev, sınıf adı, sınıf adından bağımsız değişken alır ve ana çalıştırma döngüsünü başlatır.UIApplicationMain()UIApplicationUIApplicationDelegate

    import UIKit
    
    UIApplicationMain(
        CommandLine.argc,
        CommandLine.unsafeArgv,
    
        NSStringFromClass(CustomUIApplication.self), //was created at step 1
        NSStringFromClass(AppDelegate.self)
    )
    
  3. @UIApplicationMainVarsayılan olarak açıklamayı kaldırın / yorumlayın AppDelegate.

    @UIApplicationMainüretir main.swift.

    Bunu yapmazsanız bir derleme hatası alırsınız:

    UIApplicationMain öznitelik, üst düzey kod içeren bir modülde kullanılamaz

    //@UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
        //...
    }
    
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.