Some questions about "NSStringCompareOptions" struct document in swift - ios

I just stuck in swift's document that explain how "NSStringCompareOptions" works. Just some newb questions.
struct NSStringCompareOptions : OptionSetType {
init(rawValue rawValue: UInt)
static var CaseInsensitiveSearch: NSStringCompareOptions { get }
static var LiteralSearch: NSStringCompareOptions { get }
static var BackwardsSearch: NSStringCompareOptions { get }
static var AnchoredSearch: NSStringCompareOptions { get }
static var NumericSearch: NSStringCompareOptions { get }
static var DiacriticInsensitiveSearch: NSStringCompareOptions { get }
static var WidthInsensitiveSearch: NSStringCompareOptions { get }
static var ForcedOrderingSearch: NSStringCompareOptions { get }
static var RegularExpressionSearch: NSStringCompareOptions { get }
}
and this struct contains "init" in it, when I call NSStringCompareOptions()
Why it allows the init method "rawValue" to be omitted?
and another question is that I know
NSStringCompareOptions()
is the new version as
NSStringCompareOptions.allZero
and it means "no options"
so what's the different between both below?
NSStringCompareOptions()
NSStringCompareOptions(rawValue:0)
Thank you very much for helping me.

For a better understanding, you should look at the definition of OptionSetType, which is the protocol which NSStringCompareOptions conforms to.
In addition to the basic protocol definition, you will find some extensions:
extension OptionSetType where RawValue : BitwiseOperationsType {
/// Create an empty instance.
///
/// - Equivalent to `[] as Self`
public convenience init()
...
}
And the SetAlgebraType protocol which OptionSetType conforms to:
extension SetAlgebraType {
/// Creates the set containing all elements of `sequence`.
public convenience init<S : SequenceType where S.Generator.Element == Element>(_ sequence: S)
...
}
The fact that these methods are in protocol extensions indicates that they have default implementations which are automatically provided.
You can read more about option sets in Using Swift with Cocoa and Objective-C.

Both are same NSStringCompareOptions() and NSStringCompareOptions(rawValue:0)
There is no deffernce. you can used any of those.
Good Luck and Happy coding

Related

Create a protocol with default implementation that gives name/title/self of Enum as string

