Swift 4 - 'substring(to:)' is deprecated - Alternative To My Code [duplicate] - ios

This question already has answers here:
'substring(to:)' is deprecated: Please use String slicing subscript with a 'partial range upto' operator
(2 answers)
Closed 3 years ago.
My code was as below
var theReview = addReview.text
let len2 = addReview.text.utf16.count
if len2 > 3000 {
theReview = theReview?.substring(to: (theReview?.index((theReview?.startIndex)!, offsetBy: 3000))!)
}
My aim was to get the first 3000 characters of the text if it is longer than 3000 characters.
However, I get the warning below:
'substring(to:)' is deprecated: Please use String slicing subscript
with a 'partial range upto' operator
What can be an alternative to my code. I am not a very professional coder. So any help would be great.

Simply call prefix(_:) on theReview with the required length.
func prefix(_ maxLength: Int) -> Substring
Returns a subsequence, up to the specified maximum length, containing
the initial elements of the collection.
If the maximum length exceeds the number of elements in the
collection, the result contains all the elements in the collection
var theReview = addReview.text
theReview = String(theReview.prefix(3000))
Note: There is no need to check if the theReview's length exceeds 3000. It will be handled by prefix(_:) itself.

might this could help you
var theReview = addReview.text
theReview = String(theReview.prefix(3000))

Use String init with slice.
let index = theReview.index(theReview.startIndex, offsetBy: 3000)
theReview = String(theReview[theReview.startIndex..<index])
or prefix as mentioned in previous answers

Related

How can I check if a string already contains a character in Swift [duplicate]

This question already has answers here:
How do I check if a string contains another string in Swift?
(28 answers)
Closed 4 years ago.
I would like to check in my app, if there is already a - character in the textField.
How can I do this?
You can use contains() method
let myString = "test"
if myString.contains("e"){
let index = myString.index(of: "e")
myString.remove(at: index!)
}
p.s you can get myString from textField.text
You can simply:
var yourTextFieldString: String = textField.text
yourTextFieldString.contains("-")
It returns a Bool.

substring of the first 4 characters from a textField in Swift 4

I'm trying to create a substring of the first 4 characters entered in a textField in Swift 4 on my iOS app.
Since the change to Swift 4 I'm struggling with basic String parsing.
So based on Apple documentation I'm assuming I need to use the substring.index function and I understand the second parameter (offsetBy) is the number of characters to create a substring with. I'm just unsure how I tell Swift to start at the beginning of the string.
This is the code so far:
let postcode = textFieldPostcode.text
let newPostcode = postcode?.index(STARTATTHEBEGININGOFTHESTRING, offsetBy: 4)
I hope my explanation makes sense, happy to answer any questions on this.
Thanks,
In Swift 4 you can use
let string = "Hello World"
let first4 = string.prefix(4) // Hell
The type of the result is a new type Substring which behaves very similar to String. However if first4 is supposed to leave the current scope โ€“ for example as a return value of a function โ€“ it's recommended to create a String explicitly:
let first4 = String(string.prefix(4)) // Hell
See also SE 0163 String Revision 1
In Swift 4:
let postcode = textFieldPostcode.text!
let index = postcode.index(postcode.startIndex, offsetBy: 4)
let newPostCode = String(postcode[..<index])

Cannot assign value of type 'String' to type 'UILabel!' [duplicate]

This question already has answers here:
Cannot assign a value of type "String" to type "UILabel" in swift
(2 answers)
Closed 5 years ago.
I'm getting this error in XCode with Swift. I've tried a lot of other solutions I've seen on this site, but none seem to work.
#IBAction func generateClick(_ sender: Any) {
let int1 = Int(number1.text!)!
let int2 = Int(number2.text!)!
let random = arc4random_uniform(UInt32((int2 - int1) + int1))
numberText = "\(random)"
The goal is the pick a random number when they click the generate button. (Between the 2 numbers they specify, being number1 and number2)
I suppose numberText is you UILabel reference.
You want assign to it's text Attribute like this:
numberText.text = "\(random)"

