I’ve a query associated to correctly managing intensive duties, like connecting to a server for an iOS consumer app. I’ve a server operating in python. Each consumer and server code are beneath.
With the present code, I recieve the next warning:
Thread Efficiency Checker: Thread operating at Person-interactive quality-of-service class ready on a thread with out a QoS class specified (base precedence 33). Examine methods to keep away from precedence inversions
PID: 31921, TID: 17707895
Backtrace
=================================================================
3 CFNetwork 0x000000019baeca08 estimatedPropertyListSize + 37652
4 CFNetwork 0x000000019b9573a8 cfnTranslateCFError + 2688
5 libdispatch.dylib 0x00000001019e67bc _dispatch_client_callout + 20
6 libdispatch.dylib 0x00000001019e834c _dispatch_once_callout + 140
7 CFNetwork 0x000000019b95737c cfnTranslateCFError + 2644
8 CFNetwork 0x000000019baec8c8 estimatedPropertyListSize + 37332
9 libdispatch.dylib 0x00000001019e67bc _dispatch_client_callout + 20
10 libdispatch.dylib 0x00000001019e834c _dispatch_once_callout + 140
11 CFNetwork 0x000000019baec790 estimatedPropertyListSize + 37020
12 CFNetwork 0x000000019baec81c estimatedPropertyListSize + 37160
13 libdispatch.dylib 0x00000001019e67bc _dispatch_client_callout + 20
14 libdispatch.dylib 0x00000001019e834c _dispatch_once_callout + 140
15 CFNetwork 0x000000019baec804 estimatedPropertyListSize + 37136
16 CFNetwork 0x000000019b9ac498 _CFStreamErrorFromCFError + 248272
17 CoreFoundation 0x000000019a7bd568 3A5F992A-D1CD-312E-BD2E-F7C66343A417 + 406888
18 LFA QUANTIFICATION 0x000000010090e490 $s18LFA_QUANTIFICATION6ClientC7connectyyF + 1648
19 LFA QUANTIFICATION 0x0000000100914294 $s18LFA_QUANTIFICATION4HomeC12logOutButtonyySo8UIButtonCF + 132
20 LFA QUANTIFICATION 0x000000010091440c $s18LFA_QUANTIFICATION4HomeC12logOutButtonyySo8UIButtonCFTo + 52
21 UIKitCore 0x000000019d807f78 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 14884728
22 UIKitCore 0x000000019d19c698 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 8152728
23 UIKitCore 0x000000019d19ca10 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 8153616
24 UIKitCore 0x000000019d199f0c 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 8142604
25 UIKitCore 0x000000019d19ba78 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 8149624
26 UIKitCore 0x000000019cbd74c0 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 2102464
27 UIKitCore 0x000000019cbd6e64 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 2100836
28 UIKitCore 0x000000019cbd60e4 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 2097380
29 UIKitCore 0x000000019cb98970 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 1845616
30 UIKitCore 0x000000019cb97010 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 1839120
31 UIKitCore 0x000000019cb95a1c 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 1833500
32 UIKitCore 0x000000019ca80d78 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 699768
33 UIKitCore 0x000000019ca80468 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 697448
34 UIKitCore 0x000000019ca80524 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 697636
35 CoreFoundation 0x000000019a79162c 3A5F992A-D1CD-312E-BD2E-F7C66343A417 + 226860
36 CoreFoundation 0x000000019a7908a8 3A5F992A-D1CD-312E-BD2E-F7C66343A417 + 223400
37 CoreFoundation 0x000000019a78f058 3A5F992A-D1CD-312E-BD2E-F7C66343A417 + 217176
38 CoreFoundation 0x000000019a78dd88 3A5F992A-D1CD-312E-BD2E-F7C66343A417 + 212360
39 CoreFoundation 0x000000019a78d968 CFRunLoopRunSpecific + 608
40 GraphicsServices 0x00000001dea834e0 GSEventRunModal + 164
41 UIKitCore 0x000000019cc00edc 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 2272988
42 UIKitCore 0x000000019cc00518 UIApplicationMain + 340
43 UIKitCore 0x000000019ce39734 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 4601652
44 LFA QUANTIFICATION 0x000000010090ca10 $sSo21UIApplicationDelegateP5UIKitE4mainyyFZ + 120
45 LFA QUANTIFICATION 0x000000010090c988 $s18LFA_QUANTIFICATION11AppDelegateC5$mainyyFZ + 44
46 LFA QUANTIFICATION 0x000000010090ca8c predominant + 28
47 dyld 0x00000001bdcaed84 7BE2B757-3B3D-3E91-8CB7-74F3887660C7 + 23940
I did fairly a little bit of studying into it and experimenting, and I attempted to unravel it with utilizing DispathQueues to run within the background across the following code that calls the consumer class (from one other view controller):
@IBAction func logOutButton(_ sender: UIButton) {
DispatchQueue.international(qos: .background).async {
self.clientSession.join()
self.clientSession.ship(message: "IMAGE")
self.clientSession.ship(message: "Leaving")
self.clientSession.ship(message: "!")
}
}
Utilizing the .async flag, I used to be capable of make the warnings go away, however then the consumer was unable to recieve enter from my server (not less than, I used to be unable to print the message that was recieved). I test the server-side, and the server was each receiving and sending information again to the iOS consumer as ordinary. Typically talking, operating with async all the time made the warning to away however the consumer appeared unable to reply accurately to the server (i.e appeared to hold/not recieve server messages)
My predominant query is that this: how can I make these warnings go away with out affecting the consumer’s capability to recieve messages from the server? It does not seem to be the warnings mess with the app’s performance, however I want to know why these points come up and what’s the beneficial repair? My hunch is that I’m not utilizing DispatchQueues accurately or I’m not accurately scheduling the RunLoops, however that will not be the case.
Any steering in any approach can be useful.
Present Code:
//
// Consumer.swift
// LFA QUANTIFICATION
import UIKit
class Consumer: NSObject {
var inputStream: InputStream!
var outputStream: OutputStream!
weak var delegate: ChatRoomDelegate?
var username = ""
let maxBufferLength = 4096
func join() {
var readStream: Unmanaged<CFReadStream>?
var writeStream: Unmanaged<CFWriteStream>?
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, ("ADDR" as CFString), PORT, &readStream, &writeStream) // placeholder for ADDR and PORT, crammed in accurately when operating
inputStream = readStream!.takeRetainedValue()
outputStream = writeStream!.takeRetainedValue()
inputStream.delegate = self
outputStream.delegate = self
inputStream.schedule(in: .present, forMode: .widespread)
outputStream.schedule(in: .present, forMode: .widespread)
inputStream.open()
outputStream.open()
}
func byteArray<T>(from worth: T) -> [UInt8] the place T: FixedWidthInteger {
withUnsafeBytes(of: worth.bigEndian, Array.init)
}
func ship(message: String) {
let lengthStr : Int32 = Int32(message.depend)
let bytes : [UInt8] = byteArray(from: lengthStr)
outputStream.write(bytes, maxLength: bytes.depend) // ship size of the message
// ship the message
if let _ = message.information(utilizing: .ascii) {
outputStream.write(message, maxLength: Int(lengthStr))
}
}
}
extension Consumer: StreamDelegate {
func stream(_ aStream: Stream, deal with eventCode: Stream.Occasion) {
change eventCode {
case .openCompleted:
print("Stream Opened")
case .hasBytesAvailable:
print("right here")
if aStream == inputStream {
recieveData()
}
case .errorOccurred:
print("Error")
case .endEncountered:
print("END")
default:
break
}
}
func recieveData() {
var buffer = [UInt8](repeating: 0, depend: 1024)
let bytesRead = inputStream.learn(&buffer, maxLength: buffer.depend)
if bytesRead > 0 {
let recievedData = Knowledge(buffer.prefix(bytesRead))
guard let recievedString = String(information: recievedData, encoding: .utf8) else { return }
self.delegate?.recieved(message: recievedString)
}
}
}
protocol ChatRoomDelegate: AnyObject {
func recieved(message: String)
}
// Server.py
import threading
import socket
UNKNOWN_BUFFER_LENGTH = 1024
PORT = 5050
SERVER = "localhost"
ADDR = (SERVER, PORT)
FORMAT = "utf-8"
DISCONNECT_MESSAGE = "!"
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)
purchasers = set()
# Record of all present consumer connnections
clients_lock = threading.Lock()
def receive_message(conn):
# Obtain 4 bytes from the socket
information = conn.recv(4)
# Convert the acquired bytes to an integer utilizing big-endian byte order
received_integer = int.from_bytes(information, byteorder="massive")
msg = conn.recv(received_integer).decode(FORMAT)
return msg
def process_image(conn, addr):
print("Right here")
message = f"[{addr}] Recieved Incoming Message"
conn.sendall(message.encode(FORMAT))
print("Despatched message")
def handle_client(conn, addr):
print(f"[NEW CONNECTION] {addr} Linked")
strive:
linked = True
whereas linked:
msg = receive_message(conn)
if msg == "IMAGE":
process_image(conn, addr)
if not msg:
break
if msg == DISCONNECT_MESSAGE:
linked = False
print(f"[{addr}] {msg}")
lastly:
with clients_lock:
purchasers.take away(conn)
conn.shut()
def begin():
print('[SERVER STARTED]')
server.pay attention()
whereas True:
conn, addr = server.settle for()
with clients_lock:
purchasers.add(conn)
print(f'[CONNENCTED CLIENTS] {len(purchasers)}')
thread = threading.Thread(goal=handle_client, args=(conn, addr))
thread.begin()
begin()
View Controller that Calls the Consumer class, with the code snippet mentioned above (the place I attempted to repair with async)
//
// Dwelling.swift
// LFA QUANTIFICATION
import UIKit
class Dwelling: UIViewController {
let clientSession = Consumer()
@IBOutlet weak var cameraPhotoButton: UIButton!
@IBOutlet weak var homeText: UILabel!
var consumer: String!
override func viewDidLoad() {
tremendous.viewDidLoad()
clientSession.delegate = self
homeText.textual content = "Hi there " + consumer + "! How are you feeling at the moment?"
homeText.numberOfLines = 5
// Button Look properties
cameraPhotoButton.titleLabel!.textAlignment = .heart
cameraPhotoButton.titleLabel!.numberOfLines = 0
}
override func viewWillAppear(_ animated: Bool) {
tremendous.viewWillAppear(animated)
}
@IBAction func capturePhoto(_ sender: UIButton) {
guard let vc = storyboard?.instantiateViewController(withIdentifier: "cam") as? Digicam else {
return
}
vc.modalPresentationStyle = .fullScreen
current(vc, animated: true, completion: nil)
}
@IBAction func logOutButton(_ sender: UIButton) {
self.clientSession.join()
self.clientSession.ship(message: "IMAGE")
self.clientSession.ship(message: "Leaving")
self.clientSession.ship(message: "!")
}
//clientSession.ship(message: "hi there")
//clientSession.ship(message: "!")
}
extension Dwelling: ChatRoomDelegate {
func recieved(message: String) {
print("Chatroom: ", message)
}
}