Karhin’s Blog
Apps, Design and Music
Later ↑

3 Ways to Play Xbox on a Mac

There are a thousand and one reasons why this might be useful: the TV is occupied or you don’t have one at all, poor eyesight or something else. In any case, Macs do have good displays, but unfortunately, there is no simple way to connect a console directly.

Remote Play

As of the end of 2023, Microsoft still doesn’t have an official Remote Play app for macOS, but they do have one for iPad and iPhone. I don’t understand why they haven’t ported it yet: there’s no objective reason.

Fortunately, there are third-party apps, such as OneCast. I’ve used it for several months. Currently, it costs about $30 for a one-time purchase.

It works roughly the same way as Remote Play in the official app. Sometimes you connect once and see Full HD with almost no lag, and sometimes you’re watching a pixelated slideshow. I never quite understood how it works under the hood and how it’s related to the phases of the moon, but I did manage to play several games on it.

HDMI Converter

There’s this magical thing called an “HDMI Capture Card.” It’s a device that connects to the computer via Type-C and converts the HDMI signal into something that the computer recognizes as a webcam.

Such devices range from $10 to $50. I’ll admit I made a mistake and ordered an adapter from Sandberg, which converts to Full HD at 30Hz (funny that it’s cheaper than OneCast). Theoretically, you can find devices with better specs, but they might be a bit more expensive.

To play, I use OBS. I tried with QuickTime, VLC, and some other apps, but they created noticeable lag. In an ideal world, this should have been the perfect solution, but it has its drawbacks.

  • The picture quality and stability immediately outshine Remote Play.
  • The adapter creates a slight delay that you need to get used to. It doesn’t interfere with playing games like Cyberpunk or Starfield.
  • Pay close attention to the output image specifications, not like I did.
  • This setup works for iPads with a Type-C port (iOS 17 or later) and an app like Orion.

Portable Display?

Okay, it seems playing Xbox via a Mac isn’t a great idea. Another option: buy a portable display. I’ve seen 13 and 15-inch portable IPS Full HD displays on the market. They’re priced similarly to a budget Samsung TV, are space-efficient, and weigh around 800 grams.

In short, the best option: get rich, buy a cinema, and play Xbox there instead of dealing with these alternatives. Don’t forget to subscribe to my Telegram channel. I’d skip Twitter since Musk might soon ruin it completely.

Why Should Lightning Go Away

There’s no secret that over the past year, Apple has considered removing the Lightning port from iPhones and accessories. Before the presentation, there were many discussions among Apple’s sectarians.

Should the European Union influence major Silicon Valley companies at all? Was Lightning the best connector in the world? Is Type-C evil? And many other strange questions.

Most of the arguments in favor of a proprietary connector are sheer sectarianism. I want to break down a bit why Lightning should have disappeared a long time ago.

Peripherals

Let’s start with the fact that Lightning was a good form factor for its time. At that time, there was no Type-C specification, but there was an awful Micro USB, which can still sometimes be found in devices because it’s cheap. Besides being one-sided, it constantly broke.

Now almost all technology is released with a Type-C connector. One cable is enough to charge a computer, connect a monitor Thunderbolt cord is needed, PlayStation or Xbox controller, headphones (except those from Apple, of course), iPad, or camera.

Currently, only the iPhone, AirPods, keyboard, and mouse require their proprietary wire.

It also works the other way around. You can’t just connect an SSD to an iPhone to transfer a 30-minute 4K video. You can’t directly connect a camera to transfer video from it to your phone. You can’t connect your phone to a TV if it doesn’t support AirPlay or if the wireless network quality is poor.

Almost any case of connecting something to an iPhone ends with it being impossible to do so. Meanwhile, I’ve been able to do all this with my iPad for a couple of years.

Type-C Is Unreliable and Some Different Cords

I’ll just remind you that Type-C is just a form factor for USB, which can support different specifications. It might not even transfer data, just provide power to the device.

