Làm cách nào để tôi có được một tham chiếu đến đại biểu ứng dụng trong Swift?


409

Làm cách nào để tôi có được một tham chiếu đến đại biểu ứng dụng trong Swift?

Cuối cùng, tôi muốn sử dụng tham chiếu để truy cập vào bối cảnh đối tượng được quản lý.


8
Lưu ý rằng một số người sẽ coi việc sử dụng đại biểu ứng dụng làm vùng chứa cho bối cảnh đối tượng được quản lý hoặc các đối tượng "toàn cầu" khác là một mô hình chống. Hãy xem xét việc đại biểu ứng dụng chuyển MOC cho bộ điều khiển, thay vì làm cho bộ điều khiển tìm thấy nó.
Kristopher Johnson

1
@KristopherJohnson Hey Kris, làm thế nào tôi có thể tạo điều kiện cho AppDelegate tiêm phụ thuộc vào bộ điều khiển xem? Khởi tạo bộ điều khiển khung nhìn theo chương trình và sử dụng sự phản chiếu để quyết định cái gì cần khởi tạo / tiêm, đệ quy? Có khuôn khổ nào có thể giúp với điều này? Nếu tôi phải làm điều này cho mọi trình điều khiển chế độ xem theo cách thủ công, AppDelegate của tôi sẽ rất lớn! Ồ, tốt nhất là không tạo ra một nhà máy cho tất cả mọi thứ :)
Jimbo

1
Một tìm kiếm chữ thảo đã tìm thấy Swinject cũng có hệ thống tự động nối dây :)
Jimbo

6
Đối với các lập trình viên khuyên không nên đưa bất cứ thứ gì "không liên quan" vào đại biểu ứng dụng, điều đó hơi vô nghĩa vì tài liệu của Apple tuyên bố rõ ràng rằng một "crucial role"trong số các UIApplicationDelegatesingleton là "...to store your app’s central data objects or any content that does not have an owning view controller." developer.apple.com/documentation/uikit/uiapplicationdelegate
bsod

Câu trả lời:


757

Giải pháp khác đúng ở chỗ nó sẽ giúp bạn tham chiếu đến đại biểu của ứng dụng, nhưng điều này sẽ không cho phép bạn truy cập bất kỳ phương thức hoặc biến nào được thêm bởi lớp con của UIApplication, như bối cảnh đối tượng được quản lý của bạn. Để giải quyết vấn đề này, chỉ cần downcast xuống "AppDelegate" hoặc bất cứ điều gì lớp con UIApplication của bạn sẽ được gọi. Trong Swift 3, 4 & 5 , điều này được thực hiện như sau:

let appDelegate = UIApplication.shared.delegate as! AppDelegate
let aVariable = appDelegate.someVariable

10
Trong trường hợp bất cứ ai vẫn gặp sự cố, việc nhắm mục tiêu OS X yêu cầu bạn nhập Ca cao để làm việc cho NSApplication. SharedApplication (). Tôi đoán rằng iOS sẽ cần tương đương.
smaurice

2
Đây là hữu ích hơn trong hai câu trả lời.
Joe

3
@zacjordaan Sử dụng phương pháp đó, bạn sẽ nhận được tự động hoàn thành cho tài sản, nhưng nó sẽ không thực sự hoạt động. Bằng cách đó sẽ tạo một phiên bản mới của lớp AppDelegate mỗi khi bạn sử dụng nó. Tốt hơn hết là bạn nên sử dụng đại biểu có thể truy cập thông qua singleton SharedApplication. Và theo như câu hỏi thứ hai của bạn, có lẽ bạn muốn sử dụng một hằng. Mặc dù, bạn có thể đang thay đổi các thuộc tính của AppDelegate, nhưng bạn có thể sẽ không gán lại con trỏ cho bất kỳ thứ gì khác, trong trường hợp đó, không cần phải có biến. Điều này hoàn toàn phụ thuộc vào bạn mặc dù. Làm những gì phù hợp với nhu cầu của bạn.
Mick MacCallum

2
Lời khuyên tuyệt vời! Tôi đã lầm tưởng rằng AppDelegate () là singleton nhưng sau khi nghĩ về những gì bạn đã nói tôi đã nhận ra rằng nếu đó là mô hình ứng dụng chung cho chúng tôi sử dụng theo cách này. Tất nhiên tôi không muốn sinh ra những trường hợp không cần thiết nếu tôi không phải làm vậy, vì vậy tuyên bố liên tục của bạn sẽ hoàn toàn phù hợp; Cảm ơn bạn.
zacjordaan

