The '..<' operator can signify a Range or a CountableRange when the bounds are integers, so the compiler defaults to CountableRange when a range expression with integer bounds is in a statement that provides no context to suggest the expression should be regarded as Range.
let chunk = dataToSend?.subdata(in: sendDataIndex!..<(sendDataIndex! + amountToSend))
The 'subdata(in:)' method requires a Range argument, so the range expression with integer bounds provided as its argument will be inferred from the context to be Range and the statement will compile.
let subRange = sendDataIndex!..<(sendDataIndex! + amountToSend)
In contrast, without the context of the method call or any other hint in that statement, the range expression with integer bounds is ambiguous, so the compiler will default to regarding it as CountableRange, and then the following line will not compile because the 'in:' parameter is Range but subRange is CountableRange.
let chunk = dataToSend?.subdata(in: subRange)
If you had written:
let subRange: Range = sendDataIndex! ..< (sendDataIndex! + amountToSend)
then the explicit type annotation, Range, would have told the compiler to regard the range expression as Range instead of CountableRange, and then the line that didn't compile would have compiled.
Also, you can create a Range from a CountableRange with:
Range(someCountableRange)
Finally, consider using optional binding ('if let ...' and 'guard let ...') instead of force unwrapping a variable unless you are absolutely sure that the variable will never contain nil or you specifically do want a nil value to crash the program.