iOS Development

ios – Quantity button occasions are delayed till after block is completed

Spread the love

I’ve this iOS app in Swift that lets the person take an image, ship it to a server with an API and retrieve a response. The letters within the response are transformed into vibrations that the person can really feel utilizing Apple’s CHHapticEngine. I am additionally utilizing a github library referred to as JPSVolumeButtonHandler that listens for quantity button presses and does one thing when it detects one. I wish to cancel the vibrations when the person presses one of many quantity buttons if the response occurs to be too lengthy. The issue I am going through is that when the app is taking part in the vibrations no quantity button presses are being detected and so I can not cancel the vibrations. It’s only after the vibrations are finished that the occasions are registered.
I have never applied any cancelation but and have solely tried to get the amount buttons to be detected.
I can provide the extra features that creates the haptics as properly.

Code within the ImagePicker will get executed after a response is retrieved.

import SwiftUI
import JPSVolumeButtonHandler
import AVFoundation
import Corehaptics

struct ContentView: View {
@State non-public var hapticEngine: CHHapticEngine?
@State non-public var volumeHandler: JPSVolumeButtonHandler?
@State non-public var ohwow: String = ""
//different @State non-public variables

//different code

.sheet(isPresented: $isImagePickerPresented, onDismiss: {
}) {
    ImagePicker(picture: $capturedImage, onImageCapture: { imageData in
        if let imageData = imageData{
            uploadImage(imageData: imageData, serverURL: userInput) { lead to
                print("inside closure")

                change consequence {
                    case .success(let responseString):
                    ohwow = extractedText(responseString) ?? "unhealthy response"
                    ohwow = ohwow.lowercased()
                    vibro = true
                    viewModel.isConditionTrue = true
                    finishedstring = morseOhwow(ohwow) //interprets the string into morse code which is performed via vibrations.

                        case .failure(let error):
                            print("Error: (error)")

The Quantity Button Handler

Textual content()
//Different stuff

.onAppear {


    public func setupHaptics() {
        print("setupHaptics name")
            do {
                hapticEngine = strive CHHapticEngine()
                strive hapticEngine?.begin()
            } catch {
                print("Error initializing haptic engine: (error)")
    volumeHandler = JPSVolumeButtonHandler(up: {
        DispatchQueue.predominant.async{ //I do not assume that is crucial however I added it for testing
        if self.vibro{
            print("vibro is true")

downBlock: {
    //Similar because the upblock

Features for creating and taking part in haptics

public func createHapticPattern(_ doublenum: Double) -> CHHapticPattern {
    var occasions = [CHHapticEvent]()
    let event1 = CHHapticEvent(
        eventType: .hapticContinuous,
        parameters: [
            CHHapticEventParameter(parameterID: .hapticIntensity, value: 2.0),
            CHHapticEventParameter(parameterID: .hapticSharpness, value: 0.1)
        relativeTime: 0.0,
        length: doublenum

    let sample = strive! CHHapticPattern(occasions: occasions, parameters: [])
    return sample

public func playHapticPattern(_ doublenum: Double) {
    guard let hapticEngine = hapticEngine else { return }
    do {
        let sample = createHapticPattern(doublenum)
        let participant = strive hapticEngine.makePlayer(with: sample)
        strive participant.begin(atTime: CHHapticTimeImmediate)
    catch {
        print("Error taking part in haptic sample: (error)")
public func makevibration(_ coolstring: String){
    for i in 0...coolstring.depend - 1{

        if coolstring[i] == "."{
   Date(timeIntervalSinceNow: 0.6))
        else if coolstring[i] == "-"{
   Date(timeIntervalSinceNow: 1.2))
        else if coolstring[i] == "I"{ //that is for when a letter ends. Could be inefficient.
   Date(timeIntervalSinceNow: 0.9))
        else if coolstring[i] == " "{
   Date(timeIntervalSinceNow: 2.1))

I attempted making a boolean within the ImagePicker like within the code above in order that as an alternative of operating a perform inside imagepicker, it will get referred to as by a distinct supply when it detects a change within the boolean. This does not work. I attempted lots with and Dispatch.predominant.async to see if it may work as a result of CHHapticEngine must be run in the primary thread and I feel within the jps library supply file it additionally runs on the primary thread. So perhaps this can be a drawback to do with concurrency?

Could be an extended query however any assist could be appreciated!

Leave a Reply

Your email address will not be published. Required fields are marked *