4
Tôi không muốn thêm câu này dưới dạng câu trả lời riêng biệt, nhưng để có được AppDelegate với các phương thức, thuộc tính của riêng bạn trong dự án sử dụng cả Swift và Obj-c, bạn nên thêm #import "AppDelegate.h" vào "ProjectName-BridgingHeader .h "
Marcin Mierzejewski

44

Swift 4.2

Trong Swift, dễ dàng truy cập trong VC của bạn

extension UIViewController {
    var appDelegate: AppDelegate {
    return UIApplication.shared.delegate as! AppDelegate
   }
}

26

Thuận tiện xây dựng

Thêm vào lớp AppDelegate ở cuối mã

Swift 5

func appDelegate() -> AppDelegate {
    return UIApplication.shared.delegate as! AppDelegate
}

Để sử dụng tài liệu tham khảo AppDelegate trong lớp của bạn?


Gọi phương thức AppDelegate

appDelegate (). setRoot ()


Sẽ thật tuyệt khi giải thích những gì setRoot () làm và khi nào gọi nó. ví dụ: gọi nó từ ViewContoder có ổn không? Từ một bài kiểm tra Đơn vị nơi cửa sổ chưa được đặt? Nhiều bối cảnh sẽ là tuyệt vời.
Houman

@Houman setRoot là phương thức từ AppDelegate, có thể được sử dụng để chuyển đổi giữa nhiều Rễ hoặc ParentViewCont kiểm soát và có thể là bất kỳ phương thức nào. Thảo luận là về cách lấy tham chiếu của AppDelegate để truy cập thêm, nhưng hy vọng setRoot cũng phải rõ ràng.
AiOsN

19

Nó khá giống với Objective-C

let del = UIApplication.sharedApplication().delegate

19

Điều này có thể được sử dụng cho OS X

let appDelegate = NSApplication.sharedApplication().delegate as AppDelegate
var managedObjectContext = appDelegate.managedObjectContext?

3
Hoặc đơn giản hơnlet appDelegate = NSApp.delegate as AppDelegate
Vladimir Prudnikov

1
Trong Swift 3 sử dụnglet appDelegate = NSApplication.shared().delegate as AppDelegate
Dirk

4
Trong Swift 4 :NSApp.delegate as? AppDelegate
Nick

12

Đây là phiên bản Swift 2.0:

let delegate = UIApplication.sharedApplication().delegate as? AppDelegate

Và để truy cập vào bối cảnh đối tượng được quản lý:

    if let delegate = UIApplication.sharedApplication().delegate as? AppDelegate {

        let moc = delegate.managedObjectContext

        // your code here

    }

hoặc, sử dụng bảo vệ:

    guard let delegate = UIApplication.sharedApplication().delegate as? AppDelegate  else {
        return
    }

    let moc = delegate.managedObjectContext

    // your code here

10

Chuyển đổi <3

Tạo một phương thức trong AppDelegate Class cho ex

func sharedInstance() -> AppDelegate{
        return UIApplication.sharedApplication().delegate as! AppDelegate
    }

và gọi nó là một nơi khác cho ex

let appDelegate : AppDelegate = AppDelegate().sharedInstance()

Chuyển đổi> = 3.0

func sharedInstance() -> AppDelegate{
    return UIApplication.shared.delegate as! AppDelegate
}

2
điều này cũng hoạt động, và tôi thích ý tưởng về việc đặt tên sharedInstance. cảm ơn!
John Griffiths

2
Ví dụ của bạn vẫn sẽ khởi tạo một AppDelegateđối tượng mới mỗi lần bạn gọiAppDelegate().sharedInstance()
pxpgraphics

1
Tôi thích giải pháp này tốt hơn giải pháp được chấp nhận (đó là "dài dòng" nếu bạn phải sử dụng tất cả). Tôi đã suy nghĩ về thử nghiệm với một extensioncho NSApplicationtrước khi tôi tìm thấy câu trả lời này, nhưng điều này là tốt hơn nhiều. Ngày nay, bạn có thể muốn sử dụng một thuộc tính chỉ đọc được tính toán trong lớp shared, có lẽ bạn muốn đăng một bản cập nhật cho Swift 3?
Patru