I am trying to create a protocol with default implementation that returns enum itself as string. But not able to find the correct syntax.
This is the code I tried so far, but it is not taking default implementation
protocol TestSelf {
static var desc: String { get set }
}
extension TestSelf {
get {
static var desc: String {
String(describing: self)
}
set {
print(\(new value))
}
}
enum Test: TestSelf { }
Access
print(Test.desc)
Asking me to implement the desc in the enum saying 'static var' declaration requires an initializer expression or an explicitly stated getter. I don't want to initialize it again. It should work with Default Implementation.
Ask:
At all places I don't need to write
String(describing: Test.self)
instead I can directly use
Test.desc
I think you want something like this (this is playground code):
protocol SelfDescriber {
static var descriptionOfSelf: String {get}
}
extension SelfDescriber {
static var descriptionOfSelf: String {
String(describing: Self.self)
}
}
enum Test: SelfDescriber {}
print(Test.descriptionOfSelf) // "Test"

Swift Protocol-Oriented Programming: Can Protocol Extension Property Have Same Name As Base Class Property

Scenario
I am working on an SDK that will be used in two separate projects. Both projects will be using CoreData and the SDK needs to be fed data that is present in both project's managed object model. To do this I am employing a protocol-oriented design to get the SDK the data it needs.
The project will start out with a NSManagedObject base class that contains it's properties...
// Project
class Tag: NSManagedObject {
var name: String!
var code: String!
var items: [Any]!
...
}
These names are basic and simple. It would be nice to not have to change these when we conform this class to the protocol.
The SDK declares two protocols. The first protocol will be the data source the SDK will need to populate it's views. Some class in the project will conform to this and be the delegate...
// SDK
protocol SDKDataSource {
func getTaggableObjects() -> [Taggable]
}
var delegate: SDKDataSource!
The second protocol will be the ultimatum the SDK will make to it's project that the NSManagedObject it will be fed should conform to...
// SDK
protocol Taggable {
var name: String { get }
var code: String { get }
var items: [Any] { get }
}
In the project I will create an extension of the class and agree to conform that class to the Taggable protocol...
// Extension (in Project w/ SDK included)
extension Tag: Taggable {
var name: String {
get {
self.name
}
}
var code: String {
get {
self.code
}
}
var items: [Any] {
get {
self.items
}
}
}
This way when the SDK asks it's datasource to getTaggableObjects() the SDK will receive the objects from the Project's CoreData model that it can understand.
Question
Does the name of property in the protocol extension have to be different than the name of the property that is in the base class, or will doing the above work? It would be nice if I knew this is okay before I implement my design.
I can confirm that using the same name is not allowed.
I tried and it's yes.
protocol MyArray {
var count: Int {get}
}
extension Array: MyArray {
}
But you can't make different implementations for different protocols that have the same function or property.
Update
If protocol and base class have property with the same name but different type. You can make different implementations.
protocol MyArray {
var count: Float {get}
}
extension Array: MyArray {
var count: Float {
get {
return 0.0
}
}
}

A static field inherited from the base class or protocol - how?

I want to be able to have the classes which have a static property (field) which is either inherited from the base class or "mixed" from a protocol. And every class should have it's own implementation of that property. Is it possible? Preferably, it to be immutable.
class C1 {
static let stProperty = "my prorepty1"
}
class C2 {
static let stProperty = "my prorepty2"
}
It's possible, but it's really hard to make this useful in Swift. How do you plan to refer to this property? Let's start with a super-simple implementation:
protocol SomeProtocol {
static var prop: String { get }
}
class C1: SomeProtocol {
static let prop = "This is One"
}
Great. So now I want a function that uses this:
func useProp(x: SomeProtocol) -> String {
return x.prop
// 'SomeProtocol' does not have a member named 'prop'
}
That doesn't work. x is an instance, but I want the type.
// Accessing members of protocol type value 'SomeProtocol.Type' is unimplemented
func useProp(x: SomeProtocol.Type) -> String {
return x.prop
}
This is probably how it will work some day given the word "unimplemented." But it doesn't work today.
func useProp(x: SomeProtocol) -> String {
// Accessing members of protocol type value 'SomeProtocol.Type' is unimplemented
return x.dynamicType.prop
}
Same thing.
Today, you really have to hang this on the object itself and not use static or class:
protocol SomeProtocol {
var prop: String { get }
}
class C1: SomeProtocol {
let prop = "This is One"
}
func useProp(x: SomeProtocol) -> String {
return x.prop
}
That's not so terrible in many cases, since the value for the class is probably also the value for any given instance of the class. And it's really all we can do today.
Of course your problem might be that you don't have an instance yet and you need this information to build an instance. That's really hard today and you should probably rethink your design. You'll generally have to use some other pattern like a Builder. See Generic Types Collection for more.
Now you also said:
or "mixed" from a protocol
I wouldn't say "mixed" here. If you really mean this like a Ruby "mixin", there is no such thing in Swift today. Swift folks often refer to this feature as "default implementation," and it's not currently possible (though I do expect it to come eventually). The only thing you can do in the protocol is say that the implementor has to provide this method somehow. You can't provide it for them.
Sure you can do that with a protocol:
protocol SomeProtocol {
static var foo: String { get }
}
class One: SomeProtocol {
class var foo: String {
get {
return "This is One"
}
}
}
Btw I agree with Rob Napier below that this is a bit off a oddball feature. I do think there are probably use-cases for it, but I also think those can be better implemented with other language features
protocol P {
class var stProperty: String { get }
}
class C1 {
class var stProperty: String {
return = "my property1"
}
}
class C2 {
class var stProperty: String {
return = "my property2"
}
}
Usage:
C2.prop //"my property2"
If you try:
C2.prop = "new value" //"cannot assign to the result of this expression"

Static dictionary type variable declaration in swift?

I have been trying to declare a static dictionary within a "struct". However, I could not achieve this. It gives me "Type 'BagItem' does not conform to protocol 'Hashable'" .
And my code is here:
struct StaticBag {
static var bag: Dictionary<BagItem, Array<BagItem>> = Dictionary<BagItem, Array<BagItem>>()
// static func AddMainItem(item: BagItem)
// {
// self.bag[item] = Array<BagItem>()
// }
}
'BagItem' in the code is my another global class.
What is the right and best way to declare this variable ?
Thank you for your answers
Best regards
As it says, the issue is that your custom BagItem type doesn't conform to the Hashable protocol. Dictionary keys need to be hashable, since dictionaries use the hash values to look up entries quickly.
What does BagItem look like? Is there a unique property that is already hashable? If so, you can add Hashable conformance by adding a hashValue property and implementing the == operator:
class BagItem : Hashable {
var uniqueID: Int = 0
var hashValue: Int { return uniqueID.hashValue }
}
func ==(lhs: BagItem, rhs: BagItem) -> Bool {
return lhs.uniqueID == rhs.uniqueID
}

Swift - Typealias dictionary with value that implements a generic protocol

I want to typealias a dictionary of String keys and values of objects/structs that implements the Equatable protocol. So I wrote this line of code but it gave me error that I didn't know how to go on to fix.
typealias Storage = [String: Equatable]
I want to use the type [String: Equatable] as a variable in a protocol, e.g:
protocol StorageModel {
var storage: Storage { get set }
init(storage: Storage)
}
Error:
Protocol 'Equatable' can only be used as a generic constraint because
it has Self or associated type requirements
Can anyone suggest a solution?
Generally speaking, the protocol tag isn't required, protocol names are first-class type names and can be used directly:
typealias Storage = [String:Equatable]
In this case, what the error is telling you is that because Equatable includes func == (lhs:Self, rhs:Self) -> Bool and specifically lhs:Self, Equatable can't be used except as a constraint on a generic:
class Generic<T:Equatable> { ... }
Without more details about what you're trying to achieve and how you're trying to use StorageModel, the best I can come up with is:
protocol Matches {
typealias T
func matches(t:T) -> Bool
}
protocol StorageModel {
typealias T
var storage: [String:T] { get set }
init(storage:[String:T])
}
extension Int : Matches {
func matches(target:Int) -> Bool {
return self == target
}
}
class MyClass <T:Matches> {
var model = [String:T]()
}
Another possibility is to use a generic instead of a protocol:
class StorageModel <T:Equatable> {
var storage: [String:T]
init(storage:[String:T]) {
self.storage = storage
}
}
From there you'll need to do some research, dig into the Swift manual, do some googling and see what solves your problem.

Resources