Building Video Streaming Widget for iOS App

Introduction I was exploring the idea of creating a YouTube-like widget for the lock screen on iOS devices. It wasn’t easy because most articles on the Internet discussed general implementations, such as for a coffee shop or a to-do list. Even when I found some similar versions, the project wouldn’t compile. I made the decision to approach it my way, so here’s what I found out: Caveats After being stuck for two or more hours without understanding why, after tapping on a button, I wasn't able to receive a callback from it and the widget always opened the main iOS app, I realized that I forgot to add AppIntent - without it, you can’t handle actions for iOS 17. import AppIntents struct ButtonIntent: AppIntent { static let title: LocalizedStringResource = "ButtonIntent" @Parameter(title: "id") var id: String func perform() async throws -> some IntentResult { if id == Command.playPause.rawValue { DataModel.shared.isPlaying.toggle() } return .result() } } Another crucial point is not to forget to add an explicit init. If you don’t implement it explicitly, it will not work. import AppIntents struct ButtonIntent: AppIntent { static let title: LocalizedStringResource = "ButtonIntent" @Parameter(title: "id") var id: String init(id: String) { self.id = id } init() {} func perform() async throws -> some IntentResult { if id == Command.playPause.rawValue { DataModel.shared.isPlaying.toggle() } return .result() } } Lastly, I attempted to add a Slider, but I found that it’s not supported by the widget. My solution was to choose a ProgressView instead. Implementation struct YouTubeLockScreenWidget: View { var body: some View { VStack { Spacer() ProgressView(value: DataModel.shared.currentTime, total: DataModel.shared.totalTime) .progressViewStyle(.linear) Spacer() HStack { ForEach(Command.allCases) { command in Button(intent: ButtonIntent(id: command.id)) { Image(systemName: imageSystemName(isPlaying: DataModel.shared.isPlaying, command: command)) } } } } } } final class DataModel { static let shared = DataModel() var isPlaying: Bool = false var currentTime: TimeInterval = 34 var totalTime: TimeInterval = 304 } enum Command: String, CaseIterable { case previous case playPause case next } extension Command: Identifiable { var id: String { rawValue } } func imageSystemName(isPlaying: Bool, command: Command) -> String { switch command { case .playPause: if isPlaying { return "pause.fill" } else { return "play.fill" } case .next: return "forward.fill" case .previous: return "backward.fill" } } I had not replaced default generated code when I was adding widget to the project. I just added YouTubeLockScreenWidget to generated VideoStreamingWidgetEntryView. ...

May 5, 2024 · 2 min · Dmytro Chumakov

Building Video Streaming iOS App

Introduction I was looking for a way to add a video player to my iOS app that could be able to play remote videos. Caveats Problem I found that you can’t open Vimeo or Youtube videos because of AVFoundationErrorDomain Code=-11850 "Operation Stopped" UserInfo={NSLocalizedFailureReason=The server is not correctly configured Domain=NSOSStatusErrorDomain Code=-12939 error. I don’t know exactly what this means, but I’m speculating it’s related to some protection. Solution My solution was to find another video that is not related to those platforms. ...

May 3, 2024 · 1 min · Dmytro Chumakov

Building Group Chat using WebSockets

Introduction I never had a chance to work with WebSockets, so I decided to take a look and create a group chat. Here’s what I discovered: To be able to send and receive messages, you need to create an interface for communication between a server and your application. In my case, I chose sendMessage and receiveMessage methods. For the server-side, I chose Node.js. For the iOS application, I chose the Socket.IO library. Implementation Let’s dive deeper into the implementation. ...

May 2, 2024 · 4 min · Dmytro Chumakov

Exploring visionOS

Introduction I find myself fascinated by the idea of creating an app for visionOS where I could possibly display 3D AirPods that I like. Here are a few steps on how you can do the same: First step The first step that you need to do is to create a visionOS project. Second step The next step would be adding a 3D object to Reality Composer Pro and exporting it as a .usdz file. You can download free 3D objects here. All you need to do to download content is to register on this site. ...

May 2, 2024 · 1 min · Dmytro Chumakov

iOS AR App: Experience 3D Guitar

Introduction I was searching for an AR implementation of a 3D guitar inside an iOS app. Here’s what I discovered: First Step The first step is not related to building the app. Before that you need to create a project using the Reality Composer Pro app (you can find it through Spotlight search). Second Step After that, you need to visit https://developer.apple.com/augmented-reality/quick-look/ and download one of the USDZ files. In my case, I chose the 3D guitar. ...

May 1, 2024 · 2 min · Dmytro Chumakov