40

I have update Xcode to 7.3 and now I have a warning to the function that I use to create random strings.

I have tried to change the for statement with for (i in 0 ..< len){...} however, the warning became an error.

How can I remove the warning?

static func randomStringWithLength (len : Int) -> NSString {
  let letters : NSString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  let randomString : NSMutableString = NSMutableString(capacity: len)

  for (var i=0; i < len; i += 1){ // warning
    let length = UInt32 (letters.length)
    let rand = arc4random_uniform(length)
    randomString.appendFormat("%C", letters.characterAtIndex(Int(rand)))
  }
  return randomString
}
JeremyP
  • 84,577
  • 15
  • 123
  • 161
SNos
  • 3,430
  • 5
  • 42
  • 92
  • possible duplicate of http://stackoverflow.com/questions/36173379/warning-c-style-for-statement-is-deprecated-and-will-be-removed-in-a-future-ve/36173489 – Bhavin Bhadani Jun 03 '16 at 08:46

4 Answers4

78

C-style for loop has been deprecated in Swift 3. You can continue using it for a while, but they will certainly disappear in the future.

You can rewrite your loop to Swift's style:

for i in 0..<len {
    let length = UInt32 (letters.length)
    let rand = arc4random_uniform(length)
    randomString.appendFormat("%C", letters.characterAtIndex(Int(rand)))
}

Since you don't use i at all in the loop's body, you can replace it with:

for _ in 0..<len {
    // do stuffs
}
Code Different
  • 90,614
  • 16
  • 144
  • 163
28

This BLOG saved my life.

INCREMENTING

for i in 0 ..< len {

}

DECREMENTING

for i in (0 ..< len).reverse() {

}

NON-SEQUENTIAL INDEXING

Using where

for i in (0 ..< len) where i % 2 == 0 {

}

Using striding to or through

for i in 0.stride(to: len, by: 2) {

}
Thomás Pereira
  • 9,589
  • 2
  • 31
  • 34
  • 4
    You should definitely avoid using a `where` clause in a situation where there is such a clear cut pattern. `0.stride(to: len, by: 2)` halves the number of jumps the processor has to do. – Alexander Mar 20 '18 at 01:13
  • when I try the last one I get `value of type 'Int' has no member 'stride'` – gman Sep 30 '21 at 19:32
13

in Swift 3 it's been an error

some general replacement was posted and just add

For Swift 3 and need to change the "index"

for var index in stride(from: 0, to: 10, by: 1){}
d0ye
  • 1,580
  • 1
  • 15
  • 26
  • it did worked 4 changing the index , seems not work for now :( 4 Changing the index maybe we should replace for loop with a while loop :( like ` var index = 0 while(index < len)` – d0ye Dec 01 '16 at 09:01
  • i try this solution but i keep give a warning that idex is never mutated so you should use let instead of var ,but you can't use let in mutate case – Amr Angry Feb 19 '17 at 12:08
  • 3
    @AmrAngry just `for index in stride(from: 0, to: 10, by: 1){}` :) – d0ye Feb 20 '17 at 03:20
6

I've had success with the following. You can use the for loop as follows - note that the for loop is inclusive so you may need to check that len is actually greater than 0:

for i in 0...len - 1 {
  let length = UInt32 (letters.length)
  let rand = arc4random_uniform(length)
  randomString.appendFormat("%C", letters.characterAtIndex(Int(rand)))
}

Or you can use this:

for i in 0 ..< len {
  let length = UInt32 (letters.length)
  let rand = arc4random_uniform(length)
  randomString.appendFormat("%C", letters.characterAtIndex(Int(rand)))
}

BTW it appears XCode 7.x does help you to get there but it's a two step process. First you have to change your increment operator from (say) i++ to i += 1 and then XCode warning helps you modify the loop.

JeremyP
  • 84,577
  • 15
  • 123
  • 161
bownie
  • 1,608
  • 15
  • 21