Lightning is the same. But the joke is that it only supports the outdated and slow USB 2.0. And there are also Lightning cords from China that can only charge the phone.

Myths about Type-C being unreliable compared to Lighting are mostly nonsense. The pins in Lighting can break just as easily, and the connector itself oxidizes over time. If it’s somewhat more reliable, it doesn’t outweigh all the benefits of a universal connector.

To cover 99% of the use cases of any Type-C connector, buy quality cords. A good cable isn’t cheap, and the price starts at $40. A good cable usually has a lightning icon, indicating that the cord supports Thunderbolt. Such cords can even be used to connect monitors.

The only reason why Lighting hasn’t disappeared yet is money. Apple made money on this connector; manufacturers must pay Apple to do something with this connector.

Just a reminder of the glorious times when phones didn’t have a 3.5mm jack and headphones from various manufacturers were tightly tied to the device because of a custom connector. Sounds cool? Apple still sells headphones with Lightning when all other wired headphones are with Type-C. Just like 20 years ago.

UPD: I wrote this post before the presentation and unexpectedly guessed all the points that were made. Now they will be selling EarPods with a Type-C connector. Are you still against EU regulation?

Apple Museum in Poland

As you can guess, I’m a fan of computers and Apple. One morning, we thought about where to go, and Kate read about the Apple museum in Warsaw. My first thought was something like oh-my.

This museum is the largest in the World. I think it’s a fun fact. Steve Wozniak – one of the founders of Apple – has Polish roots. The family name also hints about it.

Cześć, Hello, Bonjour! The ticket costs $12.

The museum is in Fabryka Norblina in the center of Warsaw. It’s a factory with 200 years of history. There are more than 1600 exhibits related to the history of Apple. Do you know about Apple printers or cameras?

Apple I

Apple I was the first computer developed by Apple in 1976. The introductory price was $666.66. There are no more than 50 computers in the world nowadays. If you are lucky enough, you can find one at the auction for $500.000.

It’s a replica of the original computer, but you can see real Wozniak’s sign on the user manual and the motherboard.

Apple II and friends

Apple II is a legend in the computer world because it’s one of the first personal computers and the most produced and cloned computer.

Timeline of Apple II family, Wikipedia.

The series was started in 1978 and discounted in 1993. There are many-many modifications and many-many clones. Some sources say that around 200 clone models were produced.

Almost modern Macs

Zoomers don’t know about them. Boomers say that they were the best computers and the grass was green. For me, it’s just computers.

I didn’t know about enterprise solutions like Workgroup Server before. The series of Workgroup Servers was started in 1993 and discounted in 2003. Also, “Studio Display” is reused title from 1999.

Notebooks

Newton, colorful iBook, PowerBook? Black MacBook from plastic?

Duo Dock II is one of the most strange devices, in my opinion. The docking station turns a connected PowerBook Duo into a full-featured desktop Macintosh.

Printers

Apple produced printers and print paper from the 1980s to the end 1990s. They can be divided into three groups: dot matrix, laser, and thermal inkjet.

Some weird things from Apple

Analog Apple Watch, digital camera QuickTake, video conference camera, the repair suitcase. Wow!

Posters

Software, guides, and other boxes

Do you remember software boxes, CDs, and tapes? I think it’s a kind of forgotten art. Some of the examples were very unexpected for me. Some of them look very fresh even today.

Bonus videos

I played with old-school iMacs produced at the start of the 2000s. Sometimes I see opinions like old macOS was better and faster. So, you can check the genie effect on the original iMac PowerPC!

Really don’t understand why modern OS are so silent. Just listen to these sounds. I think they are fun and cute.

Conclusion

Must see it in Warsaw. It’s a nice place if you love the history of computers or are a tech lover. Exhibition changes time-to-time. I visited the museum at the end of 2022.

Don’t forget to subscribe to my Telegram channel, Instagram, and Twitter.

Artykul is available on the App Store

