Initializers in native arrays in swift - ios

I am just getting started with swift and I know we have a default array initialiser in swift and the syntax goes like this:
let myArray = [Int](count:3 , repeatedValue:2)//int types [2,2,2]
But when I remove [Int] from the statement,it initialises the array with values (3,2).
let myArray = (count:3 , repeatedValue:2)//[3,2]
Can anyone explain this behaviour?

In the second example, you're getting a tuple, not an Array. If you don't want to specify [Int], you still need to specify Array, like this:
let myArray = Array(count: 3, repeatedValue: 2)
Learn more about tuples in the Swift book.

Related

Ambiguous use of 'mutableCopy()' Swift3

I tried to update Swift 3 and I got the following error :
Ambiguous use of 'mutableCopy()'
Before update to swift 3. It runs well.
Swift 2.3
NSUserDefaults.standardUserDefaults().objectForKey("listsavednews")?.mutableCopy() as! NSMutableArray
Swift 3.0
(UserDefaults.standard.object(forKey: "listsavednews")? as AnyObject).mutableCopy() as! NSMutableArray
I found that mutableCopy in Swift3 return Any that doesnt have method mutableCopy() so that it needs to cast to AnyObject.
Any helps thanks.
I dont know why I can't comment.
Thanks all, I'll be using :
UserDefaults.standard.mutableArrayValue(forKey: "listsavednews")
mutableCopy is an Objective-C method from NSObject. There's little reason to use it in Swift 3.
Since you are dealing with UserDefaults and mutableCopy, you must be dealing with either an array or dictionary. Or it could be a string.
The proper way to do this in Swift 3 is to use the proper UserDefaults method to get an array or dictionary. And assign the result to a var. That combination will give you a mutable array or mutable dictionary.
var someArray = UserDefaults.standard.array(forKey: "somekey")
or:
var someDictionary = UserDefaults.standard.dictionary(forKey: "somekey")
In the two above cases, you end up with an optional since there might not be any data for the given key. And you also get a non-specific array or dictionary which isn't ideal. It would be better to cast the result to the appropriate type.
Let's say you have an array of strings and you want an empty array if there is nothing currently in user defaults. You can then do:
var someArray = UserDefaults.standard.array(forKey: "somekey" as? [String]) ?? []
Adjust as necessary if the array contains something other than String.
If you actually have a dictionary, the code would be similar.
var someDictionary = UserDefaults.standard.dictionary(forKey: "somekey") as? [String:String] ?? [:]
If your original object is just a string, then you could do:
var someString = UserDefaults.standard.string(forKey: "somekey") ?? ""

Swift Array addObjects to NSMutableArray

I have a Swift Array and I want to add all the objects inside to NSMutableArray
let stringName: String = "Something"
let stringNameSeperated = Array(logoName)
let mutableStringName: NSMutableArray = NSMutableArray(array: stringNameSeperated)
How can I do that?
I'm not really sure what you wanted to archive, but if you just wanted a Swift.Character sequence array, here's a simpler way without even the Array() process: (Notice that the result was casted into String. If you want Character, you will have to modify the code a bit.)
let stringName: String = "Something"
let mutableStringName: NSMutableArray = NSMutableArray(array: map(stringName) { String($0) } )
And from my understanding, you no longer have to case between Swift Array and Objective-C Array, you can use them interchangeably. Also, you can pass a Swift Array to a parameter that expected to be NSArray without problem in Swift 1.x as well.

How can NSMutableArray add object using let in swift

I created a NSMutableArray in swift using let and
when I add addObject in the mutableArray then it will add it even though I
used the let to assign a constant. Can anyone explain how let works in swift? If it doesn't allow you to add value in later then how is the following
code working?
let arr : NSMutableArray = [1,2,3,4,5]
arr.addObject(6)
println(arr)
Classes are reference types, and NSMutableArray is a class.
Foundation's NSMutableArray is different from Swift's Array: the latter is a value type.
If you create a constant NSMutableArray:
let ns: NSMutableArray = ["a", "b"]
then this works:
ns.addObject("c")
but this doesn't:
ns = ["d", "e"] // nope!
because you can change the content of the reference but you can't change what is assigned to the constant.
On the other hand, with Swift's Array:
let sw: [String] = ["a", "b"]
the constant can't be changed because it's a value, not a reference.
sw.append("c") // nope!
Doc: Structures and Enumerations Are Value Types and Classes Are Reference Types
disclaimer: this answer only applies to NS type data structures, please see #Eric D's answer for the full picture
let when used with a class just means the variable cant be changed, eg, to another array. If you dont want the array to be editable, use a normal NSArray and not a mutable one
let arr : NSMutableArray = [1,2,3,4,5]
arr = [1,2,3,4,5] //error trying to assign to a let variable that has already been assigned
arr.addObject(6) //fine because we are not changing what is assigned to arr, but we are allowed to change the object that is assigned to arr itself
I think your understanding of what a constant variable is, is a bit too strict.

