Swift에서 앱 델리게이트에 대한 참조를 얻으려면 어떻게해야합니까?


409

Swift에서 앱 델리게이트에 대한 참조를 얻으려면 어떻게해야합니까?

궁극적으로 참조를 사용하여 관리 객체 컨텍스트에 액세스하고 싶습니다.


8
일부는 관리되는 객체 컨텍스트 또는 다른 "전역"객체에 대한 컨테이너로 앱 대리자를 사용하여 반 패턴으로 간주합니다. 컨트롤러가 컨트롤러를 찾도록하는 대신 앱 델리게이트가 MOC를 컨트롤러에 전달하도록하십시오.
Kristopher Johnson

1
@KristopherJohnson Hey Kris, View 컨트롤러에 의존성을 주입하는 AppDelegate를 어떻게 용이하게 할 수 있습니까? 프로그래밍 방식으로 뷰 컨트롤러를 인스턴스화하고 리플렉션을 사용하여 재귀 적으로 인스턴스화 / 주입 할 항목을 결정합니까? 이를 도울 수있는 프레임 워크가 있습니까? 모든 뷰 컨트롤러에 대해 수동 으로이 작업을 수행해야한다면 AppDelegate가 커질 것입니다! 아, 바람직하게는 모든 것을위한 공장을 만들지 않고 :)
Jimbo

1
커서 검색 Swinject 또한 자동 배선이 있습니다 :)
Jimbo

6
응용 프로그램 델리게이트에 "익명 한"것을 넣지 말라고 조언하는 프로그래머에게는 애플 문서 "crucial role"UIApplicationDelegate싱글 톤 중 하나가 "...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

답변:


757

다른 솔루션은 응용 프로그램의 대리자에 대한 참조를 얻는다는 점에서 맞지만 관리되는 객체 컨텍스트와 같이 UIApplication의 하위 클래스에 의해 추가 된 메서드 나 변수에는 액세스 할 수 없습니다. 이 문제를 해결하려면 간단히 "AppDelegate"로 다운 캐스트하거나 UIApplication 서브 클래스를 호출하십시오. 에서는 신속한 3, 4 및 5 는 다음과 같이, 이것은 이루어진다 :

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

10
누구든지 여전히 문제가있는 경우 OS X를 대상으로 지정하려면 Cocoa를 가져와 NSApplication.sharedApplication ()에서 작동해야합니다. iOS에는 동등한 것이 필요하다고 생각합니다.
smaurice

2
이것은 두 가지 답변 중 더 유용합니다.
Joe

3
@zacjordaan이 방법을 사용하면 속성에 대한 자동 완성 기능이 제공되지만 실제로 작동하지는 않습니다. 그렇게하면 사용할 때마다 AppDelegate 클래스의 새 인스턴스가 만들어집니다. sharedApplication 싱글 톤을 통해 액세스 할 수있는 대리자를 사용하는 것이 좋습니다. 그리고 두 번째 질문이 진행되는 한, 상수를 사용하고 싶을 것입니다. 그러나 AppDelegate의 속성을 변경하더라도 포인터를 다른 것에 다시 할당하지 않을 것입니다.이 경우 변수가 필요하지 않습니다. 그러나 이것은 완전히 당신에게 달려 있습니다. 필요에 맞는 것을하십시오.
Mick MacCallum

2
훌륭한 조언! 나는 AppDelegate ()가 싱글 톤이라고 잘못 생각했지만 당신이 말한 것을 생각한 후에 그것이 있다면 우리 가이 방법으로 사용할 수있는 sharedApplication 패턴이 없다는 것을 깨달았습니다. 물론 필요하지 않은 경우 불필요한 인스턴스를 생성하고 싶지 않으므로 상수 선언이 완벽하게 적합합니다. 감사합니다.
zacjordaan

4
이 답변을 별도의 답변으로 추가하고 싶지 않지만 Swift와 Obj-c가 모두 사용되는 프로젝트의 속성, 자체 메서드로 AppDelegate를 얻으려면 #Import "AppDelegate.h"를 "ProjectName-BridgingHeader"에 추가해야합니다 .h "
Marcin Mierzejewski

44

스위프트 4.2

스위프트에서는 VC에서 쉽게 액세스 할 수 있습니다.

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

25

편의 생성자

코드 끝에 AppDelegate 클래스에 추가

스위프트 5

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

수업에서 AppDelegate 참조를 사용하려면?


AppDelegate 메소드 호출

appDelegate (). setRoot ()


setRoot ()의 기능과 호출시기를 설명하는 것이 좋습니다. 예를 들어 ViewController에서 호출해도됩니까? 창이 아직 설정되지 않은 단위 테스트에서? 더 많은 맥락이 좋을 것입니다.
Houman

@Houman setRoot는 AppDelegate의 메소드로 여러 Roots 또는 ParentViewController 사이를 전환하는 데 사용할 수 있으며 모든 메소드가 될 수 있습니다. 추가 액세스를 위해 AppDelegate의 참조를 얻는 방법에 대한 토론이지만 setRoot도 명확해야합니다.
AiOsN