Artykul is an app that allows you to read your favorite sites in one place without ads, clutter, and algorithmic newsfeeds. I’m excited to announce the app is available on the App Store for iOS, iPadOS, and macOS!

We have been developing the app since March 2021. The first iteration worked on our servers, but we abandoned this decision and rewrote the backend and the client from scratch. The second iteration works on the device in your pocket.

You can add any website that has RSS or Atom feed. RSS is simple, open, and time-proven technology. You can take back control of your news feed. Unlike any other reader, Artykul uses RSS or Atom only for searching links, not content. In the future, we can add support for sites without feeds.

We developed the best-in-class Article Reader. And you can customize it: font, size, and color theme. All articles in Artykul are available offline. The reader also remembers a position where you stop reading.

One small surprise for developers is Artykul Instructions. It’s a small JSON-based format that describes web pages and their content. With the help of instructions, developers can modify web pages before converting and provide more meta information from the page. Feel free to try it!

Artykul for macOS

You can turn on push notifications for new articles from favorite sites. Our backend checks sites and notifies you when found something new.

We have implemented so many features and a million more well on the way. I can speak about the app all day. A picture is worth a thousand words, better try it yourself.

  • Folders
  • Bookmarks
  • Favorites
  • Full-Text Search
  • Unread indicator
  • Mark as read on the scroll
  • Custom feed settings for images and cell size limiting
  • Gesture navigation and full-screen reader
  • Folders with custom icons
  • Custom site names
  • Storage settings
  • 4 themes for the reader
  • Discover
  • App tint color
  • OPML import and export
  • And more-more-more…

We also developed widgets for sites. You can see it at the bottom of the screen if you view this page from an Apple device. Soon we will publish documentation for web developers and site owners. You will be able to integrate your blog or news site with Artykul in 1 minute.

Oh, and today you can read my blog in my app! Ecosystem! I’m also starting to blog in English. It’s my first note 🥹

Sign in with Apple: реализация и подводные камни

«Вход через Apple» был представлен в 2019 году и стал обязательным для всех приложений, которые используют авторизацию через социальные сети или внешние сервисы.

Я реализовывал функцию несколько раз и набил пару шишек на ней. Перед тем, как её реализовывать, хорошо подумайте, потому что самый главный вывод, который я сделал: не связывайтесь с авторизацией через Apple.

  • За неё нужно платить 100 долларов в год.
  • API очень запутанное, а отсутствие некоторых методов накладывает на архитектуру серверного приложения определённые ограничения.
  • Сложно тестировать.

iOS приложение

Здесь нет ничего сложного, но есть некоторые моменты, на которые стоит обратить внимание. Для начала добавьте в настройках проекта одноименное разрешение.

В 2022 году при авторизации можно попросить полное имя и электронную почту.

Первый важный момент: запрашиваемые данные передаются лишь однажды при первом входе, поэтому обязательно сохраните их в Keychain. Если ваш сервер или сеть отвалится и вы не сможете с первого раза отправить эти данные, то боюсь, что ваш пользователь больше не сможет войти.

Для работы с Keychain я использую KeychainWrapper. Репозиторий давно не обновлялся, но и в API ничего не менялось.

Если вы всё-таки запрашивали данные, но потеряли их, то вход можно сбросить через настройки: Settings → Apple ID → Password & Security → Apps Using Apple ID → Stop using Apple ID.

Второй важный момент: это не работает в симуляторе. В iOS 16 может починили, но я не проверял.

Третий важный момент: в Catalyst кнопка из SwiftUI не работает и приложение просто падает. Багу сто лет. Может быть его уже исправили, но я не проверял.

В SwiftUI добавить кнопку очень просто. Не забудьте импортировать AuthenticationServices.

SignInWithAppleButton(.continue, onRequest: { request in
    request.requestedScopes = [.email, .fullName]
}, onCompletion: { result in
    switch result {
    case .success(let auth):
        // handle it
    case .failure(let error):
        // ¯\_(ツ)_/¯
        print(error)
    }
})