NSMutableArray cast to swift Array of custom type

I'd like to figure out how to specify or cast an NSMutableArray to a swift Array of a custom type. I currently have 2 files:
First file requires an NSMutableArray for its functionality (passed by reference, ability to remove particular objects with indices I don't know)
Second file uses a Swift array (better memory / throwaway array), with a custom type, which I declare using
let newArray: [CustomType]!
I need to pass the NSMutableArray in as a parameter to a function in the second file, which requires a [CustomType]. When simply calling it:
let newVC = UIViewController(array: mutableArray)
it keeps telling me 'CustomType' is not identical to 'AnyObject'. I've tried calling the function using mutableArray as [CustomType], which does not work either. How can I make the swift Array function accept my NSMutableArray?
This works for me:
var swiftArray = NSArray(array:mutableArray) as Array<CustomType>
swiftArray is then a Swift array of objects of CustomType. You can pass the array and iterate over it as you would expect.
What I needed was this:
let newVC = UIViewController(array: mutableArray as AnyObject as [CustomType])

How does one create a mutable copy of an immutable array in swift?

Now that Swift's Array's are truly immutable thanks to full value semantics, how can I create an mutable copy of an immutable array? Similar to Obj-C mutableCopy(). I can of course downcast the array to an NSArray and use mutableCopy() but don't want to use NSArray because it does not strictly typed.
I have a toolbar which has items from the storyboard. I want to remove an item from the toolbar and use toolbar.setItems. I wanted to do it without casting as a NSArray, because none of these functions take NSArrays, they take [AnyObject].
Obviously now when I call removeAtIndex() it does not work, which is correct. I just need a mutableCopy
Simply assigning to var does not work for me and give 'Immutable value of type [AnyObject]'
var toolbarItems = self.toolbar.items
toolbarItems.removeAtIndex(2) //Immutable value of type [AnyObject]
I am using Beta 3
The problem is that self.toolbar.items is an implicitly unwrapped optional (of type [AnyObject]!) and they are always immutable. When you assign to the variable toolbarItems without explicitly stating its type, it too becomes an implicitly unwrapped optional, and thus is immutable as well.
To fix this do either:
var toolbarItems:[AnyObject] = self.toolbar.items
toolbarItems.removeAtIndex(2)
Or:
var toolbarItems = self.toolbar.items as [AnyObject]
toolbarItems.removeAtIndex(2)
Update
As of Xcode 6 Beta 5, you can update collections that are stored in optional variables, so the original code now works:
var toolbarItems = self.toolbar.items
toolbarItems.removeAtIndex(2)
Arrays are value types (struct), so they are passed around by value and not by reference.
That said, if you create a variable of array type and assign it the immutable array, a copy of the immutable array is actually created and assigned to it - and of course that copy has no relationship with the original immutable array (besides having the same values at the time it is created).
let immutable = [1, 2, 3]
//immutable[0] = 1 // Fails, ok
var mutable = immutable
mutable[0] = 5
In your case, you are accessing an immutable array which is an NSArray of AnyObjects (see documentation). You can use it as an Array in swift, make a copy of it and modify as follows:
let immutable : NSArray = [ 1, 2, 3 ]
//immutable[0] = 1 // Fails, ok
var mutable : [AnyObject] = immutable
mutable.removeAtIndex(1) // mutable now is [1, 3]
mutable[0] = 7 // mutable now is [7, 3]
After you're done with your changes, you can assign to the items property
It is as simple as declaring a var with your array.
var items = toolbar.items
Now you can change items and then reassign to the toolbar.
toolbar.items = items
Note that you can cannot (as of Beta 3) alter the elements of an "immutable" array declared with let as well. Just the length of the array is was fixed, which is why you cannot remove items.
However, according to Apple's documentation of UIToolbar, the items array is already mutable.
SWIFT
var items: [AnyObject]!
Tested + works:
var mutable : [UIBarButtonItem] = []
for button in toolbar.items {
mutable += button as UIBarButtonItem
}
mutable.removeAtIndex(2)
toolbar.setItems(mutable, animated: true)
TO REMOVE AN OBJECT FROM PARTICULAR INDEX OF AN ARRAY.
let fullArray : NSArray = Userdefaults().value(forKey: "YOUR_ARRAY_STRING") as! NSArray
var mutableArray : [AnyObject] = fullArray as [AnyObject]
mutableArray.remove(at: INDEX_TO_REMOVE) //Eg: mutableArray.remove(at: 0)
mutableArray.append(ARRAY_TO_APPEND)
In Beta3 constant arrays are completely immutable while variable arrays are entirely mutable. So just change let array:to var array: and then verify your code

Resources