আপনি কীভাবে সুইফট 3 এ কাস্টম বিজ্ঞপ্তি তৈরি করবেন?


112

অবজেক্টিভ-সি-তে, একটি কাস্টম বিজ্ঞপ্তিটি কেবল একটি সরল এনএসএসস্ট্রিং, তবে এটি কী হওয়া উচিত তা সুইফট 3-এর ডাব্লুডাব্লুডিসি সংস্করণে সুস্পষ্ট নয়।


উত্তর:


32

আপনি এটির জন্য একটি প্রোটোকলও ব্যবহার করতে পারেন

protocol NotificationName {
    var name: Notification.Name { get }
}

extension RawRepresentable where RawValue == String, Self: NotificationName {
    var name: Notification.Name {
        get {
            return Notification.Name(self.rawValue)
        }
    }
}

এবং তারপরে আপনার নোটিফিকেশন নামগুলি enumযে কোনও জায়গাতেই সংজ্ঞায়িত করুন । উদাহরণ স্বরূপ:

class MyClass {
    enum Notifications: String, NotificationName {
        case myNotification
    }
}

এবং এটি ব্যবহার করুন

NotificationCenter.default.post(name: Notifications.myNotification.name, object: nil)

এইভাবে ফাউন্ডেশন থেকে বিজ্ঞপ্তির নামগুলি বাতিল করা হবে Notification.Name। এবং Notification.Nameপরিবর্তনের জন্য বাস্তবায়নের ক্ষেত্রে আপনাকে কেবল আপনার প্রোটোকলটি পরিবর্তন করতে হবে ।


এটি হ'ল ঠিক সেভাবেই আমি মূলত ভেবেছিলাম এটি কাজ করা উচিত - বিজ্ঞপ্তিগুলি enums হওয়া উচিত। কৌতুক জন্য ধন্যবাদ!
hexdreamer

সমস্যা নেই! আমি কোডটি সম্পাদনা করে এক্সটেনশনের ধারণাটি অন্তর্ভুক্ত করলাম NotificationNameযাতে nameসম্পত্তিটি কেবল প্রোটোকলের সাথে সঙ্গতিপূর্ণ এনামগুলিতে যুক্ত হয়।
হালিল_জি

