00 Apple Code Signing, In Depth — A Series

Apple Code Signing, In Depth --- A Series

Where you are: the front door of an 8-part series on how Apple's developer program, signing certificates, and provisioning profiles fit together.

What you'll know after this file: the whole map, the reading order, and the one story (PawPal) that ties every article together.

Most developers meet Apple code signing as a wall of red errors in Xcode: "No profiles for 'com.x.y' were found" , "Provisioning profile doesn't include signing certificate" , "errSecInternalComponent" . They click Automatically manage signing, it works, and the system stays a black box until it breaks on CI at 2 a.m.

This series opens the box. It doesn't start from menus. It starts from the security problem Apple had to solve and works forward from there, so each piece looks like something you would have had to invent yourself.

The series

# Article Question it answers
1 Why code signing exists What breaks without it?
2 What Apple code signing is (and isn't) What exactly is this system, and where are its edges?
3 The concept map What are the pieces, and who does what?
4 The running example: shipping PawPal What does one real app's journey look like?
5.1 The Developer Account & Team Who is the root of identity?
5.2 Signing Certificates & Private Keys How does Apple vouch for you?
5.3 App IDs, Capabilities & Entitlements How does Apple vouch for what your app may do?
5.4 Registered Devices How does Apple limit where a non-store build may run?
5.5 Provisioning Profiles How are who / what / where bound into one signed permission slip?
5.6 codesign & the Signature Inside Your App What does a signature physically look like inside the binary?
5.7 On-Device Verification (installd, AMFI, the kernel) How does the iPhone decide to run your code?
5.8 Distribution & Apple Re-signing What changes for TestFlight, App Store, Ad Hoc, Enterprise, and macOS?
6 Full walkthrough: PawPal end to end Every step again, at full depth
7 Troubleshooting, CI & next steps How do I fix it when it breaks?

Reading order: go 1 → 6 straight through the first time. Each deep dive (5.x) also works on its own, because it recaps its role and ties back to the PawPal example.

The whole territory, in one picture

What are all the concepts and components, and how do they group?
#mermaid-svg-Ge7m4Ut9GLIS7hvD{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .error-icon{fill:#552222;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .marker.cross{stroke:#333333;}#mermaid-svg-Ge7m4Ut9GLIS7hvD svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Ge7m4Ut9GLIS7hvD p{margin:0;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge{stroke-width:3;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section--1 rect,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section--1 path,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section--1 circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section--1 polygon,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section--1 path{fill:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section--1 text{fill:#ffffff;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .node-icon--1{font-size:40px;color:#ffffff;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-edge--1{stroke:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-depth--1{stroke-width:17;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section--1 line{stroke:hsl(60, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:lightgray;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:#efefef;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-0 rect,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-0 path,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-0 circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-0 polygon,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-0 path{fill:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-0 text{fill:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .node-icon-0{font-size:40px;color:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-edge-0{stroke:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-depth-0{stroke-width:14;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-0 line{stroke:hsl(240, 100%, 83.5294117647%);stroke-width:3;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:lightgray;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:#efefef;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-1 rect,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-1 path,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-1 circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-1 polygon,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-1 path{fill:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-1 text{fill:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .node-icon-1{font-size:40px;color:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-edge-1{stroke:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-depth-1{stroke-width:11;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-1 line{stroke:hsl(260, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:lightgray;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:#efefef;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-2 rect,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-2 path,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-2 circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-2 polygon,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-2 path{fill:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-2 text{fill:#ffffff;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .node-icon-2{font-size:40px;color:#ffffff;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-edge-2{stroke:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-depth-2{stroke-width:8;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-2 line{stroke:hsl(90, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:lightgray;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:#efefef;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-3 rect,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-3 path,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-3 circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-3 polygon,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-3 path{fill:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-3 text{fill:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .node-icon-3{font-size:40px;color:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-edge-3{stroke:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-depth-3{stroke-width:5;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-3 line{stroke:hsl(120, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:lightgray;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:#efefef;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-4 rect,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-4 path,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-4 circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-4 polygon,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-4 path{fill:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-4 text{fill:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .node-icon-4{font-size:40px;color:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-edge-4{stroke:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-depth-4{stroke-width:2;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-4 line{stroke:hsl(150, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:lightgray;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:#efefef;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-5 rect,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-5 path,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-5 circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-5 polygon,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-5 path{fill:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-5 text{fill:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .node-icon-5{font-size:40px;color:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-edge-5{stroke:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-depth-5{stroke-width:-1;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-5 line{stroke:hsl(180, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:lightgray;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:#efefef;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-6 rect,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-6 path,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-6 circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-6 polygon,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-6 path{fill:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-6 text{fill:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .node-icon-6{font-size:40px;color:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-edge-6{stroke:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-depth-6{stroke-width:-4;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-6 line{stroke:hsl(210, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:lightgray;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:#efefef;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-7 rect,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-7 path,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-7 circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-7 polygon,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-7 path{fill:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-7 text{fill:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .node-icon-7{font-size:40px;color:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-edge-7{stroke:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-depth-7{stroke-width:-7;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-7 line{stroke:hsl(270, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:lightgray;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:#efefef;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-8 rect,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-8 path,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-8 circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-8 polygon,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-8 path{fill:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-8 text{fill:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .node-icon-8{font-size:40px;color:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-edge-8{stroke:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-depth-8{stroke-width:-10;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-8 line{stroke:hsl(330, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:lightgray;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:#efefef;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-9 rect,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-9 path,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-9 circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-9 polygon,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-9 path{fill:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-9 text{fill:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .node-icon-9{font-size:40px;color:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-edge-9{stroke:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-depth-9{stroke-width:-13;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-9 line{stroke:hsl(0, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:lightgray;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:#efefef;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-10 rect,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-10 path,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-10 circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-10 polygon,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-10 path{fill:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-10 text{fill:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .node-icon-10{font-size:40px;color:black;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-edge-10{stroke:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge-depth-10{stroke-width:-16;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-10 line{stroke:hsl(30, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:lightgray;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .disabled text{fill:#efefef;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-root rect,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-root path,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-root circle,#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-root polygon{fill:hsl(240, 100%, 46.2745098039%);}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-root text{fill:#ffffff;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-root span{color:#ffffff;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .section-2 span{color:#ffffff;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .icon-container{height:100%;display:flex;justify-content:center;align-items:center;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .edge{fill:none;}#mermaid-svg-Ge7m4Ut9GLIS7hvD .mindmap-node-label{dy:1em;alignment-baseline:middle;text-anchor:middle;dominant-baseline:middle;text-align:center;}#mermaid-svg-Ge7m4Ut9GLIS7hvD :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Apple Code Signing
Problem it solves
Who wrote this code?
Was it modified?
What is it allowed to do?
Where may it run?
Can Apple revoke it?
Core concepts
Team & Team ID
Key pair & Certificate
Certificate chain to Apple Root CA
App ID / Bundle ID
Entitlements & Capabilities
Device UDID
Provisioning Profile
Code Signature & cdhash
Key players
Apple Developer Portal
issues certs, App IDs, profiles
Developer Mac Keychain
holds private key
Xcode / codesign
seals the bundle
iOS installd
checks profile at install
AMFI + kernel
checks every page at runtime
App Store Connect
reviews & re-signs
Running example
Mia ships PawPal with push notifications
Debug on own iPhone
Ad Hoc to a tester
TestFlight then App Store
Key flows
Happy path: CSR to cert to profile to sign to install to run
Failure: device not in profile
Failure: entitlement mismatch
Failure: expired or revoked cert

The core idea in one paragraph

A signed iOS app makes three claims and has one permission slip that backs them. The claims: "I was built by this Team" (certificate), "I have not been changed since" (code signature hashes), and "I may use these powers" (entitlements). The permission slip is the provisioning profile , a plist that Apple signs and that says "this Team's certificates may sign this App ID, with these entitlements, to run on these devices, until this date." The device trusts Apple's root key and nothing else. So every claim has to trace back to something Apple signed.


Next → 01 --- Why code signing exists

相关推荐
传奇开心果编程12 小时前
【Flutter踩坑排雷】第25课:ScrollController 误用坑|跳转失效、监听泄漏与“控制器未附加”
android·flutter·ios·移动开发·跨平台·dart·声明式ui
90后的晨仔13 小时前
macOS 27 下两个 Xcode 坑:真机 DDI 错配与模拟器 App Translocation
ios
开心猴爷15 小时前
iOS 上架 App 流程
后端·ios
奶油话梅糖15 小时前
用 iPhone 扫一间房,AI 帮你在浏览器里 1:1 重建它:Wes Bos 的 scan-to-threejs 工作流
人工智能·ios·iphone
茶底世界之下1 天前
阴天窗边的柿子:用 Awaking 让暖色成为主角
ios·app·产品
kango2 天前
iOS 远程推送全链路拆解:从 deviceToken 到多账号绑定
ios·app
茶底世界之下2 天前
仙人掌与沙丘的傍晚:用 Awaking 让侧光有了层次
ios·app·产品
茶底世界之下3 天前
蓝调鱼市的一盏暖灯:用 Awaking 把冷海与灯光分开
ios·app·产品
茶底世界之下4 天前
窗边白雏菊与旧书:用 Awaking 留住一束暖光
ios·app·产品