Notification Center

I am trying to set up all of my Swift text and labels to work with notification center so what is displayed can be changed using an objective C file. My connection and status text works but I am getting the following errors for Text(“Uploading memory model to controller”): “Instance member ‘publisher5’ of type ‘CMWSTUploadViewV2Controller.ContentView’ cannot be used on instance of nested type ‘CMWSTUploadViewV2Controller.ContentView.ProgressBar’”

My Objective C code:

-(void)summerTestUploadViewController
{
    CMWSTUploadViewV2Controller* myView = [[UIStoryboard storyboardWithName:@"MainStoryboard_iPhone" bundle:nil] instantiateViewControllerWithIdentifier:@"ID_CMW_UPLOADVIEWV2_VIEW"];
 //   myView.delegate = self;
    [self presentViewController:myView animated:YES completion:^{
        [myView UpdateUploadProgressWithProgressValue:0.7];
        [myView UpdateInitialTextWithInitialTextParameter:@"Initial text here"];
        [myView UpdateAddressTextWithAddressTextParameter:@"Address text here"];
        [myView UpdateOrangeTextWithOrangeTextParameter:@"Orange text here"];
        [myView UpdateGreySubTextWithGreySubTextParameter:@"Grey sub text here"];
        [myView UpdateControllerTypeTextWithControllerTypeTextParameter:@"Controller text here"];
        [myView UpdateConnectionTypeTextWithConnectionTypeTextParameter:@"Connection text here"];
        [myView UpdateStatusTextWithStatusTextParameter:@"Status text here"];
        
    }];
}

My Swift code:


import Foundation
import SwiftUI

@objc public protocol CMWUploadViewV2Delegate: NSObjectProtocol {
    @objc func uploadOKButtonPushed()
    @objc func uploadAbortButtonPushed()
    @objc func uploadErrorLogButtonPushed()
    @objc func uploadRetryButtonPushed()
}

@objc class CMWSTUploadViewV2Controller: UIViewController {
   
    @IBOutlet var ProgressBarView: UIView!
    