কঠোরভাবে সমতুল্য কিন্তু আরও যুক্তিযুক্ত আইএমও, আপনি নোটিফিকেশননেমে (রোলের উপস্থাপনার পরিবর্তে) এর মতো এক্সটেনশনটি এভাবে সংজ্ঞায়িত করতে পারেন:extension NotificationName where Self: RawRepresentable, Self.RawValue == String {
জেজেজে

386

এটি অর্জনের জন্য একটি ক্লিনার (আমার মনে হয়) উপায় আছে

extension Notification.Name {

    static let onSelectedSkin = Notification.Name("on-selected-skin")
}

এবং তারপরে আপনি এটি এটি ব্যবহার করতে পারেন

NotificationCenter.default.post(name: .onSelectedSkin, object: selectedSkin)

2
আমি উপরের কোড ব্যবহার করছি। এটি একটি স্থিতিশীল সম্পত্তি।
সিজার ভারেলা

3
খুব পরিষ্কার, আমি এটি খুব পছন্দ করি
টম ওল্টার্স

10
extension NSNotification.Name পরিবর্তে extension Notification.Name । অন্যথায় সুইফ্ট 3 অভিযোগ সহ'Notification' is ambiguous for type lookup in this context
lluisgh

9
আপনি স্ট্রিংয়ে টাইপো তৈরি করার জন্য এবং এইভাবে টাইপ করা বিজ্ঞপ্তির নামের মূল্য প্রদর্শন করার জন্য আমার উত্সাহ পাবেন: পি
ডরিয়ান রায়

10
উল্লেখ্য যে, এই পদ্ধতি WWDC 2016 সেশন 207 অ্যাপলের দ্বারা প্রস্তাবিত হয় মূল্য হতে পারে developer.apple.com/videos/play/wwdc2016/207
লিওন

36

বিজ্ঞপ্তি.পোস্ট হিসাবে সংজ্ঞায়িত করা হয়:

public func post(name aName: NSNotification.Name, object anObject: AnyObject?)

অবজেক্টিভ-সি-তে, বিজ্ঞপ্তির নামটি একটি সরল এনএসএসস্ট্রিং। সুইফটে এটিকে এনএসএনটিফিকেশন.নাম হিসাবে সংজ্ঞায়িত করা হয়েছে।

NSNotifications.Name হিসাবে সংজ্ঞায়িত করা হয়:

public struct Name : RawRepresentable, Equatable, Hashable, Comparable {
    public init(_ rawValue: String)
    public init(rawValue: String)
}

এটি এক ধরণের অদ্ভুত, যেহেতু আমি এটি একটি এনাম হওয়ার আশা করব, এবং কোনও কাস্টম কাঠামো আপাতদৃষ্টিতে আরও কোনও সুবিধা নয়।

এনএসএনটিফিকেশন.নামের জন্য বিজ্ঞপ্তিতে একটি টাইপালিয়াস রয়েছে: নাম:

public typealias Name = NSNotification.Name

বিভ্রান্তিকর অংশটি হ'ল নোটিফিকেশন এবং এনএসএনটিফিকেশন উভয়ই সুইফটে বিদ্যমান

সুতরাং আপনার নিজস্ব কাস্টম বিজ্ঞপ্তি সংজ্ঞায়িত করতে, কিছু মত করুন:

public class MyClass {
    static let myNotification = Notification.Name("myNotification")
}

তারপরে এটি কল করতে:

NotificationCenter.default().post(name: MyClass.myNotification, object: self)

3
ভাল উত্তর. কিছু মন্তব্য: এটি এক ধরণের অদ্ভুত, যেহেতু আমি এটি এনাম হওয়ার আশা করব - একটি এনাম একটি বদ্ধ সেট। যদি Notification.Nameএনাম হন, কেউই নতুন বিজ্ঞপ্তিগুলি সংজ্ঞায়িত করতে সক্ষম হবে না। আমরা অন্যথায় এনম-জাতীয় ধরণের জন্য স্ট্রাক্ট ব্যবহার করি যা নতুন সদস্য যুক্ত করার অনুমতি দেয়। ( দ্রুত-বিবর্তনের প্রস্তাব দেখুন ))
রিক্সার

2
বিভ্রান্তিমূলক অংশটি হ'ল নোটিফিকেশন এবং এনএসএনটিফিকেশন উভয়ই সুইফটে বিদ্যমান - Notificationএটি একটি মান ধরণের (একটি কাঠামো), যাতে এটি মান (ইম) পরিবর্তনের জন্য সুইফটের শব্দার্থবিজ্ঞান থেকে উপকৃত হতে পারে। সাধারণত, ফাউন্ডেশন প্রকারগুলি তাদের "এনএস" নামাচ্ছে সুইফ্ট 3 এ, তবে যেখানে নতুন ফাউন্ডেশন মান ধরণের একটি বিদ্যমান, সেখানে পুরানো রেফারেন্স টাইপটি চারপাশে আটকে আছে ("এনএস" নাম রেখে) যাতে আপনি এখনও এটি ব্যবহার করতে পারেন আপনার রেফারেন্স শব্দার্থবিদ্যা বা এটি সাবক্লাস প্রয়োজন। প্রস্তাব দেখুন ।
রিক্সার

আমাকে স্পষ্ট করতে দাও: আমি আশা করি যে বিজ্ঞপ্তির নামগুলি ত্রুটিগুলির মতো এনাম হবে ums আপনি নিজের ত্রুটি এনামগুলি সংজ্ঞায়িত করতে পারেন এবং এটিকে ত্রুটি টাইপের সাথে সামঞ্জস্য করতে পারেন।
হেক্সড্রিমার

