Cannot request appointment in iMessage apps and stickers lab

Unlike other labs I’ve checked, requesting appointment for the iMessage apps and stickers labs, requires the Feedback ID field to be filled. Isn’t this a mistake?

Hi Marco, we are currently investigating this issue for this particular session on the web. In the meantime, can you attempt to request an appointment through the Apple Developer app? You shouldn't encounter the same issue there.

When I tried, registration was already closed. It's really frustrating, because it was open when I first tried and it was the one lab I really wanted to get an appointment for.

Maybe someone here can help me? Here is the comment I wrote to request the lab.

I am developing a Stickers Message app extension and want to use SwiftUI to build the the interface. I have a working version which uses a UIHostingController to load the main SwiftUI view and a UIViewRepresentable to load a MSStickerView inside SwiftUI. What I want to discuss is:

  1. Is there better strategy than the one above?
  2. Is there a way for MSStickerView do not auto-size correctly inside SwiftUI? It doesn’t currently. 
  3. Is there a way to eliminate the MessagesViewController and have an App.swift loading a ContentView instead?
  4. Is there a way to delete Main.Storyboard? I’m not using Storyboards, but didn’t find a way to update Info.plist in order to delete it.

Hi Marco, sorry about the lab signup issues! With regards to your questions:

  1. It sounds like your approach is reasonable. If you're able to share some sample code, that would be helpful.
  2. That’s a little surprising. It would be helpful to see the MSSticker and MSStickerView initialization code if you can provide it.
  3. Since iMessage "apps" are extensions, not apps, this isn't possible.
  4. You should be able to delete the storyboard, replace NSExtensionMainStoryboard with NSExtensionPrincipalClass in your extension’s Info.plist, and set the value to your MSMessagesAppViewController subclass's name.

1. SwiftUI in UIView

Here is my MessagesViewController:


import UIKit
import Messages

class MessagesViewController: MSMessagesAppViewController {

    let swiftUIView = MainView()

    override func viewDidLoad() {
        super.viewDidLoad()

        addSubSwiftUIView(swiftUIView, to: view)
    }
}

The code is simple because the magic is being done by the boilerplate in the UIViewController extension bellow. Got the the idea and code from the article 'Getting started with UIKit in SwiftUI and vice versa' by Antoine van der Lee. It works pretty well, no complains here.

import UIKit
import SwiftUI

extension UIViewController {
    func addSubSwiftUIView<Content>(_ swiftUIView: Content, to view: UIView) where Content : View {

        let hostingController = UIHostingController(rootView: swiftUIView)

        addChild(hostingController)
        view.addSubview(hostingController.view)
        hostingController.view.translatesAutoresizingMaskIntoConstraints = false

        let constraints = [
            hostingController.view.topAnchor.constraint(equalTo: view.topAnchor),
            hostingController.view.leftAnchor.constraint(equalTo: view.leftAnchor),
            view.bottomAnchor.constraint(equalTo: hostingController.view.bottomAnchor),
            view.rightAnchor.constraint(equalTo: hostingController.view.rightAnchor)
        ]

        NSLayoutConstraint.activate(constraints)
        hostingController.didMove(toParent: self)
    }
}

2. MSStickerView won’t auto-size

To create an MSStickerView inside SwiftUI I'm using the following code. The frame: passed to the StickerView is not applied though. Without .frame(minWidth: size, minHeight: size), nothing is shown because the size becomes virtually zero.

import Messages
import SwiftUI
import UIKit

struct StickerView: UIViewRepresentable {
    var frame: CGRect
    var sticker: MSSticker?

    func makeUIView(context: Context) -> MSStickerView {
        MSStickerView(frame: frame, sticker: sticker)
    }    

    func updateUIView(_ uiView: MSStickerView, context: Context) {        
    }
}

@ViewBuilder
func makeStickerView(fromStickerData stickerData: StickerDataEntry, size: CGFloat = CGFloat(64)) -> some View {
    
    if let sticker = try? MSSticker(contentsOfFileURL: stickerData.url!, localizedDescription: stickerData.description) {

        StickerView(frame: CGRect(x: 0, y: 0, width: 408, height: 408), sticker: sticker)
            .frame(minWidth: size, maxWidth: size, minHeight: size, maxHeight: size)      
    }
}

4. Delete Main.Storyboard

I’ve tried following similar instructions before and again just now, but to no avail. The result is a bank screen on the iPhone and the app icon in the middle of a blank screen on the simulator (running on a Mac mini M1). The relevant section of my Info.plist looks like this:

	<key>NSExtension</key>
	<dict>
		<key>NSExtensionPrincipalClass</key>
		<string>MessagesViewController</string>
		<key>NSExtensionPointIdentifier</key>
		<string>com.apple.message-payload-provider</string>
	</dict>

Hi Marco, I'm using UIKit in Touchgram (because it was started ages ago) so can't help specifically but have spent most of the last 3 years in this space so happy to help.

Touchgram is probably the most complex iMessage app extension ever built (especially when I wrap v1.3) - it's effectively a full Keynote-level layout system plus gesture recognition plus exposing SpriteKit features such as shaders, animations & particles... all inside iMessage...to send interactive messages.

Responding to the Delete Main.Storyboard point

The result is a bank screen on the iPhone and the app icon in the middle of a blank screen on the simulator

If you are seeing that, you are launching the app from XCode.

You need to launch the Message Extension to debug it, which will bring it up inside Messages.

Note that this is very fragile - I sometimes have to launch a couple of times and do a dance of quitting XCode/Simulators.

Cannot request appointment in iMessage apps and stickers lab
 
 
Q