कैसे एक प्रतिनिधि बनाने के बारे NSUserNotificationCenterDelegate
में जाता है , यानी स्विफ्ट में?
कैसे एक प्रतिनिधि बनाने के बारे NSUserNotificationCenterDelegate
में जाता है , यानी स्विफ्ट में?
जवाबों:
ऐसा नहीं है कि obj-c से अलग है। सबसे पहले, आपको अपनी कक्षा की घोषणा में प्रोटोकॉल को निर्दिष्ट करना होगा, जैसे निम्नलिखित:
class MyClass: NSUserNotificationCenterDelegate
कार्यान्वयन निम्न प्रकार दिखाई देगा:
// NSUserNotificationCenterDelegate implementation
func userNotificationCenter(center: NSUserNotificationCenter, didDeliverNotification notification: NSUserNotification) {
//implementation
}
func userNotificationCenter(center: NSUserNotificationCenter, didActivateNotification notification: NSUserNotification) {
//implementation
}
func userNotificationCenter(center: NSUserNotificationCenter, shouldPresentNotification notification: NSUserNotification) -> Bool {
//implementation
return true
}
बेशक, आपको प्रतिनिधि को सेट करना होगा। उदाहरण के लिए:
NSUserNotificationCenter.defaultUserNotificationCenter().delegate = self;
@interface MyCustomClass: UIViewController <ClassIWantToUseDelegate>
, जिससे आप इनकंट्रोल / व्यू कॉन्क्रोलर को कॉन्फ़िगर कर सकते हैं , और साथ ही सब-वे पर डेलिगेट विधियों को बुला सकते हैं? कुछ के लिए इसी तरह इस ?
यहां दो दृश्य नियंत्रकों के बीच प्रतिनिधियों पर थोड़ी मदद की गई है:
चरण 1: UIViewController में एक प्रोटोकॉल बनाएं जिसे आप हटा रहे होंगे / डेटा भेज रहे होंगे।
protocol FooTwoViewControllerDelegate:class {
func myVCDidFinish(_ controller: FooTwoViewController, text: String)
}
Step2: भेजने वाले वर्ग में प्रतिनिधि की घोषणा करें (अर्थात UIViewcontroller)
class FooTwoViewController: UIViewController {
weak var delegate: FooTwoViewControllerDelegate?
[snip...]
}
चरण 3: डेटा को प्राप्त करने की विधि को भेजने के लिए एक वर्ग विधि में प्रतिनिधि का उपयोग करें, जो कि प्रोटोकॉल को अपनाने वाली कोई भी विधि है।
@IBAction func saveColor(_ sender: UIBarButtonItem) {
delegate?.myVCDidFinish(self, text: colorLabel.text) //assuming the delegate is assigned otherwise error
}
चरण 4: प्राप्त वर्ग में प्रोटोकॉल को अपनाएं
class ViewController: UIViewController, FooTwoViewControllerDelegate {
चरण 5: प्रतिनिधि पद्धति को लागू करें
func myVCDidFinish(_ controller: FooTwoViewController, text: String) {
colorLabel.text = "The Color is " + text
controller.navigationController.popViewController(animated: true)
}
चरण 6: प्रतिनिधि को तैयार करेंफॉर्गी में सेट करें:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "mySegue" {
let vc = segue.destination as! FooTwoViewController
vc.colorString = colorLabel.text
vc.delegate = self
}
}
और वह काम करना चाहिए। यह बेशक कोड के टुकड़े हैं, लेकिन आपको यह विचार देना चाहिए। इस कोड की एक लंबी व्याख्या के लिए आप यहां मेरे ब्लॉग प्रविष्टि पर जा सकते हैं:
यदि आप रुचि रखते हैं कि एक प्रतिनिधि के साथ हुड के नीचे क्या चल रहा है, तो मैंने उस पर यहां लिखा था:
weak
केवल कक्षाओं के लिए आवश्यक है न कि संरचना और एनम। यदि प्रतिनिधि एक संरचना या एनम होने जा रहा है, तो आपको चक्र बनाए रखने के बारे में चिंता करने की आवश्यकता नहीं है। हालाँकि, एक प्रतिनिधि को उसकी कक्षा (यह बहुत सारे मामलों के लिए सच है क्योंकि अक्सर एक ViewController है), तो आपको जरूरत है weak
लेकिन आपको अपने प्रोटोकॉल को एक वर्ग के रूप में घोषित करने की आवश्यकता है। अधिक जानकारी यहाँ है stackoverflow.com/a/34566876/296446
प्रतिनिधि हमेशा मुझे भ्रमित करते हैं जब तक मुझे एहसास नहीं हुआ कि एक प्रतिनिधि केवल एक वर्ग है जो किसी अन्य वर्ग के लिए कुछ काम करता है । यह किसी और के होने जैसा है कि आपके लिए सभी गंदे काम करने के लिए जो आप खुद नहीं करना चाहते हैं।
मैंने इसे स्पष्ट करने के लिए एक छोटी कहानी लिखी। यदि आप चाहें तो इसे एक खेल के मैदान में पढ़ें।
// MARK: Background to the story
// A protocol is like a list of rules that need to be followed.
protocol OlderSiblingDelegate: class {
// The following command (ie, method) must be obeyed by any
// underling (ie, delegate) of the older sibling.
func getYourNiceOlderSiblingAGlassOfWater()
}
// MARK: Characters in the story
class BossyBigBrother {
// I can make whichever little sibling is around at
// the time be my delegate (ie, slave)
weak var delegate: OlderSiblingDelegate?
func tellSomebodyToGetMeSomeWater() {
// The delegate is optional because even though
// I'm thirsty, there might not be anyone nearby
// that I can boss around.
delegate?.getYourNiceOlderSiblingAGlassOfWater()
}
}
// Poor little sisters have to follow (or at least acknowledge)
// their older sibling's rules (ie, protocol)
class PoorLittleSister: OlderSiblingDelegate {
func getYourNiceOlderSiblingAGlassOfWater() {
// Little sis follows the letter of the law (ie, protocol),
// but no one said exactly how she had to respond.
print("Go get it yourself!")
}
}
// MARK: The Story
// Big bro is laying on the couch watching basketball on TV.
let bigBro = BossyBigBrother()
// He has a little sister named Sally.
let sally = PoorLittleSister()
// Sally walks into the room. How convenient! Now big bro
// has someone there to boss around.
bigBro.delegate = sally
// So he tells her to get him some water.
bigBro.tellSomebodyToGetMeSomeWater()
// Unfortunately no one lived happily ever after...
// The end.
समीक्षा में, प्रतिनिधि पैटर्न बनाने और उपयोग करने के लिए तीन प्रमुख भाग हैं।
ऊपर हमारे बॉसी बिग ब्रदर कहानी की तुलना में, प्रतिनिधियों को अक्सर निम्नलिखित व्यावहारिक अनुप्रयोगों के लिए उपयोग किया जाता है:
महान हिस्सा यह है कि इन वर्गों को पहले से एक दूसरे के बारे में कुछ भी जानने की जरूरत नहीं है सिवाय इसके कि प्रतिनिधि वर्ग आवश्यक प्रोटोकॉल के अनुरूप हो।
मैं निम्नलिखित दो लेखों को पढ़ने की अत्यधिक सलाह देता हूं। उन्होंने मुझे यह समझने में मदद की कि डॉक्युमेंटेशन की तुलना में प्रतिनिधियों को और भी बेहतर बनाया गया है।
एक और नोट
उस संदर्भ को संदर्भित करता है जो अन्य वर्गों के लिए है कि वे weak
मजबूत संदर्भ चक्र से बचने के लिए कीवर्ड का उपयोग न करें । देखें इस उत्तर अधिक जानकारी के लिए।
मुझे @MakeAppPie की पोस्ट के लिए कुछ सुधार मिले
सबसे पहले जब आप डेलिगेट प्रोटोकॉल बना रहे हैं तो उसे क्लास प्रोटोकॉल के अनुरूप होना चाहिए। जैसे नीचे दिए गए उदाहरण में।
protocol ProtocolDelegate: class {
func myMethod(controller:ViewController, text:String)
}
दूसरा, चक्र बनाए रखने से बचने के लिए आपका प्रतिनिधि कमजोर होना चाहिए।
class ViewController: UIViewController {
weak var delegate: ProtocolDelegate?
}
अंतिम, आप सुरक्षित हैं क्योंकि आपका प्रोटोकॉल एक वैकल्पिक मूल्य है। इसका अर्थ है कि इसका "शून्य" संदेश इस संपत्ति पर नहीं भेजा जाएगा। यह respondToselector
objC के साथ सशर्त विवरण के समान है, लेकिन यहां आपके पास एक पंक्ति में सब कुछ है:
if ([self.delegate respondsToSelector:@selector(myMethod:text:)]) {
[self.delegate myMethod:self text:@"you Text"];
}
ऊपर आपके पास एक ओजे-सी उदाहरण है और नीचे आपके पास स्विफ्ट का उदाहरण है कि यह कैसा दिखता है।
delegate?.myMethod(self, text:"your Text")
delegate?.myMethod
तो दुर्घटना नहीं होगी क्योंकि यदि प्रतिनिधि हैं nil
तो कुछ नहीं होगा। हालाँकि अगर आपने गलती की है और लिखा है कि delegate!.myMethod
आप दुर्घटनाग्रस्त हो सकते हैं अगर एक प्रतिनिधि सेट नहीं है, तो इसका मूल रूप से आपके लिए सुरक्षित होने का एक तरीका है ...
यहाँ एक जिस्ट है जिसे मैंने एक साथ रखा है। मैं भी यही सोच रहा था और इससे मेरी समझ में सुधार हुआ। यह देखने के लिए कि क्या चल रहा है , एक Xcode प्लेग्राउंड में खोलें ।
protocol YelpRequestDelegate {
func getYelpData() -> AnyObject
func processYelpData(data: NSData) -> NSData
}
class YelpAPI {
var delegate: YelpRequestDelegate?
func getData() {
println("data being retrieved...")
let data: AnyObject? = delegate?.getYelpData()
}
func processYelpData(data: NSData) {
println("data being processed...")
let data = delegate?.processYelpData(data)
}
}
class Controller: YelpRequestDelegate {
init() {
var yelpAPI = YelpAPI()
yelpAPI.delegate = self
yelpAPI.getData()
}
func getYelpData() -> AnyObject {
println("getYelpData called")
return NSData()
}
func processYelpData(data: NSData) -> NSData {
println("processYelpData called")
return NSData()
}
}
var controller = Controller()
UIViewController
हमारे द्वारा बनाए गए प्रतिनिधि के अनुरूप मैं अपनी किसी भी कक्षा को कैसे बना सकता हूं ? क्या उन्हें एक स्विफ्ट फ़ाइल में घोषित किया जाना है? किसी भी मदद का मतलब बहुत होगा।
class ViewController : UIViewController NameOfDelegate
।
a.swift
आपके उत्तर के अनुसार एक प्रतिनिधि वर्ग बनाता हूं , तो यह सामने नहीं आता है b.swift
। मैं अपनी स्विफ्ट फ़ाइल के बाहर किसी भी वर्ग तक नहीं पहुँच सकता। किसी भी मुश्किल?
स्विफ्ट 2 में प्रवेश
मैं दो viewControllers के साथ डेलिगेट के उदाहरण के साथ समझा रहा हूं। इस मामले में, दूसरा वीवीसी ऑब्जेक्ट पहले व्यू कंट्रोलर को डेटा वापस भेज रहा है।
प्रोटोकॉल घोषणा के साथ वर्ग
protocol getDataDelegate {
func getDataFromAnotherVC(temp: String)
}
import UIKit
class SecondVC: UIViewController {
var delegateCustom : getDataDelegate?
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func backToMainVC(sender: AnyObject) {
//calling method defined in first View Controller with Object
self.delegateCustom?.getDataFromAnotherVC("I am sending data from second controller to first view controller.Its my first delegate example. I am done with custom delegates.")
self.navigationController?.popViewControllerAnimated(true)
}
}
पहले ViewController प्रोटोकॉल के अनुरूप यहाँ किया जाता है:
class ViewController: UIViewController, getDataDelegate
प्रथम दृश्य नियंत्रक में प्रोटोकॉल विधि परिभाषा (ViewController)
func getDataFromAnotherVC(temp : String)
{
// dataString from SecondVC
lblForData.text = dataString
}
प्रथम दृश्य नियंत्रक (ViewController) से सेकंड को धक्का देने के दौरान
let objectPush = SecondVC()
objectPush.delegateCustom = self
self.navigationController.pushViewController(objectPush, animated: true)
प्रथम श्रेणी:
protocol NetworkServiceDelegate: class {
func didCompleteRequest(result: String)
}
class NetworkService: NSObject {
weak var delegate: NetworkServiceDelegate?
func fetchDataFromURL(url : String) {
delegate?.didCompleteRequest(url)
}
}
द्रितीय श्रेणी:
class ViewController: UIViewController, NetworkServiceDelegate {
let network = NetworkService()
override func viewDidLoad() {
super.viewDidLoad()
network.delegate = self
network.fetchDataFromURL("Success!")
}
func didCompleteRequest(result: String) {
print(result)
}
}
Type 'ViewController' does not conform to protocol 'NetworkServiceDelegate'
plz सुझाव दिखाता है। यह स्विफ्ट पर मेरा 6 वां दिन है :)
कदम से बहुत आसान कदम (100% काम और परीक्षण)
चरण 1: पहले दृश्य नियंत्रक पर विधि बनाएँ
func updateProcessStatus(isCompleted : Bool){
if isCompleted{
self.labelStatus.text = "Process is completed"
}else{
self.labelStatus.text = "Process is in progress"
}
}
चरण 2: प्रतिनिधि को दूसरे दृश्य नियंत्रक पर धकेलें
@IBAction func buttonAction(_ sender: Any) {
let secondViewController = self.storyboard?.instantiateViewController(withIdentifier: "secondViewController") as! secondViewController
secondViewController.delegate = self
self.navigationController?.pushViewController(secondViewController, animated: true)
}
चरण 3: सेट प्रतिनिधि की तरह
वर्ग ViewController: UIViewController, ProcessStatusDelegate {
step4: प्रोटोकॉल बनाएँ
protocol ProcessStatusDelegate:NSObjectProtocol{
func updateProcessStatus(isCompleted : Bool)
}
चरण 5: एक चर लें
var delegate:ProcessStatusDelegate?
Step6: जबकि पिछले व्यू कंट्रोलर कॉल डेलिगेट मेथड पर जाएं तो पहले व्यू कंट्रोलर को डेटा के साथ सूचित करें
@IBAction func buttonActionBack(_ sender: Any) {
delegate?.updateProcessStatus(isCompleted: true)
self.navigationController?.popViewController(animated: true)
}
@IBAction func buttonProgress(_ sender: Any) {
delegate?.updateProcessStatus(isCompleted: false)
self.navigationController?.popViewController(animated: true)
}
सरल उदाहरण:
protocol Work: class {
func doSomething()
}
class Manager {
weak var delegate: Work?
func passAlong() {
delegate?.doSomething()
}
}
class Employee: Work {
func doSomething() {
print("Working on it")
}
}
let manager = Manager()
let developer = Employee()
manager.delegate = developer
manager.passAlong() // PRINTS: Working on it
डेलिगेट्स एक डिज़ाइन पैटर्न है जो एक वस्तु को किसी विशिष्ट घटना के होने पर दूसरी वस्तु को संदेश भेजने की अनुमति देता है। एक वस्तु की कल्पना करें एक ए क्रिया करने के लिए एक वस्तु बी को बुलाता है। एक बार कार्रवाई पूरी होने के बाद, ऑब्जेक्ट A को पता होना चाहिए कि B ने कार्य पूरा कर लिया है और आवश्यक कार्यवाही कर रहा है, यह प्रतिनिधियों की सहायता से प्राप्त किया जा सकता है! यहाँ एक ट्यूटोरियल है जो प्रतिनिधियों को चरण 3 में तेजी से कदम बढ़ाता है
उपरोक्त समाधान थोड़ा युग्मित लग रहा था और एक ही समय में अन्य नियंत्रकों में एक ही प्रोटोकॉल का पुन: उपयोग करने से बचें, यही कारण है कि मैं उस समाधान के साथ आया हूं जो सामान्य प्रकार-इरेज़र का उपयोग करके अधिक मजबूत टाइप किया गया है।
@noreturn public func notImplemented(){
fatalError("not implemented yet")
}
public protocol DataChangedProtocol: class{
typealias DataType
func onChange(t:DataType)
}
class AbstractDataChangedWrapper<DataType> : DataChangedProtocol{
func onChange(t: DataType) {
notImplemented()
}
}
class AnyDataChangedWrapper<T: DataChangedProtocol> : AbstractDataChangedWrapper<T.DataType>{
var base: T
init(_ base: T ){
self.base = base
}
override func onChange(t: T.DataType) {
base.onChange(t)
}
}
class AnyDataChangedProtocol<DataType> : DataChangedProtocol{
var base: AbstractDataChangedWrapper<DataType>
init<S: DataChangedProtocol where S.DataType == DataType>(_ s: S){
self.base = AnyDataChangedWrapper(s)
}
func onChange(t: DataType) {
base.onChange(t)
}
}
class Source : DataChangedProtocol {
func onChange(data: String) {
print( "got new value \(data)" )
}
}
class Target {
var delegate: AnyDataChangedProtocol<String>?
func reportChange(data:String ){
delegate?.onChange(data)
}
}
var source = Source()
var target = Target()
target.delegate = AnyDataChangedProtocol(source)
target.reportChange("newValue")
उत्पादन : नया मूल्य newValue मिला
कक्षा में एक प्रतिनिधि बनाएँ जो कुछ डेटा भेजने या अन्य कक्षाओं को कुछ कार्यक्षमता प्रदान करने की आवश्यकता है
पसंद
protocol GetGameStatus {
var score: score { get }
func getPlayerDetails()
}
उसके बाद कक्षा में जो इस प्रतिनिधि की पुष्टि करने जा रहा है
class SnakesAndLadders: GetGameStatus {
func getPlayerDetails() {
}
}