1
সত্য - অ্যাপল কমপক্ষে তাত্ত্বিকভাবে নোটোফিকেশননাম (বা এ জাতীয় কিছু) একটি প্রোটোকল তৈরি করতে পারত, যার সাথে আপনি অনুসরনকারী প্রকারগুলি তৈরি করেন। আমি জানি, তবে সম্ভবত কারণ আছে যা তারা করেন নি ... সম্ভবত ওজেজির ব্রিজিংয়ের সাথে কিছু করার সম্ভবত? আপনার যদি আরও ভাল সমাধান কাজ হয়ে যায় তবে একটি বাগ ফাইল করুন ( উত্স উত্স করতে , ফাউন্ডেশন সুইফট উন্মুক্ত রয়েছে)।
রিক্সার

2
আপনি সম্ভবত এটি সঠিক যে এটি ছোট হাতের সাথে শুরু করা উচিত।
hexdreamer


11

আপনি এনএসএনটিফিকেশন.নামে একটি কাস্টম ইনিশিয়ালাইজার যুক্ত করতে পারেন

extension NSNotification.Name {
    enum Notifications: String {
        case foo, bar
    }
    init(_ value: Notifications) {
        self = NSNotification.Name(value.rawValue)
    }
}

ব্যবহার:

NotificationCenter.default.post(name: Notification.Name(.foo), object: nil)

1
সুইফট
৩.০.২ এর

@ জলাকু কেবল একটি এনামের এসগুলি নীচে রাখা caseউচিত, এনাম নিজেই নয়। প্রকারের নামগুলি বড় আকারের এবং এনামগুলি প্রকার types
ম্যানমাল

9

আমি অন্য একটি বিকল্প প্রস্তাব করতে পারি যা @ সিজারভারেলা প্রস্তাবিত অনুরূপ।

extension Notification.Name {
    static var notificationName: Notification.Name {
        return .init("notificationName")
    }
}

এটি আপনাকে বিজ্ঞপ্তিগুলিতে সহজেই পোস্ট এবং সাবস্ক্রাইব করতে দেয়।

NotificationCenter.default.post(Notification(name: .notificationName))

আশা করি এটা তোমাকে সাহায্য করবে।


4

আমি সেখান থেকে ওখান থেকে জিনিসগুলিকে মিশ্রিত করে নিজস্ব বাস্তবায়ন করেছি এবং এটি সবচেয়ে সুবিধাজনক হিসাবে খুঁজে পেয়েছি। আগ্রহী কারও জন্য ভাগ করে নেওয়া:

public extension Notification {
    public class MyApp {
        public static let Something = Notification.Name("Notification.MyApp.Something")
    }
}

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(self.onSomethingChange(notification:)),
                                               name: Notification.MyApp.Something,
                                               object: nil)
    }

    deinit {
        NotificationCenter.default.removeObserver(self)
    }

    @IBAction func btnTapped(_ sender: UIButton) {
        NotificationCenter.default.post(name: Notification.MyApp.Something,
                                      object: self,
                                    userInfo: [Notification.MyApp.Something:"foo"])
    }

    func onSomethingChange(notification:NSNotification) {
        print("notification received")
        let userInfo = notification.userInfo!
        let key = Notification.MyApp.Something 
        let something = userInfo[key]! as! String //Yes, this works :)
        print(something)
    }
}


2

এটি কেবল রেফারেন্স

// Add observer:
NotificationCenter.default.addObserver(self,
    selector: #selector(notificationCallback),
    name: MyClass.myNotification,
    object: nil)

    // Post notification:
    let userInfo = ["foo": 1, "bar": "baz"] as [String: Any]
    NotificationCenter.default.post(name: MyClass.myNotification,
        object: nil,
        userInfo: userInfo)

1

এনামগুলি ব্যবহার করার সুবিধাটি হ'ল আমরা নামটি সঠিক কিনা তা পরীক্ষা করতে সংকলকটি পাই। সম্ভাব্য সমস্যাগুলি হ্রাস করে এবং রিফ্যাক্টরিংকে সহজ করে তোলে।