19

Objective-C와 거의 동일합니다.

let del = UIApplication.sharedApplication().delegate

19

이것은 OS X에 사용될 수 있습니다

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

3
아니면 간단히let appDelegate = NSApp.delegate as AppDelegate
Vladimir Prudnikov

1
에서 스위프트 3 사용let appDelegate = NSApplication.shared().delegate as AppDelegate
더크

4
에서 스위프트 4 :NSApp.delegate as? AppDelegate

12

Swift 2.0 버전은 다음과 같습니다.

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

그리고 관리 객체 컨텍스트에 액세스하려면 :

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

        let moc = delegate.managedObjectContext

        // your code here

    }

또는 guard를 사용하여 :

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

    let moc = delegate.managedObjectContext

    // your code here

10

스위프트 <3

Ex 용 AppDelegate 클래스에서 메소드 작성

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

전 다른 곳으로 불러

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

스위프트> = 3.0

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

2
이것은 또한 작동하며 sharedInstance 이름 지정 아이디어를 좋아합니다. 감사!
John Griffiths

2
AppDelegate전화를 걸 때마다 예를 들어 새 객체를 인스턴스화합니다.AppDelegate().sharedInstance()
pxpgraphics

1
나는이 솔루션을 받아 들여진 것보다 더 좋아한다 (만약 당신이 그것을 다 써야한다면 "심지어"장황하다). 이 답변을 extension찾기 NSApplication전에 for 를 실험하는 것에 대해 생각하고 있었지만 훨씬 좋습니다. 요즘 클래스 계산 된 읽기 전용 속성을 사용하고 싶을 shared수도 있습니다. 스위프트 3에 대한 업데이트를 게시하고 싶습니까?
Patru

1
실제로이 static var shared : TournamentDelegate? { get { return NSApplication.shared().delegate as? TournamentDelegate } }유형의 사물에 대해 계산 된 읽기 전용 속성을 사용하는 Swift 3 스타일을 개발하는 데 더 적합한 코드를 사용하여 코드를 리팩토링하는 중입니다. ?리팩토링이 완료되면 아마 떨어질 수있을 것입니다. (죄송합니다. 주석의 코드 형식은 항상 엉망입니다.)
Patru

@ pxpgraphics UIApplication은 싱글 톤 클래스이므로 다중 인스턴스화에 대해 걱정할 필요가 없습니다.
Abhijith가


6

간단히 이것을 시도하십시오 :

스위프트 4

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

AppDelegate의 위치 :

// MARK: - Whatever
func whateverWillOccur() {

    // Your code here.

}

5

클래스 이름을 UIApplicationDelegate하드 코딩하지 않는 확장 기능은 다음과 같습니다 AppDelegate.

extension UIApplicationDelegate {

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

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

이를 위해 Mac에서 NSApplicationDelegate다음을 제공합니다 'Self' is only available in a protocol or as the result of a method in a class; did you mean 'AppDelegate'?. 이것이 구식입니까?
pkamb

@ pkamb 방금 새 프로젝트에서 시도했지만이 오류가 없습니다. 나는 대체 UIApplicationDelegateNSApplicationDelegateUIApplication에 의해 NSApplication.
nyg

5
  1. 당신을 확인 import UIKit

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


4

매우 간단합니다

앱 대리자 인스턴스

let app = UIApplication.shared.delegate as! AppDelegate

한 줄 구문으로 메소드를 호출 할 수 있습니다

app.callingMethod()

이 코드로 변수에 액세스 할 수 있습니다

app.yourVariable = "Assigning a value"

2

필자의 경우 하위 클래스 import UIKit위에 누락되었습니다 NSManagedObject. 그것을 가져온 후, 나는 UIApplication그 일부 로서 그 오류를 제거 할 수 있었다UIKit

그것이 다른 사람들을 돕기를 바랍니다!


2

나는 이것을 스위프트 2.3에서 사용한다.

1. AppDelegate 클래스에서

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

2. 전화 걸기

let appDelegate = AppDelegate.sharedInstance

2
extension AppDelegate {

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

2

iOS 12.2 및 Swift 5.0부터는 AppDelegate인식되는 기호가 아닙니다. UIApplicationDelegate입니다. AppDelegate따라서 언급 된 답변 은 더 이상 정확하지 않습니다. 다음 답변은 정확하고 강제 언 래핑을 피하며 일부 개발자는 코드 냄새를 고려합니다.

import UIKit

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

1
swift5에서 코드는 "UIApplication.delegate는 주 스레드에서만 사용해야합니다"경고를 표시합니다. 답변을 업데이트 할 수 있습니까?
Mahesh Narla

그것은 fatalError기능적으로 강제 랩 해제와 같습니다!
pkamb

1

Swift 3.0에서는 다음을 통해 appdelegate참조를 얻을 수 있습니다.

let appDelegate = UIApplication.shared.delegate as! AppDelegate

0

Xcode 6.2에서는 작동합니다

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

let aVariable = appDelegate.someVariable

2
v01d, 어디에서 가져 왔습니까?
NSPratik
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.