    // embed SwiftUI into the UIKit storyboard view controller
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let childView = UIHostingController(rootView: ContentView())
        addChild(childView)
        childView.view.frame = ProgressBarView.bounds
        ProgressBarView.addSubview(childView.view)
        childView.didMove(toParent: self)
        
    }
    
    @objc weak var delegate: CMWUploadViewV2Delegate?
    
    //creating function for dictionary to store changes and create notification
    //This takes a value between 0 and 1 
    @objc func UpdateUploadProgress(progressValue: Float)
    {
        //First, we need to normalize the value which is between 0 and 0.99 to 0 and 0.8999996
        let normalizedValue = progressValue * 0.8999996
        let valueUpdate:[String: Float] = ["ProgressValue": normalizedValue]
        NotificationCenter.default.post(name:NSNotification.Name("COM.CMW.UpdateUploadProgress"), object: nil, userInfo:valueUpdate)
    }
    
    @objc func UpdateInitialText(InitialTextParameter: String)
    {
        let textUpdate:[String: String] = ["InitialTextParameter": InitialTextParameter]
        NotificationCenter.default.post(name:NSNotification.Name("COM.CMW.UpdateInitialText"), object: nil, userInfo:textUpdate)
    }
    
    @objc func UpdateAddressText(AddressTextParameter: String)
    {
        let textUpdate:[String: String] = ["AddressTextParameter": AddressTextParameter]
        NotificationCenter.default.post(name:NSNotification.Name("COM.CMW.UpdateAddressText"), object: nil, userInfo:textUpdate)
    }
    
    @objc func UpdateOrangeText(OrangeTextParameter: String)
    {
        let textUpdate:[String: String] = ["OrangeTextParameter": OrangeTextParameter]
        NotificationCenter.default.post(name:NSNotification.Name("COM.CMW.UpdateOrangeText"), object: nil, userInfo:textUpdate)
    }
    
    @objc func UpdateGreySubText(GreySubTextParameter: String)
    {
        let textUpdate:[String: String] = ["GreySubTextParameter": GreySubTextParameter]
        NotificationCenter.default.post(name:NSNotification.Name("COM.CMW.UpdateGreySubText"), object: nil, userInfo:textUpdate)
    }
    
  
    @objc func UpdateControllerTypeText(ControllerTypeTextParameter: String)
    {
        let textUpdate:[String: String] = ["ControllerTypeTextParameter": ControllerTypeTextParameter]
        NotificationCenter.default.post(name:NSNotification.Name("COM.CMW.UpdateControllerTypeText"), object: nil, userInfo:textUpdate)
    }
    
     @objc func UpdateConnectionTypeText(ConnectionTypeTextParameter: String)
     {
         let textUpdate:[String: String] = ["ConnectionTypeTextParameter": ConnectionTypeTextParameter]
         NotificationCenter.default.post(name:NSNotification.Name("COM.CMW.UpdateConnectionTypeText"), object: nil, userInfo:textUpdate)
     }
    
     @objc func UpdateStatusText(StatusTextParameter: String)
     {
         let textUpdate:[String: String] = ["StatusTextParameter": StatusTextParameter]
         NotificationCenter.default.post(name:NSNotification.Name("COM.CMW.UpdateStatusText"), object: nil, userInfo:textUpdate)
     }
    
    struct ContentView: View {
        //creating vars
        @State var progressValue: Float = 0.3
        //let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
        @State private var degress: Double = -110
        @State var GreySubText = ""
        let label = UILabel()
        @State var buttonText1 = ""
        @State var buttonText2 = ""
        @State var controllerTypeText = ""
        @State var connectionTypeText = "CAN"
        @State var statusText = "Status text here"
        @State var fourLinesText = "More status text here. Controller responding. This text will be 4 lines in length. 1234567891011121314151617181920. Controller responding. This text will be 4 lines in length. 1234567891011121314151617181920. Controller responding. This text will be 4 lines in length. 1234567891011121314151617181920"
        @State var initialText = "Resetting to upload mode."
        
        //setting up notification center to listen to addresses
        let publisher = NotificationCenter.default.publisher(for: NSNotification.Name("COM.CMW.UpdateUploadProgress"))
        let publisher8 = NotificationCenter.default.publisher(for: NSNotification.Name("COM.CMW.UpdateInitialText"))
        let publisher6 = NotificationCenter.default.publisher(for: NSNotification.Name("COM.CMW.UpdateAddressText"))
        let publisher7 = NotificationCenter.default.publisher(for: NSNotification.Name("COM.CMW.UpdateOrangeText"))
        let publisher5 = NotificationCenter.default.publisher(for: NSNotification.Name("COM.CMW.UpdateGreySubText"))
        let publisher2 = NotificationCenter.default.publisher(for: NSNotification.Name("COM.CMW.UpdateControllerTypeText"))
        let publisher3 = NotificationCenter.default.publisher(for: NSNotification.Name("COM.CMW.UpdateConnectionTypeText"))
        let publisher4 = NotificationCenter.default.publisher(for: NSNotification.Name("COM.CMW.UpdateStatusText"))
        
        //display
        var body: some View {
            VStack {
                Spacer()
                    .frame(height: 70)
                
                if #available(iOS 16.0, *) {
                    Label("Resetting to upload mode.", systemImage: "clock")
                        .font(.title)
                        .foregroundColor(Color(hex: "000"))
                        .fontWeight(.bold)
                        .onReceive(publisher8) { obj in
                            let statusTextVal = obj.userInfo?["InitialTextParameter"] as? String
                            fourLinesText = statusTextVal!
                        }

                } else {
                    // Fallback on earlier versions
                    Label("Resetting to upload mode.", systemImage: "clock")
                        .font(.title)
                        .foregroundColor(Color(hex: "000"))
                }
                    
                    
                ZStack{
                    //background rectangle
                    RoundedRectangle(cornerRadius: 25)
                        .fill(Color(hex: "494949"))
                        .frame(width: 300, height: 300)
                    
                    ProgressBar(progress: self.$progressValue)
                        .frame(width: 250.0, height: 250.0)
                        .padding(40.0)
                        .onReceive(publisher) { obj in
                            let progVal = obj.userInfo?["ProgressValue"] as? Float
                            progressValue = progVal!
                            }
                    
                    ProgressBarTriangle(progress: self.$progressValue).frame(width: 280.0, height: 290.0).rotationEffect(.degrees(degress), anchor: .bottom)
                        .offset(x: 0, y: -150)
                }
                
                //***Controller, Connection, and Status labels/text
                Spacer()
                    .frame(height: 20)
                VStack(alignment :.leading, spacing: 30) {
                    HStack {
                        if #available(iOS 16.0, *) {
                            Label("Controller type:", image: "ControllerIcon")
                                .foregroundColor(Color(hex: "000"))
                                .fontWeight(.bold)
                        } else {
                            // Fallback on earlier versions
                            Label("Controller type:", image: "ControllerIcon")
                                .foregroundColor(Color(hex: "000"))
                        }
                        Text(controllerTypeText)
                        //app crashes when following code active:
                        //onReceive(publisher2) { obj in
                            //let controllerTextVal = obj.userInfo?["ControllerTypeTextParameter"] as? String
                            //controllerTypeText = controllerTextVal!
                        //}
                    }
                    
                    HStack {
                        if #available(iOS 16.0, *) {
                            Label("Connection type:", image: "CANIconSmall")
                                .foregroundColor(Color(hex: "000"))
                                .fontWeight(.bold)
                        } else {
                            // Fallback on earlier versions
                            Label("Connection type:", image: "CANIconSmall")
                                .foregroundColor(Color(hex: "000"))
                        }
                        Text(connectionTypeText)
                            .onReceive(publisher3) { obj in
                                let connectionTextVal = obj.userInfo?["ConnectionTypeTextParameter"] as? String
                                connectionTypeText = connectionTextVal!
                            }
                    }
                    
                    HStack {
                        if #available(iOS 16.0, *) {
                            Label("Status:", image: "StatusIcon")
                                .foregroundColor(Color(hex: "000"))
                                .fontWeight(.bold)
                        } else {
                            // Fallback on earlier versions
                            Label("Status:", image: "StatusIcon")
                                .foregroundColor(Color(hex: "000"))
                        }
                        
                    }
                    
                    //four lines of status text
                    Text(fourLinesText)
                        .foregroundColor(Color(hex: "000"))
                        .lineLimit(4)
                        .multilineTextAlignment(.leading)
                        .onReceive(publisher4) { obj in
                            let statusTextVal = obj.userInfo?["StatusTextParameter"] as? String
                            fourLinesText = statusTextVal!
                        }
                    
                    Spacer()
                }
                .padding(.leading, 20)
                .padding(.trailing, 20)
            }
        }
        
        public struct ProgressBar: View {
            //creating vars
            @Binding var progress: Float
            @State var addressText = "0x1c000"
            @State var orangeText = "Orange Text"
            
            public func UpdateProgressValue(progressValue: Float)
            {
                progress = progressValue
            }
            
            var body: some View {
                
                VStack (alignment :.center, spacing: 30){
                    HStack {
                        Label("Address:", systemImage: "target")
                            .foregroundColor(Color(hex: "8f8f8f"))
                            .padding(.top, 15)
                        Text(addressText)
                            .foregroundColor(Color(hex: "8f8f8f"))
                            .padding(.top, 15)
                            //.onReceive(publisher6) { obj in
                                //let addressTextVal = obj.userInfo?["AddressTextParameter"] as? String
                                //addressText = addressTextVal!
                            //}
                    }
                    ZStack {
                        
                        Circle()
                            .trim(from: 0.35, to: 0.85)
                            .stroke(style: StrokeStyle(lineWidth: 12.0, lineCap: .round, lineJoin: .round))
                            .opacity(0.3)
                            .foregroundColor(Color.gray)
                            .rotationEffect(.degrees(54.5))
                        
                        Circle()
                            .trim(from: 0.35, to: CGFloat(self.progress))
                            .stroke(style: StrokeStyle(lineWidth: 12.0, lineCap: .round, lineJoin: .round))
                            .fill(AngularGradient(gradient: Gradient(stops: [
                                .init(color: Color.init(hex: "daff00"), location: 0.39000002),
                                .init(color: Color.init(hex: "00ff04"), location: 0.5999999),
                                .init(color: Color.init(hex: "32E1A0"), location: 0.8099997)]), center: .center))
                            .rotationEffect(.degrees(54.5))
                        
                        VStack(alignment :.center, spacing: 10) {
                            
                            Text("824").font(Font.system(size: 44)).bold().foregroundColor(Color.init(hex: "ffffff"))
                            
                            if #available(iOS 16.0, *) {
                                Label(orangeText, systemImage: "clock")
                                    .foregroundColor(Color(hex: "FF6600"))
                                    .fontWeight(.bold)
                                //.onReceive(publisher7) { obj in
                                    //let statusTextVal = obj.userInfo?["OrangeTextParameter"] as? String
                                    //orangeText = statusTextVal!
                                //}
                            } else {
                                // Fallback on earlier versions
                                Label(orangeText, systemImage: "clock")
                                    .foregroundColor(Color(hex: "FF6600"))
                                //.onReceive(publisher7) { obj in
                                    //let statusTextVal = obj.userInfo?["OrangeTextParameter"] as? String
                                    //orangeText = statusTextVal!
                                //}
                            }
                            
                            Text("Uploading memory model to controller")
                                .foregroundColor(Color(hex: "8f8f8f"))
                                .multilineTextAlignment(.center)
                                .onReceive(publisher5) { obj in
                                    let GreySubTextVal = obj.userInfo?["GreySubTextParameter"] as? String
                                    connectionTypeText = GreySubTextVal!
                                }
                            
                        }
                    }
                    
                }
                
            }
            
        }
        
        struct ProgressBarTriangle: View {
            @Binding var progress: Float
            
            
            var body: some View {
                ZStack {
                    Image("triangle").resizable().frame(width: 10, height: 10, alignment: .center)
                }
            }
        }
    }
    
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView()
        }
    }
}
    extension Color {
        init(hex: String) {
            let hex = hex.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
            var int: UInt64 = 0
            Scanner(string: hex).scanHexInt64(&int)
            let a, r, g, b: UInt64
            switch hex.count {
            case 3: // RGB (12-bit)
                (a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
            case 6: // RGB (24-bit)
                (a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF)
            case 8: // ARGB (32-bit)
                (a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
            default:
                (a, r, g, b) = (1, 1, 1, 0)
            }
            
            self.init(
                .sRGB,
                red: Double(r) / 255,
                green: Double(g) / 255,
                blue:  Double(b) / 255,
                opacity: Double(a) / 255
            )
        }
        
    }

You are getting a build error because you declared publisher5 as a property in the content view, but you are trying to access it in the progress bar view. The progress bar has no knowledge of publisher5.

You don’t use publisher5 in your content view so you could declare it in the progress bar view. But you may need to use a @State or @StateObject property instead of a let constant.

There could be other errors in your code. Some questions.

  • Do UIKit view controllers support adding SwiftUI views to them?
  • Why do you nest the progress bar inside the content view? Shouldn’t they be independent structs?

What you are trying to do is unusual so you may have a tough time getting much more help on this forum. Not many people use Objective-C code in SwiftUI apps, and not many people try to place SwiftUI in UIKit view controllers.

This topic was automatically closed after 166 days. New replies are no longer allowed.