В UIKit тоже ничего сложного нет, но придётся написать чуть больше кода. Создать фирменную кнопку можно примерно вот так.

private lazy var signInButton: ASAuthorizationAppleIDButton = {
    let button = ASAuthorizationAppleIDButton(
        authorizationButtonType: .continue,
        authorizationButtonStyle: traitCollection.userInterfaceStyle == .dark ? .white : .black
    )
    button.cornerRadius = 13.0
    button.translatesAutoresizingMaskIntoConstraints = false
    button.addTarget(self, action: #selector(didTapSignInButton), for: .touchUpInside)
    return button
}()

При нажатии создаём запрос на авторизацию и ASAuthorizationController, которому нужно указать делегата.

@objc private func didTapSignInButton() {
    let request = ASAuthorizationAppleIDProvider().createRequest()
    request.requestedScopes = [.email]
    
    let controller = ASAuthorizationController(authorizationRequests: [ request ])
    controller.delegate = self
    controller.presentationContextProvider = self
    controller.performRequests()
}

extension ViewController: ASAuthorizationControllerDelegate {
    
    func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
        print(error)
    }
    
    func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
        guard let credential = authorization.credential as? ASAuthorizationAppleIDCredential else { return }
        // handle it
    }
    
}

Что передавать на сервер?

Из объекта credential вам обязательно нужно достать identityToken и authorizationCode. Они необходимы для проверки токена на стороне сервера.

Эти объекты можно просто перевести в строки и передать как есть.

guard let identityTokenData = credential.identityToken else { return }
guard let authorizationCodeData = credential.authorizationCode else { return }
guard let identityToken = String(data: identityTokenData, encoding: .utf8) else { return }
guard let authorizationCode = String(data: authorizationCodeData, encoding: .utf8) else { return }

Identity Token содержит всю самую важную информацию: уникальный идентификатор пользователя, email и fullName.

Серверная часть

Если для вашего языка программирования есть хорошая библиотека для валидации токенов от Apple, то поздравляю, можете её взять и использовать. Скорее всего, её нет.

Четвёртый важный момент: c 30 июня 2022 года все приложения должны предоставлять функцию удаления аккаунта в приложении. Это требование напрямую касается всех, кто использует вход через Apple, так как необходимо отозвать токены, а нормального способа это сделать не существует.

Перед тем, как вы сможете валидировать токены, необходимо получить ваш приватный ключ в Apple Developer. Если вы отправляете пуши, то у вас он скорее всего есть.

Apple Developer → Certificates, Identifiers & Profiles → Keys. Не забудьте включить сервис Sign In with Apple.

Сохраните ключ в безопасное место и не делайте хардкод. Вместе с ключом вам нужно держать рядом Key ID, Team ID и Bundle ID вашего приложения.

Генерируем токен для сервера

Перед этим шагом поищите библиотеку для JWT, если у вас её ещё нет.

Он нужен для того, чтобы отправлять запросы на сервера Apple. Представляет из себя обычный JSON Web Token (JWT) в котором указаны Team ID и Bundle ID. Подписать его нужно вашим приватным ключом, который вы скачали у Apple.

В документации более подробно расписано про все поля. Ниже пример пейлоуда на Go, а вот пример генерации на питоне.

Для подписи используйте ES256.

type SecretKeyPayload struct {
	Iss string `json:"iss"`
	Iat int64  `json:"iat"`
	Exp int64  `json:"exp"`
	Aud string `json:"aud"`
	Sub string `json:"sub"`
}

Проверяем Identity Token

Сначала нужно скачать JSON Web Key (JWK) от Apple, которыми подписываются токены для авторизации. Адрес с ключами ниже.

https://appleid.apple.com/auth/keys

Не все библиотеки для JWT поддерживают JWK, но в этом нет ничего страшного. JWK представляет из себя просто массив ключей. Достаточно разобрать заголовок из JWT и найти публичный ключ у которого такой же kid.

