TEAM LICENSES: Save money and learn new skills through a Hacking with Swift+ team license >>

Hacking with watchOS: SwiftUI Edition - Project 10 iMove - build error: Failed to create plugin

Forums > Books

I've just added the 4 method stubs needed to conform to the delegate protocols. When I try to build the project the following message is displayed:

Failed to create plugin
placeholder for /Users/jake/
Library/Developer/Xcode/DerivedData/...
**Details**   **OK**

When I click the Details button:

Details

Failed to create plugin placeholder for /Users/jake/Library/Developer/Xcode/DerivedData/iMove-djetllsyrqfntrbjsfbfkwzpdled/Build/Products/Debug-watchsimulator/iMove WatchKit App.app/PlugIns/iMove WatchKit Extension.appex
Domain: IXErrorDomain
Code: 2
Failure Reason: Failed to create promise.
User Info: {
    FunctionName = "+[IXPlaceholder _placeholderForBundle:client:withParent:installType:metadata:error:]";
    IDERunOperationFailingWorker = IDELaunchiPhoneSimulatorLauncher;
    SourceFileLine = 639;
}
--
Failed to set placeholder attributes xyz.Catch-22.iMove.watchkitapp.watchkitextension
Domain: IXErrorDomain
Code: 2
Failure Reason: Failed to create promise.
User Info: {
    FunctionName = "+[IXPlaceholder _placeholderForBundle:client:withParent:installType:metadata:error:]";
    SourceFileLine = 529;
}
--
extensionDictionary must be set in placeholder attributes for a plugin placeholder
Domain: IXErrorDomain
Code: 17
Failure Reason: Invalid placeholder attributes.
User Info: {
    FunctionName = "-[IXPlaceholder setPlaceholderAttributes:error:]";
    SourceFileLine = 1419;
}
--

Analytics Event: com.apple.dt.IDERunOperationWorkerFinished : {
    "device_model" = "Watch5,4";
    "device_osBuild" = "8.0 (19R345)";
    "device_platform" = "com.apple.platform.watchsimulator";
    "launchSession_schemeCommand" = Run;
    "launchSession_state" = 1;
    "launchSession_targetArch" = "x86_64";
    "operation_duration_ms" = 107;
    "operation_errorCode" = 2;
    "operation_errorDomain" = IXErrorDomain;
    "operation_errorWorker" = IDELaunchiPhoneSimulatorLauncher;
    "operation_name" = IDERunOperationWorkerGroup;
    "param_consoleMode" = 0;
    "param_debugger_attachToExtensions" = 0;
    "param_debugger_attachToXPC" = 1;
    "param_debugger_type" = 3;
    "param_destination_isProxy" = 1;
    "param_destination_platform" = "com.apple.platform.watchsimulator";
    "param_diag_MainThreadChecker_stopOnIssue" = 0;
    "param_diag_MallocStackLogging_enableDuringAttach" = 0;
    "param_diag_MallocStackLogging_enableForXPC" = 1;
    "param_diag_allowLocationSimulation" = 1;
    "param_diag_gpu_frameCapture_enable" = 0;
    "param_diag_gpu_shaderValidation_enable" = 0;
    "param_diag_gpu_validation_enable" = 0;
    "param_diag_memoryGraphOnResourceException" = 0;
    "param_diag_queueDebugging_enable" = 1;
    "param_diag_runtimeProfile_generate" = 0;
    "param_diag_sanitizer_asan_enable" = 0;
    "param_diag_sanitizer_tsan_enable" = 0;
    "param_diag_sanitizer_tsan_stopOnIssue" = 0;
    "param_diag_sanitizer_ubsan_stopOnIssue" = 0;
    "param_diag_showNonLocalizedStrings" = 0;
    "param_diag_viewDebugging_enabled" = 1;
    "param_diag_viewDebugging_insertDylibOnLaunch" = 1;
    "param_install_style" = 0;
    "param_launcher_UID" = 2;
    "param_launcher_allowDeviceSensorReplayData" = 0;
    "param_launcher_kind" = 0;
    "param_launcher_style" = 0;
    "param_launcher_substyle" = 2048;
    "param_runnable_appExtensionHostRunMode" = 0;
    "param_runnable_productType" = "com.apple.product-type.application.watchapp2";
    "param_runnable_swiftVersion" = "5.5.1";
    "param_runnable_type" = 2;
    "param_testing_launchedForTesting" = 0;
    "param_testing_suppressSimulatorApp" = 0;
    "param_testing_usingCLI" = 0;
    "sdk_canonicalName" = "iphonesimulator15.0";
    "sdk_osVersion" = "15.0";
    "sdk_variant" = iphonesimulator;
}
--

