
【iOS】 オンデバイスLLMを活用し、オリジナル絵文字(ジェン文字)を生成しよう。try! Swift Tokyo 2026のトーク解説
世界中から開発者が集まる日本最大級のSwiftのカンファレンスtry! Swift Tokyo 2026で登壇してきました。
今年の会場は去年に引き続き、立川ステージガーデンで開催され、前日は、モーニング娘。’26さんが同会場でコンサートしていたらしく、まさか偉大なアイドルさんと同じ舞台の上に立てるとは思いませんでした。
登壇内容
Genmojiと私たちはどう生きるのかというテーマで登壇させていただきました。
Apple Intelligenceを活用した画像生成(主にジェン文字)についての発表でした。
LTという短い時間での発表で、ざっくりした全体像でしか紹介できませんでした。
なので、この記事では発表スライドを挟みながら、少しだけ詳細も説明していきます。
環境
- Xcode 26.4
- iOS 26.4
Apple Intelligence
Apple Intelligenceはデバイスに組み込まれたAppleのAIです。
Apple Intelligence対応端末一覧
iPhone
| 端末 | チップ |
|---|---|
| iPhone 15 Pro / 15 Pro Max | A17 Pro |
| iPhone 16 / 16 Plus | A18 |
| iPhone 16e | A18 |
| iPhone 16 Pro / 16 Pro Max | A18 Pro |
| iPhone 17 / 17e | A19 |
| iPhone Air | A19 Pro |
| iPhone 17 Pro / 17 Pro Max | A19 Pro |
iPad
| 端末 | チップ |
|---|---|
| iPad mini (第7世代) | A17 Pro |
| iPad Air | M1以降 |
| iPad Pro | M1以降 |
Mac / その他
| 端末 | チップ |
|---|---|
| MacBook Air / Pro | M1以降 |
| iMac / Mac mini | M1以降 |
| Mac Studio | M1 Max以降 |
| MacBook Neo | A18 Pro |
| Apple Vision Pro | M2以降 |
ジェン文字とは
WWDC24で発表されたApple Intelligenceの機能で、パーソナライズされた絵文字を作成できる機能です。
例えば、SmileとNosebleedというテキストから次のようなジェン文字が作成できます。

ジェン文字はBeta版
登場から2年経ちましたが、いまだにBeta版に位置しており、意図としない結果が出力されてしまうことを理解した上でご利用いただければと思います。

ユーザーがジェン文字を作成できる場所
Apple Intelligence対応機種であれば、以下の経路でジェン文字が作成できます。
- 絵文字キーボードのジェン文字ボタン
- AppleのImage Playgroundアプリ
- スタイルのオプションでジェン文字を選択することで作成可能

開発者がアプリに画像生成機能を組み込む方法
AppleからImage Playgroundフレームワークが提供されており、これを活用することでオンデバイスでの画像生成をアプリに簡単に組み込むことができます。
主に、2つのアプローチがあります。
ImagePlaygroundSheet- UIKit, AppKit:
ImagePlaygroundViewControleer
- UIKit, AppKit:
ImageCreator
ImagePlaygroundSheet
ImagePlaygroundSheetは、前述したAppleのImage Playgroundアプリと同じような機能をもったシステムシートを表示できる機能です。