Учитывайте, что ключи очень часто обновляются. Количество ключей и они сами постоянно меняются.

identityToken, который прислал нам iOS клиент, представляет из себя как раз таки JWT, который подписан одним из этих ключей.

Не забудьте дополнительно проверить следующие поля:

  • exp меньше текущего времени в UNIX.
  • iss равен https://appleid.apple.com.
  • aud равен нашему Bundle ID.

Генерируем Refresh Token

На этом шаге нам пригодится приватный ключ сервера, который мы уже сгенерировали и подписали ранее. Более подробная документация доступна на сайте Apple.

https://appleid.apple.com/auth/token

На этот адрес отправляем запрос с следующей формдатой:

  • client_id с идентификатором приложения.
  • client_secret с серверным токеном.
  • grant_type с строкой authorization_code.
  • code с authorizationCode, который нам прислало iOS приложение.

В ответ должен прилететь JSON с следующей структурой. Не забудьте проверить HTTP статус, он должен быть 200.

type GeneratedTokenResponse struct {
	AccessToken  string `json:"access_token"`
	TokenType    string `json:"token_type"`
	ExpiresIn    int64  `json:"expires_in"`
	RefreshToken string `json:"refresh_token"`
	IdToken      string `json:"id_token"`
}

В ответе можно найти id_token, это новый железобетонный identityToken, который уже точно можно использовать внутри приложения.

А что дальше?

Можно добавить нового пользователя в систему и сгенерировать свой собственный токен, чтобы отдать его клиенту. Вы же не хотите такой ерундой заниматься каждый раз на эппловых токенах?

Пятый важный момент: обязательно сохраните в базу данных refresh_token и access_token. Желательно с привязкой к вашим внутренним сессиям.

Зачем это нужно? Я не знаю, спросите у Тима Кука или напишите петицию, что у лучших инженеров какое-то абсолютно дебильное API с ненужными действиями, потому что вы ничего не сможете сделать с этими токенами, кроме как отозвать или провалидировать.

Обновляем Access Token

В документации написано, что делать это нужно раз в сутки.

Адрес совпадает с генерацией, но немного меняются данные:

  • grant_type с строкой refresh_token.
  • refresh_token с собственно токеном, который мы получили.

Отзываем токены

Видимо, их стоит отзывать, когда пользователь разлогинивается в приложении. А ещё нужно отозвать все токены, которые нам выдал Apple, если пользователь решил удалить аккаунт в приложении. Сделать это можно только по одному за раз.

https://appleid.apple.com/auth/revoke

На этот адрес отправляем запрос с следующей формдатой:

  • client_id с идентификатором приложения.
  • client_secret с серверным токеном.
  • token_type_hint с строкой refresh_token или access_token.
  • token с самим токеном.

В случае успеха возвращается 200-ый код с пустым телом. В общем, на ответ можно просто забить.

Заключение

Я бы хотел написать, что авторизация через Apple – это круто, но нет.

  • С 2019 года здесь есть какой-то бессмысленный набор токенов, который нужно валидировать и хранить. Зачем нужен access_token?
  • Почему нельзя в любой момент получить электронную почту?
  • Зачем делать столько лишних запросов на подтверждение, если ваши сервера сами подписывают Identity Token?
  • Почему они не сделали метод для отзыва всех токенов за раз? Даже писал репорт им, что это тупость откровенная без такого метода жить, но мне никто не ответил.
  • С 2022 года, если ты ещё неправильно хранишь и отзываешь эти токены, то нарушаешь гайдлайны App Store.

Самый главные подводные камни:

  • Сохраняйте email и fullName на клиенте, пока точно не будете уверены, что регистрация была успешной.
  • Сохраняйте токены вместе с вашей внутренней сессией.
  • Валидируйте токены.
  • Не забывайте, что токены нужно отзывать.
Earlier ↓