System Information

macOS Version 11.6 (Build 20G165)
Xcode 13.1 (19466) (Build 13A1030d)
Timestamp: 2021-11-06T16:22:10-06:00

Here is my DataManager class:

import Foundation
import HealthKit

class DataManager: NSObject, HKWorkoutSessionDelegate, HKLiveWorkoutBuilderDelegate {
    enum WorkoutState {
        case inactive, active, paused
    }

    var healthStore = HKHealthStore()
    var workoutSession: HKWorkoutSession?
    var workoutBuilder: HKLiveWorkoutBuilder?
    var activity = HKWorkoutActivityType.cycling
    var state = WorkoutState.inactive

    func start() {
        let sampleTypes: Set<HKSampleType> = [
            .workoutType(),
            .quantityType(forIdentifier: .heartRate)!,
            .quantityType(forIdentifier: .activeEnergyBurned)!,
            .quantityType(forIdentifier: .distanceCycling)!,
            .quantityType(forIdentifier: .distanceWalkingRunning)!,
            .quantityType(forIdentifier: .distanceWheelchair)!
        ]

        healthStore.requestAuthorization(toShare: sampleTypes,
                                         read: sampleTypes) {
            success, error in
            if success {
                self.beginWorkout()
            }
        }
    }
    // MARK: - beginWorkout
    private func beginWorkout() {
        let config = HKWorkoutConfiguration()
        config.activityType = activity
        config.locationType = .outdoor

        do {
            workoutSession = try
            HKWorkoutSession(healthStore: healthStore,
                             configuration: config)
            workoutBuilder = workoutSession?.associatedWorkoutBuilder()
            workoutBuilder?.dataSource = HKLiveWorkoutDataSource(healthStore: healthStore,
                                                                 workoutConfiguration: config)
            workoutSession?.delegate = self
            workoutBuilder?.delegate = self
        } catch {
            // Handle errors here
        }
    }
    // MARK: - Delegate conformance methods
    func workoutSession(_ workoutSession: HKWorkoutSession,
                        didChangeTo toState: HKWorkoutSessionState,
                        from fromState: HKWorkoutSessionState,
                        date: Date) {

    }
    func workoutSession(_ workoutSession: HKWorkoutSession,
                        didFailWithError error: Error) {

    }
    func workoutBuilder(_ workoutBuilder: HKLiveWorkoutBuilder,
                        didCollectDataOf collectedTypes: Set<HKSampleType>) {

    }
    func workoutBuilderDidCollectEvent(_ workoutBuilder: HKLiveWorkoutBuilder) {

    }
}

4      

Did you do the Info.plist

“Open Info.plist using the project navigator on the left of Xcode’s window, then right-click in some white space below the previous data and choose Add Row. Look through the list of options until you find “Privacy - Health Share Usage Description”, which is the key we need to add in order to read health data. Give it the value “We read your health data during workouts”, which will be displayed to users. Now add another row, this time choosing the key “Privacy - Health Update Usage Description”, and give it the value “We need to save your completed workouts”.”

Excerpt From Hacking with watchOS: SwiftUI Edition Paul Hudson This material may be protected by copyright.

4      

@NigelGee I'm following the project page-by-page, so I did add those rows to the Info.plist prior to running the build.

4      

if you following the book then this is missing from your code

“Add this directly below the two delegate = self lines in beginWorkout():

workoutSession?.startActivity(with: Date())
workoutBuilder?.beginCollection(withStart: Date()) { success, error in
    guard success else {
        return
    }

    DispatchQueue.main.async {
        self.state = .active
    }
}

Excerpt From Hacking with watchOS: SwiftUI Edition Paul Hudson This material may be protected by copyright.

4      

Hacking with Swift is sponsored by RevenueCat.

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure your entire paywall view without any code changes or app updates.

Learn more here

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.