このシート上で選択できる画像生成のスタイルは以下の4つです。
- アニメーション
- イラスト
- スケッチ
- ChatGPT
Image Playgroundアプリでは存在していたはずのジェン文字の選択肢はありませんでした、、
ImageCreator
ImageCreatorは、与えたテキストや画像などから画像生成スタイルを決めて、プログラマティックに画像生成できるクラスです。
以下のブログに詳細がまとまっているのでぜひ読んでみてください。
基本的な画像生成の流れは以下になります。
func generateImage() async throws {
// ImageCreatorの初期化
let creator = try await ImageCreator()
// 画像に含めたいコンセプト
let concepts: [ImagePlaygroundConcept] = [.text("enjoy programing")]
// 生成される画像の見た目のオプション
let style: ImagePlaygroundStyle = .animation
for try await result in creator.images(
for: concepts,
style: style,
limit: 1
) {
// 生成された画像
let generateImage = result.cgImage
}
}
ImagePlaygroundConcept
生成する画像に含めたいコンセプトをテキストやPKDrawingや画像などで示してあげることができます。
text(String)- 短いテキストからコンセプトを作成
extracted(from: String, title: String?)- 長文の文字列とタイトルからコンセプトを作成
- この
titleが長文の文字列を要約するためのキーワードとして使用されます
- この
- 長文の文字列とタイトルからコンセプトを作成
drawing(PKDrawing)- PencilKitの描画からコンセプトを作成
image(CGImage)- 指定した画像からコンセプトを作成
image(URL)- 指定したURLの画像からコンセプトを作成
creator.imagesに渡すImagePlaygroundConceptは配列で渡せれるのため、以下のような記述も可能です。
for try await result in creator.images(
for: [.text("enjoy programing"),
.image(capturedImage)],
style: style,
limit: 1
) {
個人的な感想ですが、imageを使用した場合、生成される画像はimageの主張がかなり強い気がしています。
ImagePlaygroundStyle
生成される画像の見た目のオプションを選ぶことができます。
animation- アニメーションスタイル
illustration- 2D カートゥーンスタイル
sketch- 手描きスケッチスタイル
externalProvider- 外部プロバイダーが提供するスタイル
all:[ImagePlaygroundStyle]- あらゆるスタイルで画像を生成できるオプション
残念ながら、このドキュメント上にもgenmojiのオプションはありませんでした、、
ImageCreator.availableStyles
ImageCreatorのプロパティにavailableStylesがあります。
この値を出力して確認してみると、emojiというジェン文字のためのスタイルを確認できます。

以下のようなコードで、プログラマティックにジェン文字を生成できるようになります。
func generateGenmoji() async throws {
let creator = try await ImageCreator()
guard let emojiStyle = creator.availableStyles.first(where: { $0.id == "emoji" })
else { fatalError("My App is dead") }
for try await result in creator.images(
for: [.image(capturedImage)],
style: emojiStyle,
limit: 1
) {
let generateImage = result.cgImage
}
}
左で撮影した写真が右のジェン文字となって出力されました。

conceptRequirePersonIdentity
これはジェン文字生成に限った話ではないのですが、ImageCreatorで文字列を渡して画像生成を行っていると、たびたびconceptRequirePersonIdentityエラーが発生して、生成を失敗することがありました。
このエラーが発生していた時のコンセプトとして渡していた文字列を見てみると、

Iやa man、🏃など人間に関連すると表現を使うコンセプトで多く発生していることが分かりました。
conceptRequirePersonIdentityのエラーの説明を確認してみると、
追加で人間の顔画像を渡す必要がありそうです。
リクエストを完了するには、人物の顔が写っているソース画像を追加する必要があることを示すエラーです。
解決策
Iなどの人間に関連する表現を取り除く- 該当の文字列を消す
- 別の表現に置き換える
ImagePlaygroundConceptに人物画像を付け加える
人物画像をコンセプトに付け加えるのが一番単純ですが、すべてのユーザーが顔写真を設定したいわけではないです。そこで人間に関連する表現を取り除く方針で解決案を深掘りました。
Foundation Models
ここでFoundation Models フレームワークの出番です。
このフレームワークを使用することで、Appleが提供するオンデバイスLLMへアクセスできます。指示で役割を決め、プロンプトを入力すると、実行結果を受け取ることができます。
今回は入力値から人間に関連する表現を取り除くため、別の表現に置き換えるを試します。
以下は、日記の内容を絵文字に置き換える指示を与えた一例です。
LanguageModelSessionに指示を与えて、入力値をプロンプトとしてrespond(to:)の引数に渡して実行しています。
func removeHumanSubject(from text: String) async throws -> String {
let session = LanguageModelSession(instructions: """
You are a text rewriter. Given a journal entry,
rewrite it as a short emoji description \
that captures the mood and theme,
but remove all references to people,
humans, faces, or person identity.
Focus on objects, animals, nature, food,
activities, and emotions.
Reply with only the rewritten description, nothing else.
""")
let response = try await session.respond(to: text)
return response.content
}
また、このrespond(to:)メソッドは、generatingを引数を設定することでレスポンスとして生成される値を制御することができます。
generatingに渡す値はGenerableマクロを付けたstruct、もしくenumあれば、その形式で結果を出力させることができます。
func convertToEmojis(from text: String) async throws -> [String] {
// ...省略
let response = try await session.respond(
to: text,
generating: ExpressiveEmojis.self
)
return response.content.emojis
}
@Generable
struct ExpressiveEmojis {
@Guide(description: "A list of emojis without any text", .count(6))
let emojis: [String]
}
また、今回の例のようにGuideマクロをつけることで生成される値に影響を与えることができます。今回はテキストなしの絵文字の配列で個数は6個といったガイドを付けています。
ただし、これは出力される値を完全に強制できるものではなく、少なからず出力値に影響を与えることができるくらいの温度感でいた方が良さそうです。
このFoundation Modelsを活用した方法を用いることで、以下のようなパイプラインが実現可能です。
- User Input: ユーザー入力を受け取る
- Foundation Models: ユーザー入力値を画像生成しやすいような表現に変換する
- ImageCreator: 受け取った画像生成用の文字列から画像を生成する
例
Foundation Modelsを用いたパイプラインで試した一例ですが、下記のような結果になりました。
- User Input:
Feeling so nervous about my upcoming talk at try! Swift Tokyo - Foundation Models:
😬📣🐦💻🌍📺に変換 - ImageCreator: 以下の画像に変換

ちなみに、ジェン文字生成の場合にImageCreatorが受け取ったコンセプトが😬📣🐦💻🌍📺のような絵文字の場合に生成されるジェン文字は絵文字同士を合体させるような挙動になることがわかりました。
おまけ
これまでの説明で、どんな文字列からもジェン文字が生成することができることが分かりました。
もっとジェン文字の知名度を向上させるには、ジェン文字が人々の生活に溶け込む必要があります。
そこで思いついたひとつのアイデアを紹介します。
ユーザーの日々のできごとを取得する
Journaling Suggestionsフレームワークを使用することで、Apple純正のジャーナルアプリで表示されるようなJournalingSuggestionsPickerという機能を使用することができます。
このPickerには、訪れた場所や交流した人物、写真、聴いている曲など、ユーザーの人生で起こった個人的な出来事が表示されます。
PickerからはJournalingSuggestion.ItemContentという形で受け取ることができます。

例
以下の例では、JournalingSuggestionPickerからワークアウトに関する情報を受け取った場合のジェン文字生成フローです。
JournalingSuggestion.Workout.Detailsからはワークアウトの詳細の情報を取得できます。
struct SampleView: View {
@State private var genmojiImage: CGImage?
var body: some View {
VStack {
// result of Genmoji
if let genmojiImage {
Image(uiImage: UIImage(cgImage: genmojiImage))
}
// Button for JournalingSuggestionPicker
JournalingSuggestionsPicker {
Text("Show JournalingSuggestions")
} onCompletion: { @MainActor suggestion in
do {
let snapshot = await WorkoutSnapshot(suggestion: suggestion)
for name in snapshot.workoutNames {
let convertedEmojis = try await convertEmojis(from: "\(name) 頑張ったぞ")
let concept = convertedEmojis.joined()
try await generateGenmoji(from: concept)
}
} catch {
print(error)
}
}
}
}
func convertEmojis(from text: String) async throws -> [String] {
let session = LanguageModelSession()
let response = try await session.respond(
to: text,
generating: ExpressiveEmojis.self
)
return response.content.emojis
}
func generateGenmoji(from concept: String) async throws {
let creator = try await ImageCreator()
guard let emojiStyle = creator.availableStyles.first(where: { $0.id == "emoji" })
else { fatalError() }
let resultImages = creator.images(for: [.text(concept)], style: emojiStyle, limit: 1)
for try await image in resultImages {
// 生成されたGenmoji
self.genmojiImage = image.cgImage
}
}
}
@Generable
struct ExpressiveEmojis {
@Guide(description: "A list of emojis without any text", .count(3))
let emojis: [String]
}
struct WorkoutSnapshot {
let workoutNames: [String]
init(suggestion: sending JournalingSuggestion) async {
let workouts = await suggestion.content(forType: JournalingSuggestion.Workout.self)
self.workoutNames = workouts.compactMap {
$0.details?.localizedName ?? "No title"
}
}
}
まとめ
引き続き、ジェン文字をたくさんの人に使っていただけるように精進していきたいと思います。

おわりに
今年もtry! Swift Tokyo ではたくさんの人と交流し、刺激的な日々を過ごせました。
海外のエンジニアとの交流が日本でできる希少な機会です。
改めて、主催、運営、スピーカー、スポンサー、参加された皆さま、素敵な空間をありがとうございました!











