অবজেক্টিভ-সি-তে, একটি কাস্টম বিজ্ঞপ্তিটি কেবল একটি সরল এনএসএসস্ট্রিং, তবে এটি কী হওয়া উচিত তা সুইফট 3-এর ডাব্লুডাব্লুডিসি সংস্করণে সুস্পষ্ট নয়।
অবজেক্টিভ-সি-তে, একটি কাস্টম বিজ্ঞপ্তিটি কেবল একটি সরল এনএসএসস্ট্রিং, তবে এটি কী হওয়া উচিত তা সুইফট 3-এর ডাব্লুডাব্লুডিসি সংস্করণে সুস্পষ্ট নয়।
উত্তর:
আপনি এটির জন্য একটি প্রোটোকলও ব্যবহার করতে পারেন
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
পরিবর্তনের জন্য বাস্তবায়নের ক্ষেত্রে আপনাকে কেবল আপনার প্রোটোকলটি পরিবর্তন করতে হবে ।
NotificationName
যাতে name
সম্পত্তিটি কেবল প্রোটোকলের সাথে সঙ্গতিপূর্ণ এনামগুলিতে যুক্ত হয়।
extension NotificationName where Self: RawRepresentable, Self.RawValue == String {
এটি অর্জনের জন্য একটি ক্লিনার (আমার মনে হয়) উপায় আছে
extension Notification.Name {
static let onSelectedSkin = Notification.Name("on-selected-skin")
}
এবং তারপরে আপনি এটি এটি ব্যবহার করতে পারেন
NotificationCenter.default.post(name: .onSelectedSkin, object: selectedSkin)
extension NSNotification.Name
পরিবর্তে extension Notification.Name
। অন্যথায় সুইফ্ট 3 অভিযোগ সহ'Notification' is ambiguous for type lookup in this context
বিজ্ঞপ্তি.পোস্ট হিসাবে সংজ্ঞায়িত করা হয়:
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)
Notification.Name
এনাম হন, কেউই নতুন বিজ্ঞপ্তিগুলি সংজ্ঞায়িত করতে সক্ষম হবে না। আমরা অন্যথায় এনম-জাতীয় ধরণের জন্য স্ট্রাক্ট ব্যবহার করি যা নতুন সদস্য যুক্ত করার অনুমতি দেয়। ( দ্রুত-বিবর্তনের প্রস্তাব দেখুন ))
Notification
এটি একটি মান ধরণের (একটি কাঠামো), যাতে এটি মান (ইম) পরিবর্তনের জন্য সুইফটের শব্দার্থবিজ্ঞান থেকে উপকৃত হতে পারে। সাধারণত, ফাউন্ডেশন প্রকারগুলি তাদের "এনএস" নামাচ্ছে সুইফ্ট 3 এ, তবে যেখানে নতুন ফাউন্ডেশন মান ধরণের একটি বিদ্যমান, সেখানে পুরানো রেফারেন্স টাইপটি চারপাশে আটকে আছে ("এনএস" নাম রেখে) যাতে আপনি এখনও এটি ব্যবহার করতে পারেন আপনার রেফারেন্স শব্দার্থবিদ্যা বা এটি সাবক্লাস প্রয়োজন। প্রস্তাব দেখুন ।
সহজ উপায়:
let name:NSNotification.Name = NSNotification.Name("notificationName")
NotificationCenter.default.post(name: name, object: nil)
আপনি এনএসএনটিফিকেশন.নামে একটি কাস্টম ইনিশিয়ালাইজার যুক্ত করতে পারেন
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)
case
উচিত, এনাম নিজেই নয়। প্রকারের নামগুলি বড় আকারের এবং এনামগুলি প্রকার types
আমি অন্য একটি বিকল্প প্রস্তাব করতে পারি যা @ সিজারভারেলা প্রস্তাবিত অনুরূপ।
extension Notification.Name {
static var notificationName: Notification.Name {
return .init("notificationName")
}
}
এটি আপনাকে বিজ্ঞপ্তিগুলিতে সহজেই পোস্ট এবং সাবস্ক্রাইব করতে দেয়।
NotificationCenter.default.post(Notification(name: .notificationName))
আশা করি এটা তোমাকে সাহায্য করবে।
আমি সেখান থেকে ওখান থেকে জিনিসগুলিকে মিশ্রিত করে নিজস্ব বাস্তবায়ন করেছি এবং এটি সবচেয়ে সুবিধাজনক হিসাবে খুঁজে পেয়েছি। আগ্রহী কারও জন্য ভাগ করে নেওয়া:
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)
}
}
NSNotification.Name(rawValue: "myNotificationName")
এটি কেবল রেফারেন্স
// 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)
এনামগুলি ব্যবহার করার সুবিধাটি হ'ল আমরা নামটি সঠিক কিনা তা পরীক্ষা করতে সংকলকটি পাই। সম্ভাব্য সমস্যাগুলি হ্রাস করে এবং রিফ্যাক্টরিংকে সহজ করে তোলে।
যারা বিজ্ঞপ্তি নামগুলির জন্য উদ্ধৃত স্ট্রিংয়ের পরিবর্তে এনাম ব্যবহার করতে চান তাদের পক্ষে এই কোডটি কৌশলটি কার্যকর করে:
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)
আপনি যদি কেবল স্ট্রিং-এর কাস্টম বিজ্ঞপ্তি ব্যবহার করেন তবে কোনও ক্লাস বাড়ানোর কারণ নেই String
extension String {
var notificationName : Notification.Name{
return Notification.Name.init(self)
}
}
আপনি যদি এমন কোনও প্রকল্পে পরিষ্কারভাবে কাজ করতে চান যা একই সাথে অবজেক্টিভ-সি এবং সুইফট উভয়ই ব্যবহার করে, তবে আমি লক্ষ্য করেছিলাম যে উদ্দেশ্য-সিটিতে বিজ্ঞপ্তিগুলি তৈরি করা আরও সহজ।
একটি .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)