My app is in its final stage and I am doing some "last minute" testing. Everything else works like it's supposed to but one problem I noticed was when I attempt to convert a string of 660 characters to binary the UI completely freezes up until the entire conversion is complete, due to the heavy encoding activity.
I tried to implement Dispatch
One other thing is, it's only doing that for Binary Encoding. Every other encoding method handles 660 characters just fine.
I just want to know how I can eliminate the freezing UI (until the operation is complete) more efficiently. I have posted the full operation below (I also implemented a function for when the string is over 100 characters):
I tried to implement Dispatch
Code Block Dispatch.main.async { /* Code */ }
in my main encoding function meanwhile implementing Code Block Dispatch.gloabl(qos: .default).async { /* Main encoding sequence code */ }
(where "main encoding sequence code" is the encoding algorithm) but I am still getting the freezes. Then I tried to do THAT but instead of encoding the whole string, I split the string up. Basically, when the encoding algorithm is called, the string will be encoded every 50 characters.One other thing is, it's only doing that for Binary Encoding. Every other encoding method handles 660 characters just fine.
I just want to know how I can eliminate the freezing UI (until the operation is complete) more efficiently. I have posted the full operation below (I also implemented a function for when the string is over 100 characters):
Code Block import UIKit import Foundation class ViewController: UIViewController { // MARK:- Outlet init @IBOutlet weak var sourceString: UITextField! @IBOutlet weak var resultOutput: UITextView! @IBOutlet weak var encode: UIButton! override func viewDidLoad() { super.viewDidLoad() } // MARK:- The main encoding function @IBAction func btnEncode(_ sender: Any) { if sourceString.text!.count > 100 { displayErrorMessage(title: "Long String Alert", message: "This is a pretty long string, this may take a bit to convert to binary, please hold...(String length = " + String(source.count), buttonTitles: "Okay"); encodeBinaryWhenCharOverlimit(input: source) } DispatchQueue.main.async { // Run UI Updates self.encodeStringBinary(string: source); return } } // MARK:- Add-In functions and methods private func toBinaryStringArray(array:[UInt8]) -> [String] { DispatchQueue.global(qos: .default).sync { var result:[String] = [] for e in array { let bin = byteToBinaryString(byte: e) result.append(bin) } return result; } } private func byteToBinaryString(byte:UInt8) -> String { DispatchQueue.global(qos: .default).sync { var result = String(byte, radix: 2) while result.count < 8 { result = "0" + result } return result; } } // MARK:- Extensible extra functions and methods // This function is called when the input string is over 100 characters private func encodeBinaryWhenCharOverlimit(input: String) -> Void { DispatchQueue.main.async { var bytes:[UInt8] = [] for char in input.utf8 { bytes += [char] } // Output the result for n in self.toBinaryStringArray(array: bytes) { self.resultOutput.text.append(n.inserting(separator: " ", every: 50)) }; sleep(1) } } // MARK:- Binary Encoding algorithm private func encodeStringBinary(string: String) -> Void { // var byte = string.utf8.count var bytes:[UInt8] = [] for char in string.utf8 { bytes += [char] } // Output the result for x in self.toBinaryStringArray(array: bytes) { self.resultOutput.text.append(x) } } } // MARK:- Extensions extension Collection { func distance(to index: Index) -> Int { distance(from: startIndex, to: index) } func subSequences(limitedTo maxLength: Int) -> [SubSequence] { precondition(maxLength > 0, "groups must be greater than zero") return .init(sequence(state: startIndex) { start in guard start < self.endIndex else { return nil } let end = self.index(start, offsetBy: maxLength, limitedBy: self.endIndex) ?? self.endIndex defer { start = end } return self[start..<end] }) } var pairs: [SubSequence] { subSequences(limitedTo: 2) } } extension StringProtocol where Self: RangeReplaceableCollection { mutating func insert<S: StringProtocol>(separator: S, every n: Int) { for index in indices.dropFirst().reversed() where distance(to: index).isMultiple(of: n) { insert(contentsOf: separator, at: index) } } func inserting<S: StringProtocol>(separator: S, every n: Int) -> Self { var string = self string.insert(separator: separator, every: n) return string } }
Simply and frankly speaking, your code is full of inefficient operations and mis-usages of DispatchQueue.
On my machine, a little bit more efficient code takes 7 msec to convert 660 ASCII characters.
You may not want to use DispatchQueue for this short period of freezing.
DispatchQueue is not an accelerator. If it is wrongly used, it does not help improving responses of your app.
On my machine, a little bit more efficient code takes 7 msec to convert 660 ASCII characters.
You may not want to use DispatchQueue for this short period of freezing.
Code Block @IBAction func btnEncode(_ sender: Any) { let source = sourceString.text ?? "" let start = Date() resultOutput.text = source.utf8.lazy.map {self.byteToBinaryString(byte: $0)} .joined() let end = Date() print(end.timeIntervalSince(start)) } private func byteToBinaryString(byte:UInt8) -> String { var result = String(byte, radix: 2) if result.count < 8 { result += String(repeating: "0", count: 8 - result.count) } return result; }
DispatchQueue is not an accelerator. If it is wrongly used, it does not help improving responses of your app.