'(NSObject, AnyObject)' is not convertible to 'String' - string

How do I convert an object of type (NSObject, AnyObject) to the type String?
At the end of the first line of the method below, as String causes the compiler error:
'(NSObject, AnyObject)' is not convertible to 'String'
Casting street to NSString instead of String compiles, but I'm casting street to String because I want to compare it to placemark.name, which has the type String!, not NSString.
I know name and street are optionals, but I'm assuming they're not nil for now because all the places returned from MKLocalSearch seem to have non-nil names and streets.
func formatPlacemark(placemark: CLPlacemark) -> (String, String) {
let street = placemark.addressDictionary["Street"] as String
if placemark.name == street {
// Do something
}
}

A String is not an object, so you do need to cast it to an NSString. I would recommend the following syntax to cast it and unwrap it at the same time. Don't worry about comparing it to a variable of type String! since they are compatible. This will work:
func formatPlacemark(placemark: CLPlacemark) -> (String, String) {
if let street = placemark.addressDictionary["Street"] as? NSString {
if placemark.name == street {
// Do something
}
}
}
This has the added benefits that if "Street" is not a valid key in your dictionary or if the object type is something other than NSString, this will not crash. It just won't enter the block.
If you really want street to be a String you could do this:
if let street:String = placemark.addressDictionary["Street"] as? NSString
but it doesn't buy you anything in this case.

The return type from looking up via subscript for a swift dictionary has to be an optional since there may be no value for the given key.
Therefor you must do:
as String?

I think it may have to do with addressDictionary being an NSDictionary.
If you convert addressDictionary to a Swift dictionary, it should work.
let street = (placemark.addressDictionary as Dictionary<String, String>)["String"]

Related

String.equals(StringBuilder) and StringBuilder.equals(String) Confusion

