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):
                    print("success")
                    ohwow = extractedText(responseString) ?? "unhealthy response"
                    ohwow = ohwow.lowercased()
                    print(ohwow.depend)
                    vibro = true
                                    
                    viewModel.isConditionTrue = true
                            
                    finishedstring = morseOhwow(ohwow) //interprets the string into morse code which is performed via vibrations.
                            print("response:"(ohwow)"")

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

The Quantity Button Handler

VStack{
Textual content()
//Different stuff
}

.onAppear {

    print("onappear")
                
    setupHaptics()

    //setupHaptics()
    /*
    public func setupHaptics() {
        print("setupHaptics name")
            do {
                hapticEngine = strive CHHapticEngine()
                strive hapticEngine?.begin()
            } catch {
                print("Error initializing haptic engine: (error)")
            }
        }
    */
                
    observeCondition()
               
    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")
        }

        else{
            isImagePickerPresented.toggle()
        }
                        
        print("DETECTED")
                       
        }
                    
    }, 
downBlock: {
    //Similar because the upblock
    }
                  
})
                
volumeHandler?.begin(true)
                
}

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
        )

    occasions.append(event1)
    let sample = strive! CHHapticPattern(occasions: occasions, parameters: [])
    return sample
}
    

public func playHapticPattern(_ doublenum: Double) {
    //print("playHapticPattern")
        
    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] == "."{
            playHapticPattern(0.3)
                    
            RunLoop.present.run(till: Date(timeIntervalSinceNow: 0.6))
                     
                
        }
        else if coolstring[i] == "-"{
            playHapticPattern(0.9)
                    
            RunLoop.present.run(till: Date(timeIntervalSinceNow: 1.2))
                    
        }
        else if coolstring[i] == "I"{ //that is for when a letter ends. Could be inefficient.
            RunLoop.present.run(till: Date(timeIntervalSinceNow: 0.9))
        }
        else if coolstring[i] == " "{
            RunLoop.present.run(till: 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 Dispatch.international().async 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 *