Post marked as unsolved
171
Views
Hello,
I have some code to broadcast a BLE ad in Objective-C that worked well in Mojave, but has broken since moving to Catalina. The problem seems to stem from providing a value for the dispatch queue to the CBPeripheralManager instance versus NULL:
Calling _peripheralManager startAdvertising within CBPeripheralManagerDelegate peripheralManagerDidUpdateState works:
_peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:NULL];
Calling _peripheralManager startAdvertising within CBPeripheralManagerDelegate peripheralManagerDidUpdateState does not work:
dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
_peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:q];
As I mentioned, both versions worked in Mojave, so something is different in Catalina that I'm not able to discern that causes the version where the dispatch queue is provided to not work.
Thanks,
Larry
Post marked as solved
199
Views
I just started with Swift a few days ago, so sorry if this question is kinda simple but I was not able to find a matching answer on Google for it.
I want to implement a number that is "slowly" running down on a change. I want this number always to reach it's goal within a second no matter if it runs from 1000 to 100 or 110 to 100. But as of now, the UI always just takes the first change and not the following changes (I see different print outputs with the proper values but the actual UI does not update).
This is how my model currently looks like:
import SwiftUI
class Player: Identifiable {
let id = UUID()
@Published var name: String
@Published var maximumLifePoints: Int
@Published var currentLifePoints: Int {
didSet {
currentProgress = 1.0 / Float(maximumLifePoints) * Float(currentLifePoints)
}
}
@Published var currentProgress: Float = 1
init(name: String, startLifePoints: Int) {
self.name = name
self.maximumLifePoints = startLifePoints
self.currentLifePoints = startLifePoints
}
func setCurrentLifePoints(lifePoints: Int) {
let difference = currentLifePoints - lifePoints
let differencePerStep = difference / 100
print("Diffrence: \(difference)")
print("Diffrence step: \(differencePerStep)")
let timer = Timer.scheduledTimer(withTimeInterval: 0.01, repeats: true) { timer in
self.currentLifePoints -= differencePerStep
print("Current life points: \(self.currentLifePoints)")
}
timer.fire()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.99) {
timer.invalidate()
self.currentLifePoints = lifePoints
print("Final life points: \(self.currentLifePoints)")
}
}
}
This is my control which displays the "life points":
import SwiftUI
struct LiveCounter: View {		
		@State var player: Player
		
		var body: some View {
				GeometryReader { g in
						VStack (alignment: .center, spacing: 25.0) {
								ZStack {
										Circle()
												.fill(Color.offColor)
												.frame(width: self.circleSize(g.size), height: self.circleSize(g.size), alignment: .center)
										
										ProgressBar(currentValue: self.$player.currentProgress)
												.frame(width: self.circleSize(g.size), height: self.circleSize(g.size), alignment: .center)
										
										VStack (spacing: -4) {
												Text(self.player.name)
														.font(.system(size: g.size.height > g.size.width ? g.size.width * 0.04 : g.size.height * 0.04))
														.fontWeight(.bold)
														.foregroundColor(Color.textDefaultColor)
												
												Text("\(self.player.currentLifePoints.formattedWithSeparator)")
														.font(.system(size: g.size.height > g.size.width ? g.size.width * 0.1 : g.size.height * 0.1))
														.fontWeight(.black)
														.foregroundColor(Color.textDefaultColor)
												
												//Spacing to have life points still in center
												Text(" ")
														.font(.system(size: g.size.height > g.size.width ? g.size.width * 0.04 : g.size.height * 0.04))
														.fontWeight(.bold)
										}
								}
						}
				}
		}
		
		private func circleSize(_ size: CGSize) -> CGFloat? {
				return size.height > size.width ? size.width * 0.5 : size.height * 0.5
		}
}
So what did I miss to let the UI update to each change? I think I also messed up the Text(self.player.name) because this one does also not update on a change from another View. But for that problem I still have a few ideas how I can fix it not like with the async update stuff..
Post marked as unsolved
167
Views
Hi,
I have pseudo code for a repeating task of work:
api_call("/status") {
	if response.statusCode == 418 {
		api_call("/rotate-credentials") { ... }
	}
	else {
		doSomeWork()
	}
	sleep(60)
	api_call("/status")
}
I want to make a call to /status roughly every 60 seconds, but if the response is a 418 then I want to complete a call to /rotate-credentials before continuing with the next status request.
There are other api calls going on as well, triggered by user interaction. These other api calls should wait until the /status call is completed in full (including if a credential rotation is triggered).
This implies a serial queue? But that won't wait for the completions to finish, so I should be looking at a dispatch group enter(), leave() and wait() right?
I can't find/understand from the docs where completion handlers go, in terms of execution, relative to dispatch queues. So where is the completion handler execution of the subsequent call to /rotate-credentials ?
If I wrap the status call in a dispatch group, is the rotate-credentials completion handler execution covered by this group? So no further tasks will begin until that task is complete?
The credentials are used for digest signing of http requests, hence why I want to pause other api calls until the rotate-credentials is complete.
thanks,