So I am given this piece of code and asked the question: What will be the result of compiling and executing Test class.
package com.foo.bar;
public class Test {
public static void main(String[] args) {
String str = "java";
StringBuilder sb = new StringBuilder("java");
System.out.println(str.equals(sb) + ":" + sb.equals(str));
}
}
The result according to them and the program when run through Eclipse is
false:false
I do not understand why it gives the above output. I thought String class overrides .equals so that it converts the values into strings and compares them. i.e. :
Object b, Object c ->
b.equals(c) ->
b.toString.equals(c.toString()) //b is a String
It is running the String.equals(). If you have str -> "java" and sb -> "java" which both override toString.
str.equals(sb) -> str.toString().equals(b.toString) -> true
No, String.equals does not convert the other argument to a String then compare the characters.
Compares this string to the specified object. The result is true if and only if the argument is not null and is a String object that represents the same sequence of characters as this object.
If the other object is not a String, e.g. a StringBuilder, then it will always return false. It will not convert the object to a String.
Like any well-formed equals method, it will test if the given object is the same class (ensuring it's not null first), and if it is, cast it to a String, but it won't call toString or otherwise convert the given object to a String.

(Swift 4.x+) What are the rules for naming parameters in structs’ initializers?

I have been doing an intense - yet basic apparently - study on structs in these last days and one of the things I cannot understand is why one would ever name parameters in an initializer differently from their original name.
I know that is possible, that it is allowed but, in practice, I have always seen shadowing instead.
For example:
struct Person {
var name: String
var age: Int
init(firstName: String, ancientness: Int) {
self.name = firstName
self.age = ancientness
}
}
Apart from the absurd fun one would have in inventing idiotic names, is there a truly practical reason why one would ever do such a thing?
Thank you
The short answer is no. The long answer is when creating a custom structure you don't even have to provide a custom initializer. The struct will provide it for you. Not related to your question but you should always declare your properties as constants. If you need a different value create a new structure with the values updated from the old instance. Just create a "plain" structure:
struct Person {
let name: String
let age: Int
}
This will provide a the default initializer with the following signature:
Person.init(name: String, age: Int)
If you were gonna provide yourself the same initializer for that structure it would be written as:
init(name: String, age: Int) {
self.name = name
self.age = age
}
the final thoughts
There is no reason to do such thing. You should keep your initializers names matching the name of the properties that they will be assigned to. The only "advantage" of choosing a different name is not having to explicitly call self inside the initializer.
In your example it would suffice
init(firstName: String, ancientness: Int) {
name = firstName
age = ancientness
}
but not on mine
init(name: String, age: Int) {
name = name // Cannot assign to value: 'name' is a 'let' constant
age = age // Cannot assign to value: 'name' is a 'let' constant
}
A Truly practical reason?
The only one I can see is dropping the self which can already be done 99% of the time already when coding in Swift. I actually like a lot to use the shadowing whenever it is possible in all of my answers. You can see it at this post Swift Array instance method drop(at: Int) where a local var indexshadowing the collection method index<T: Comparable>(_ T, offsetBy: T, limitedBy: T).
Or at this post Swift: second occurrence with indexOf a classic shadowing example
var startIndex = self.startIndex
Where you can refer to startIndex local method variable or the collection's instance property adding the self prefix self.startIndex.

Swift when string is null gives fatal error

I have some string codes but when my strings values null gives my app fatal error my codes here which changes i need to do ?
let pCodeTextFieldStr:NSString = pCodeTextField.text!
let pNameTextFieldStr:NSString = pNameTextField!.text!
let pQuantityTextFieldStr:NSString = pQuantityTextField.text!
let commingReadyIDs:NSString = prefs.valueForKey("addClientID") as! String!
let commingCurrs:NSString = prefs.valueForKey("addClientCurrency") as! String!
let commingtype:NSString = prefs.valueForKey("addProductType") as! String!
let productnameclean:NSString = prefs.valueForKey("addProductName") as! String!
The exclamation mark ! tells the compiler "if this item is nil then please crash". So the first step would be not to do that. The second step would be to figure out what you want to do if something is nil. You usually handle this using if let ... or using the nil-coalescing operator, ??.
They aren't "opinion"s they're how it is.
let commingCurrs:NSString states that commingCurrs CAN NEVER be nil.
Likewise, the fragment prefs.valueForKey("addClientID") as! String! states that prefs.valueForKey("addClientID") CAN NEVER return nil.
Since your data obviously CAN be nil, you're going to have to resolve the discrepancy.
You've been given 3 options, the only possible other option is to declare your variables as optional instead of required:
let commingReadyIDs:String? = prefs.valueForKey("addClientID") as? String
But that's just kicking the can down the road. Sooner or later you're going to have to deal with the fact that these values WILL BE NIL at some point.
Just a note, ANY time you're posed with the option of putting ! in a swift program you need to think long and carefully about is it really the right thing to do? Can this truly NEVER be nil? ! is the most evil, insidious, character in the swift language.
Since there's a possibility that these string values do not exist, you should not force unwrap them. An optional represents a variable that may have a value or it may have nil. Swift encourages you as a developer to acknowledge this and unwrap cases where a value may return nil. By using !, you are telling the compiler, I know there's a value here, in which in your case, there was not and an exception was thrown.
In the example below, if a string exists for the key, it will enter the scope of the block and you can access the string with the constant variable, commingReadyIDs. If not, the block will not be entered and no exception will occur.
I would encourage you to read more about optionals in Swift documentation since you will frequently encounter them and they encourage developers to avoid these null pointer exceptions.
if let commingReadyIDs = prefs.valueForKey("addClientID") as? String{
//do whatever
}
If you don't know when value exists of a variable or when not then you should use Optional Chaining, you can try below code
// all defined variables (like pCodeTextField) can have value or can be nil so don't use forcefully unwrapped optional value without cheking nil
let pCodeTextFieldStr:NSString? = pCodeTextField?.text
let pNameTextFieldStr:NSString? = pNameTextField?.text
let pQuantityTextFieldStr:NSString? = pQuantityTextField?.text
let commingReadyIDs : NSString? = prefs?.valueForKey("addClientID") as? String
let commingCurrs : NSString? = prefs?.valueForKey("addClientCurrency") as? String
let commingtype : NSString? = prefs?.valueForKey("addProductType") as? String
let productnameclean : NSString? = prefs?.valueForKey("addProductName") as? String

Get [String] from NSUserDefaults.standardUserDefaults().dictionaryRepresentation().keys

NSUserDefaults.standardUserDefaults().dictionaryRepresentation().keys returns [NSObject] but I need (and would expect) [String]. Is it just some coffee I'm missing?
dictionaryRepresentation() returns NSDictionary that does not support generic types. You can convert to Swift dictionary:
let dictionary = NSUserDefaults.standardUserDefaults().dictionaryRepresentation() as [String : AnyObject]
let keys = dictionary.keys
That actually returns a LazyBidirectionalCollection<MapCollectionView<Dictionary<Key, Value>, Key>>. You can add .array to get an array instance back, then use map to cast the values to String:
let keys = NSUserDefaults.standardUserDefaults().dictionaryRepresentation().keys.array.map { $0 as String }
println(keys)
// [NSLanguages, NSInterfaceStyle, AppleLanguages]

How to use String in Alloy?

How to use String in Alloy?
What kind of function or operators for String are supported in Alloy?
I searched questions here and find String is a keyword in Alloy.
But I cannot find any reference about how to use String in Alloy.
Could you give one? If not, is possible to give a brief about String in Alloy?
You can actually use strings in Alloy, but only as literals to specify constant values (i.e., no string operations are supported, and Alloy does not implement a string solver). That said, the main use of strings is Alloy is to assign constant string literals to some fields for the sole purpose of making the generated instances more readable when visualized. Here is a simple example
sig Person {
name: String,
email: String
}
one sig P1 extends Person {} {
name = "Joe"
email = "joe#email.com"
}
run {
some p: Person | p.name != "Joe"
}

Resources