Post not yet marked as solved
Click to stop watching this thread.
You have stopped watching this post. Click to start watching again.
Post marked as unsolved with 1 replies, 0 views
Replied In
Could string ranges obtained with a MLTokenizer be used outside of the enumerateTokens loop?
With is a minimal macOS SwiftUI app and ContentView.swift with the following code, I can reproduce the crash with specific string.
//
// ContentView.swift
// NLTokenizerTest
//
// Created by repoleved on 24/03/2022.
//
import SwiftUI
import NaturalLanguage
struct ContentView: View {
@FocusState private var textIsFocused
@State private var text = ""
@State private var transformed = ""
var body: some View {
Form {
Section(header: Text("Input")) {
TextEditor(text: $text)
.font(.body)
.multilineTextAlignment(.leading)
.disableAutocorrection(true)
.frame(minHeight: 100)
.onChange(of: text, perform: { _ in
transformed = scramble(text)
})
.focused($textIsFocused)
}
Section(header: Text("Scrambled")) {
TextEditor(text: $transformed)
.disabled(true)
.font(.body)
.multilineTextAlignment(.leading)
.frame(maxWidth: .infinity, minHeight: 100)
.allowsHitTesting(false)
}
}
.frame(minWidth: 400)
.padding()
.onAppear(perform: { textIsFocused = true })
}
func scramble(_ text: String) -> String {
var transformed = text
print("text: \"\(text)\"")
var wordRanges: [Range<String.Index>] = []
let tokenizer = NLTokenizer(unit: .word)
tokenizer.string = transformed
tokenizer.enumerateTokens(in: transformed.startIndex..<transformed.endIndex) { range, _ in
if transformed[range].count > 3 {
let subrange = transformed.index(range.lowerBound, offsetBy: 1)..<transformed.index(range.upperBound, offsetBy: -1)
wordRanges.append(subrange)
}
return true
}
wordRanges.reversed().forEach { range in
let substring = String(transformed[range])
print("substring: \"\(substring)\"")
transformed.replaceSubrange(range, with: substring.shuffled())
}
return transformed
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}