যারা বিজ্ঞপ্তি নামগুলির জন্য উদ্ধৃত স্ট্রিংয়ের পরিবর্তে এনাম ব্যবহার করতে চান তাদের পক্ষে এই কোডটি কৌশলটি কার্যকর করে:

enum MyNotification: String {
    case somethingHappened
    case somethingElseHappened
    case anotherNotification
    case oneMore
}

extension NotificationCenter {
    func add(observer: Any, selector: Selector, 
             notification: MyNotification, object: Any? = nil) {
        addObserver(observer, selector: selector, 
                    name: Notification.Name(notification.rawValue),
                    object: object)
    }
    func post(notification: MyNotification, 
              object: Any? = nil, userInfo: [AnyHashable: Any]? = nil) {
        post(name: NSNotification.Name(rawValue: notification.rawValue), 
             object: object, userInfo: userInfo)
    }
}

তারপরে আপনি এটি ব্যবহার করতে পারেন:

NotificationCenter.default.post(.somethingHappened)

প্রশ্নের সাথে সম্পর্কিত না হলেও, উদ্ধৃত স্ট্রিং টাইপ করা এড়ানোর জন্য স্টোরিবোর্ড সেগগুলি একইভাবে করা যেতে পারে:

enum StoryboardSegue: String {
    case toHere
    case toThere
    case unwindToX
}

extension UIViewController {
    func perform(segue: StoryboardSegue) {
        performSegue(withIdentifier: segue.rawValue, sender: self)
    }
}

তারপরে, আপনার ভিউ কন্ট্রোলারে, এটিকে কল করুন:

perform(segue: .unwindToX)

> NotificationCenter.default.post(.somethingHappened)এটি একটি ত্রুটি ছুড়ে ফেলে; আপনি আপনার এক্সটেনশনে যুক্ত পদ্ধতিগুলি আরও যুক্তি স্বীকার করে।

0

আপনি যদি কেবল স্ট্রিং-এর কাস্টম বিজ্ঞপ্তি ব্যবহার করেন তবে কোনও ক্লাস বাড়ানোর কারণ নেই String

    extension String {
        var notificationName : Notification.Name{
            return Notification.Name.init(self)
        }
    }

0

@ সিজারওয়ারেলার উত্তরটি ভাল, তবে কোডটি কিছুটা পরিষ্কার করার জন্য আপনি নিম্নলিখিতটি করতে পারেন:

extension Notification.Name {
    typealias Name = Notification.Name

    static let onSelectedSkin = Name("on-selected-skin")
    static let onFoo = Name("on-foo")
}

0

আপনি যদি এমন কোনও প্রকল্পে পরিষ্কারভাবে কাজ করতে চান যা একই সাথে অবজেক্টিভ-সি এবং সুইফট উভয়ই ব্যবহার করে, তবে আমি লক্ষ্য করেছিলাম যে উদ্দেশ্য-সিটিতে বিজ্ঞপ্তিগুলি তৈরি করা আরও সহজ।

একটি .m / .h ফাইল তৈরি করুন:

//CustomNotifications.h
#import <Foundation/Foundation.h>

// Add all notifications here
extern const NSNotificationName yourNotificationName;
//CustomNotifications.m
#import "CustomNotifications.h"

// Add their string values here
const NSNotificationName yourNotificationName = @"your_notification_as_string";

আপনার MyProject-Bridging-Header.h(আপনার প্রকল্পের নাম অনুসারে) এগুলিকে সুইফটে প্রকাশ করার জন্য।

#import "CustomNotifications.h"

আপনার বিজ্ঞপ্তিগুলি যেমন উদ্দেশ্য সি-তে ব্যবহার করুন:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(yourMethod:) name:yourNotificationName:nil];

এবং সুইফটে (5) এর মতো:

NotificationCenter.default.addObserver(self, selector: #selector(yourMethod(sender:)), name: .yourNotificationName, object: nil)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.