Where best to declare a counter variable to track number of guesses?
As a general rule, you want to use the narrowest possible scope for all variables. We do this so that:


The declaration is close to where we use it, making it easier to reason about why the variable exists.
It minimizes the chance of unintended consequences where the variable is accidentally updated somewhere else.


In this case, it’s so trivial that it doesn’t matter that much, but as your code increases in complexity, this becomes increasingly important. This practice of restricting variables to the narrowest possible scope becomes a central precept in writing safe code: It’s much harder to have unintended consequences or accidentally state changes if variables have narrow scopes.

So, if numberOfGuesses represents how many guesses it took you to guess a  particular random number, then it should be inside the keepPlaying loop. But if you also wanted to keep track of the total number of guesses for all the times you played, then that (probably best kept track in another variable, perhaps, totalNumberOfGuesses) would be outside this outer loop.

By the way, while you’re at it, the continueGuessing and randomNumber, belong inside this keepPlaying loop, too.

By the way,


If you define variables only used within the scope of a loop, it saves you from having to reset that variable for the next iteration. For example, right now you are resetting continueGuessing back to true as the last step in the keepPlaying loop; if you define continueGuessing within the loop, then you wouldn’t have to reset it again at the end of the loop, resulting in simpler code.


In your code, you make reference to “globals”. As a general rule, we try to minimize the use of globals because as as apps scale, globals can make it hard to test, harder to reason about state changes, etc. See Why is Global State so Evil or google “globals are evil”.



Some unrelated observations:


Rather than 

let randomNumber = Int(arc4random_uniform(101))


I’d instead recommend:

let randomNumber = Int.random(in: 0...100)


It is equivalent, but arguably is more intuitive. (This would be especially true if you wanted to go from 1 to 100 instead, the arc4random_uniform code would become even less intuitive, whereas random(in: 1...100) is perfectly natural and trivial to reason about.
When you have a loop that you are always going to do at least once, rather than a while loop, we’d often consider repeat-while. E.g. rather than

var shouldPlayAgain = true
while shouldPlayAgain {
    ...

    shouldPlayAgain = ...
}


You might do:

var shouldPlayAgain: Bool
repeat {
    ...

    shouldPlayAgain = ...
} while shouldPlayAgain


Technically the latter is a tad more efficient, but the main benefit is that it makes your intent (to check at the end) absolutely clear.
At the end, you appear to want to be printing number of times the game was played, but you’re printing the number of guesses.

E.g. if you played twice, the first time requiring 3 guesses and the second time requiring 4 guesses, do you want to say “you played 2 times” or do you want to say “you guessed a total of 7 times”?