Creating closed Range in Swift 3 not working

Can anyone tell me why the code below works in Swift 2, but somehow breaks in Swift 3?
let range: Range = 0...2
However it can simply be fixed by doing this
let range: Range = 0..<3
Anyone knows what is the reason behind this?
Operators ... and ..< used to produce the same type, Range, in Swift 2.x. Now they produce different types (migration guide):
Range
CountableRange
ClosedRange
CountableClosedRange
Changing the type in the first assignment to ClosedRange should fix the problem. Better yet, let Swift infer the type for you:
let range = 0...2

How to separate emojis entered (through default keyboard) on textfield

I entered a two emojis in textfield ๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ง๐Ÿ˜, here I'm getting total number of 5 characters length whereas 4 characters for first emoji and 1 character for second. Looks like apple has combined 4 emojis to form a one.
I'm looking for the swift code where I can separate each of emojis separately, suppose by taking the above example I should be getting 2 strings/character separately for each emoji.
Can any one help me to solve this, I've tried many things like regex separation or componentsSeparatedByString or characterSet. but unfortunately ended up with negative.
Thanks in advance.
Update for Swift 4 (Xcode 9)
As of Swift 4 (tested with Xcode 9 beta) a "Emoji ZWJ Sequence" is
treated as a single Character as mandated by the Unicode 9 standard:
let str = "๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ง๐Ÿ˜"
print(str.count) // 2
print(Array(str)) // ["๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ง", "๐Ÿ˜"]
Also String is a collection of its characters (again), so we can
call str.count to get the length, and Array(str) to get all
characters as an array.
(Old answer for Swift 3 and earlier)
This is only a partial answer which may help in this particular case.
"๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ง" is indeed a combination of four separate characters:
let str = "๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ง๐Ÿ˜" //
print(Array(str.characters))
// Output: ["๐Ÿ‘จโ€", "๐Ÿ‘จโ€", "๐Ÿ‘งโ€", "๐Ÿ‘ง", "๐Ÿ˜"]
which are glued together with U+200D (ZERO WIDTH JOINER):
for c in str.unicodeScalars {
print(String(c.value, radix: 16))
}
/* Output:
1f468
200d
1f468
200d
1f467
200d
1f467
1f60d
*/
Enumerating the string with the .ByComposedCharacterSequences
options combines these characters correctly:
var chars : [String] = []
str.enumerateSubstringsInRange(str.characters.indices, options: .ByComposedCharacterSequences) {
(substring, _, _, _) -> () in
chars.append(substring!)
}
print(chars)
// Output: ["๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ง", "๐Ÿ˜"]
But there are other cases where this does not work,
e.g. the "flags" which are a sequence of "Regional Indicator
characters" (compare Swift countElements() return incorrect value when count flag emoji). With
let str = "๐Ÿ‡ฉ๐Ÿ‡ช"
the result of the above loop is
["๐Ÿ‡ฉ", "๐Ÿ‡ช"]
which is not the desired result.
The full rules are defined in "3 Grapheme Cluster Boundaries"
in the "Standard Annex #29 UNICODE TEXT SEGMENTATION" in the
Unicode standard.
You can use this code example or this pod.
To use it in Swift, import the category into the YourProject_Bridging_Header
#import "NSString+EMOEmoji.h"
Then you can check the range for every emoji in your String:
let example: NSString = "๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ง๐Ÿ˜" // your string
let ranges: NSArray = example.emo_emojiRanges() // ranges of the emojis
for value in ranges {
let range:NSRange = (value as! NSValue).rangeValue
print(example.substringWithRange(range))
}
// Output: ["๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ง", "๐Ÿ˜"]
I created an small example project with the code above.
For further reading, this interesting article from Instagram.

Resources