1
Tôi thực sự đang trong quá trình tái cấu trúc mã của mình để sử dụng static var shared : TournamentDelegate? { get { return NSApplication.shared().delegate as? TournamentDelegate } }phù hợp hơn với kiểu Swift 3 đang phát triển sử dụng các thuộc tính chỉ đọc được tính toán cho loại điều này. Tôi có thể sẽ bỏ được ?một khi việc tái cấu trúc được thực hiện, bạn có nghĩ vậy không? (Xin lỗi, định dạng mã trong các nhận xét luôn là một mớ hỗn độn.)
Patru

@ pxpgraphics UIApplication là một lớp singleton nên không cần phải lo lắng về việc khởi tạo nhiều lần.
Abhijith


6

Hãy thử đơn giản thế này:

Swift 4

// Call the method
(UIApplication.shared.delegate as? AppDelegate)?.whateverWillOccur()

nơi trong AppDelegate của bạn:

// MARK: - Whatever
func whateverWillOccur() {

    // Your code here.

}

5

Đây là một phần mở rộng để UIApplicationDelegatetránh mã hóa AppDelegatetên lớp:

extension UIApplicationDelegate {

    static var shared: Self {    
        return UIApplication.shared.delegate! as! Self
    }
}

// use like this:
let appDelegate = MyAppDelegate.shared // will be of type MyAppDelegate

trên Mac cho NSApplicationDelegateđiều này mang lại cho tôi : 'Self' is only available in a protocol or as the result of a method in a class; did you mean 'AppDelegate'?. Đây có phải là lỗi thời?
pkamb

@pkamb Tôi vừa thử nó trong một dự án mới và tôi không gặp lỗi này. Tôi thay thế UIApplicationDelegatebởi NSApplicationDelegateUIApplicationbởi NSApplication.
nyg

5
  1. Hãy chắc chắn rằng bạn import UIKit

  2. let appDelegate = UIApplication.sharedApplication().delegate! as! AppDelegate


4

nó rất đơn giản

Ví dụ đại biểu ứng dụng

let app = UIApplication.shared.delegate as! AppDelegate

bạn có thể gọi một phương thức với cú pháp một dòng

app.callingMethod()

bạn có thể truy cập một biến với mã này

app.yourVariable = "Assigning a value"

2

Trong trường hợp của tôi, tôi đã bị mất import UIKittrên đầu NSManagedObjectlớp con của tôi . Sau khi nhập nó, tôi có thể loại bỏ lỗi đó như UIApplicationlà một phần củaUIKit

Hy vọng nó sẽ giúp người khác !!!


2

Tôi sử dụng điều này trong Swift 2.3.

1.trong lớp AppDelegate

static let sharedInstance: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate

2.Call AppDelegate với

let appDelegate = AppDelegate.sharedInstance

2
extension AppDelegate {

    // MARK: - App Delegate Ref
    class func delegate() -> AppDelegate {
        return UIApplication.shared.delegate as! AppDelegate
    }
}

2

Kể từ iOS 12.2 và Swift 5.0, AppDelegatekhông phải là một biểu tượng được công nhận. UIApplicationDelegateLà. Bất kỳ câu trả lời đề cập đến AppDelegatelà do đó không còn đúng. Câu trả lời sau đây là chính xác và tránh việc hủy bỏ lực lượng, điều mà một số nhà phát triển coi là mùi mã:

import UIKit

extension UIViewController {
  var appDelegate: UIApplicationDelegate {
    guard let appDelegate = UIApplication.shared.delegate else {
      fatalError("Could not determine appDelegate.")
    }
    return appDelegate
  }
}

1
Trong swift5, mã của bạn sẽ đưa ra cảnh báo "UIApplication.delegate phải được sử dụng từ chỉ chủ đề chính". Bạn có thể cập nhật câu trả lời.
Mahesh Narla

đó fatalErrorlà chức năng tương đương với một lực lượng unrap!
pkamb

1

Trong Swift 3.0, bạn có thể lấy appdelegatetham chiếu bằng cách

let appDelegate = UIApplication.shared.delegate as! AppDelegate

0

Trong Xcode 6.2, điều này cũng hoạt động

let appDelegate = UIApplication.sharedApplication().delegate! as AppDelegate

let aVariable = appDelegate.someVariable

2
v01d, bạn đã lấy nó từ đâu?
NSPratik
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.