The "integer square root" of a non-negative integer \$ n \$ is defined as the largest integer not greater than \$ \sqrt{n} \$: $$ \operatorname{isqrt}(n) = \lfloor \sqrt{n} \rfloor = \max \{ k \in \Bbb N_0 \mid k^2 \le n \} $$ It is for example needed in prime factorization, as an upper bound for the possible factors.
A simple approach is to compute the floating point square root and truncate the result to an integer. In Swift that would be
func isqrt_simple(_ n: Int) -> Int {
    return Int(Double(n).squareRoot())
}
As observed in Computing the square root of a 64-bit integer, this can produce wrong results for large numbers, because an IEEE 64-bit floating point number with its 53 bit significand cannot represent large integers exactly. Here is an example:
let n = 9223371982334239233
let r = isqrt_simple(n)
print(r)           // 3037000491
print(r * r <= n)  // false
The correct result would be 3037000490, since $$ \sqrt{9223371982334239233} \approx 3037000490.9999996957524364127605120353 $$ (computed with PARI/GP).
The following implementation uses the ideas from DarthGizka's answer to the above mentioned question to implement a "correct" integer square root function in Swift 4:
func isqrt(_ n: Int) -> Int {
    precondition(n >= 0, "argument of isqrt() must be non-negative")
    var r = Int(Double(n).squareRoot()) // Initial approximation
    // Try to increase:
    while case let prod = r.multipliedReportingOverflow(by: r),
        !prod.overflow && prod.partialValue < n  {
            r += 1
    }
    // Decrease if necessary:
    while case let prod = r.multipliedReportingOverflow(by: r),
        prod.overflow || prod.partialValue > n  {
            r -= 1
    }
    return r
}
Example:
let n = 9223371982334239233
let r = isqrt(n)
print(r)                 // 3037000490
print(r * r <= n)        // true
print((r+1) * (r+1) > n) // true
Remarks:
- I have chosen 
Intas argument and result type even if the square root is defined only for non-negative integers. The reason is thatIntis the prevalent integer type in Swift and already used for quantities that can not be negative (e.g. thecountof an array, or theMemoryLayout<T>.sizeof a type). Intcan be a 32-bit or 64-bit quantity, therefore I cannot check against a constant for overflow (asr < UINT32_MAXin DarthGizka's C++ solution).multipliedReportingOverflow()is used instead to check if squaring a candidate causes an overflow.
The code worked correctly in all my tests. Here are some tests which all succeed
func testSqrt(_ n: Int) {
    let r = isqrt(n)
    if r * r > n {
        print("Too large:", n, r)
    } else if (r+1) * (r+1) <= n {
        print("Too small:", n, r)
    }
}
testSqrt(4503599761588224)
testSqrt(4503599895805955)
testSqrt(4503600030023688)
testSqrt(4503600164241423)
testSqrt(9223371982334241080)
testSqrt(9223371982334239233)
testSqrt(9223372024852248003)
testSqrt(9223372024852247041)
testSqrt(9223372030926249000)
testSqrt(9223372030926247424)
These tests fail if isqrt_simple() is used instead.
All feedback is welcome, in particular suggestions how to improve the performance.