@leejungkiin/awkit 1.4.3 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -14
- package/bin/awk.js +438 -86
- package/bin/claude-generators.js +3 -1
- package/bin/cline-generators.js +3 -1
- package/bin/codex-generators.js +7 -2
- package/core/orchestrator.md +17 -3
- package/core/skill-runtime-manifest.json +37 -0
- package/package.json +2 -2
- package/skill-packs/creator-studio/README.md +19 -0
- package/skill-packs/creator-studio/pack.json +10 -0
- package/skill-packs/marketing/README.md +64 -0
- package/skill-packs/marketing/pack.json +37 -0
- package/skill-packs/mobile-android/README.md +16 -0
- package/skill-packs/mobile-android/pack.json +10 -0
- package/skill-packs/mobile-ios/README.md +22 -0
- package/skill-packs/mobile-ios/pack.json +16 -0
- package/skill-packs/neural-memory/pack.json +8 -2
- package/skill-packs/superpowers/pack.json +1 -0
- package/skill-packs/superpowers/skills/single-flow-task-execution/SKILL.md +59 -358
- package/skill-packs/superpowers/skills/writing-skills/SKILL.md +60 -654
- package/skill-packs/superpowers/skills/writing-skills/examples/anti-rationalization.md +75 -0
- package/skill-packs/superpowers/skills/writing-skills/examples/cso-optimization.md +67 -0
- package/skill-packs/superpowers/skills/writing-skills/examples/tdd-for-skills.md +63 -0
- package/skills/CATALOG.md +49 -44
- package/skills/brainstorm-agent/SKILL.md +55 -315
- package/skills/brainstorm-agent/templates/brief-template.md +76 -0
- package/skills/codex-conductor/SKILL.md +55 -259
- package/skills/codex-conductor/examples/prompt-templates.md +72 -0
- package/skills/module-spec-writer/SKILL.md +38 -365
- package/skills/module-spec-writer/examples/port-migration-mode.md +40 -0
- package/skills/module-spec-writer/templates/module-spec-template.md +118 -0
- package/skills/orchestrator/SKILL.md +17 -8
- package/skills/single-flow-task-execution/SKILL.md +56 -363
- package/skills/single-flow-task-execution/examples/workflow-example.md +91 -0
- package/skills/smali-to-kotlin/SKILL.md +23 -416
- package/skills/smali-to-kotlin/examples/getting-started/tech-stack.md +58 -0
- package/skills/smali-to-kotlin/examples/pipeline/data-ui-parity.md +118 -0
- package/skills/smali-to-kotlin/examples/pipeline/scanner-and-bootstrap.md +106 -0
- package/skills/smali-to-swift/SKILL.md +18 -621
- package/skills/smali-to-swift/examples/getting-started/tech-stack.md +72 -0
- package/skills/smali-to-swift/examples/getting-started/toolchain.md +32 -0
- package/skills/smali-to-swift/examples/pipeline/core-logic.md +45 -0
- package/skills/smali-to-swift/examples/pipeline/data-layer.md +76 -0
- package/skills/smali-to-swift/examples/pipeline/framework-scanner.md +73 -0
- package/skills/smali-to-swift/examples/pipeline/project-bootstrap.md +76 -0
- package/skills/smali-to-swift/examples/pipeline/sdk-integration.md +66 -0
- package/skills/smali-to-swift/examples/pipeline/ui-viewmodel.md +96 -0
- package/skills/smali-to-swift/references/objc-to-swift-mapping.md +57 -0
- package/skills/spec-gate/SKILL.md +51 -265
- package/skills/spec-gate/templates/design-templates.md +93 -0
- package/skills/symphony-enforcer/SKILL.md +24 -555
- package/skills/symphony-enforcer/examples/startup-protocol.md +92 -0
- package/skills/symphony-enforcer/examples/task-completion.md +100 -0
- package/skills/symphony-enforcer/examples/three-phase.md +107 -0
- package/skills/symphony-enforcer/examples/trigger-points.md +99 -0
- package/skills/symphony-orchestrator/SKILL.md +1 -1
- package/skills/writing-skills/SKILL.md +82 -70
- package/skills/writing-skills/examples/anti-rationalization.md +53 -0
- package/skills/writing-skills/examples/cso-optimization.md +52 -0
- package/skills/writing-skills/examples/tdd-for-skills.md +48 -0
- package/templates/help.html +447 -0
- package/skills/memory-sync/SKILL.md +0 -424
- package/skills/memory-sync/memory-router.md +0 -185
- package/skills/memory-sync/memory-templates.md +0 -201
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Modern Tech Stack (Mandatory)
|
|
2
|
+
|
|
3
|
+
## Core
|
|
4
|
+
|
|
5
|
+
| Layer | Technology | Replaces |
|
|
6
|
+
|-------|-----------|----------|
|
|
7
|
+
| **UI** | SwiftUI + iOS 17+ | UIKit Storyboards / XIBs |
|
|
8
|
+
| **State** | `@Observable` (Observation framework) | `@ObservableObject` / KVO |
|
|
9
|
+
| **Navigation** | NavigationStack + NavigationPath | UINavigationController / segues |
|
|
10
|
+
| **DI** | Swift DI (protocol + init injection) | Singletons / Service Locators |
|
|
11
|
+
|
|
12
|
+
## Data Layer
|
|
13
|
+
|
|
14
|
+
| Purpose | Technology | Replaces |
|
|
15
|
+
|---------|-----------|----------|
|
|
16
|
+
| **Network** | URLSession + async/await | AFNetworking / Alamofire (evaluate) |
|
|
17
|
+
| **JSON** | Codable (Swift built-in) | NSJSONSerialization / Mantle / ObjectMapper |
|
|
18
|
+
| **Local DB** | SwiftData (iOS 17+) or Core Data | Raw SQLite / FMDB / Realm |
|
|
19
|
+
| **Preferences** | UserDefaults / @AppStorage | NSUserDefaults direct |
|
|
20
|
+
| **Keychain** | KeychainAccess (or custom wrapper) | Raw Security.framework |
|
|
21
|
+
| **Image Loading** | AsyncImage / Kingfisher / Nuke | SDWebImage (evaluate) |
|
|
22
|
+
| **Async** | Swift Concurrency (async/await, actors) | GCD / NSOperation / PromiseKit |
|
|
23
|
+
|
|
24
|
+
## Observability
|
|
25
|
+
|
|
26
|
+
| Purpose | Technology |
|
|
27
|
+
|---------|-----------|
|
|
28
|
+
| **Crash** | Firebase Crashlytics |
|
|
29
|
+
| **Analytics** | Firebase Analytics |
|
|
30
|
+
| **Logging** | OSLog / swift-log |
|
|
31
|
+
|
|
32
|
+
## Replacements Table (Legacy → Modern)
|
|
33
|
+
|
|
34
|
+
```yaml
|
|
35
|
+
always_replace:
|
|
36
|
+
NSURLConnection: "URLSession async/await"
|
|
37
|
+
AFNetworking: "URLSession async/await"
|
|
38
|
+
NSJSONSerialization: "Codable / JSONDecoder"
|
|
39
|
+
Mantle/ObjectMapper: "Codable"
|
|
40
|
+
GCD_dispatch_async: "Task { } / async-await"
|
|
41
|
+
NSOperation: "TaskGroup / async let"
|
|
42
|
+
NSTimer: "Timer.publish (Combine) or Task.sleep"
|
|
43
|
+
UIAlertView: "SwiftUI .alert modifier"
|
|
44
|
+
UIActionSheet: "SwiftUI .confirmationDialog"
|
|
45
|
+
UITableView: "List / LazyVStack"
|
|
46
|
+
UICollectionView: "LazyVGrid / LazyHGrid"
|
|
47
|
+
UIPageViewController: "TabView with .page style"
|
|
48
|
+
Storyboard_segues: "NavigationStack + NavigationLink"
|
|
49
|
+
NSNotificationCenter_addObserver: "NotificationCenter.notifications (AsyncSequence)"
|
|
50
|
+
KVO: "@Observable macro"
|
|
51
|
+
Delegate_patterns: "AsyncStream or closures"
|
|
52
|
+
Target_Action: "SwiftUI action closures"
|
|
53
|
+
|
|
54
|
+
evaluate_before_replacing:
|
|
55
|
+
Alamofire: "Keep if deeply used for interceptors/retry, otherwise → URLSession"
|
|
56
|
+
SDWebImage: "Replace with AsyncImage + Kingfisher"
|
|
57
|
+
Realm: "Migrate to SwiftData (if iOS 17+)"
|
|
58
|
+
RxSwift: "Migrate to async/await + AsyncSequence (gradual)"
|
|
59
|
+
SnapKit: "Replace with SwiftUI layout"
|
|
60
|
+
Masonry: "Replace with SwiftUI layout"
|
|
61
|
+
MBProgressHUD: "SwiftUI .overlay + ProgressView"
|
|
62
|
+
SVProgressHUD: "SwiftUI .overlay + ProgressView"
|
|
63
|
+
IQKeyboardManager: "SwiftUI handles keyboard automatically"
|
|
64
|
+
|
|
65
|
+
keep_as_is:
|
|
66
|
+
- "Firebase SDKs (use latest via SPM)"
|
|
67
|
+
- "Google Sign-In"
|
|
68
|
+
- "Facebook SDK (latest)"
|
|
69
|
+
- "Apple frameworks (MapKit, CoreLocation, AVFoundation, etc.)"
|
|
70
|
+
- "Native C/C++ libraries (.dylib)"
|
|
71
|
+
- "CryptoKit (Apple native)"
|
|
72
|
+
```
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# iOS RE Toolchain
|
|
2
|
+
|
|
3
|
+
## Decryption & Extraction
|
|
4
|
+
|
|
5
|
+
| Tool | Purpose | Output |
|
|
6
|
+
|------|---------|--------|
|
|
7
|
+
| **frida-ios-dump** / **bagbak** | Decrypt IPA from jailbroken device | Decrypted .app bundle |
|
|
8
|
+
| **class-dump** / **class-dump-swift** | Extract ObjC/Swift headers | `.h` header files |
|
|
9
|
+
| **Hopper Disassembler** | ARM disassembly + pseudo-code | Pseudo-C / ARM ASM |
|
|
10
|
+
| **IDA Pro** | Advanced disassembly | Pseudo-C / ARM ASM |
|
|
11
|
+
| **jtool2** | Mach-O analysis, entitlements | Entitlements plist, segments |
|
|
12
|
+
| **plutil / plistutil** | Read binary plists | Readable plist XML |
|
|
13
|
+
|
|
14
|
+
## What we get from an IPA
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
Payload/App.app/
|
|
18
|
+
├── App # Mach-O binary (encrypted → need decrypt first)
|
|
19
|
+
├── Info.plist # App metadata (bundle ID, permissions, URL schemes)
|
|
20
|
+
├── Frameworks/ # Embedded frameworks (.framework / .dylib)
|
|
21
|
+
│ ├── SomeSDK.framework/
|
|
22
|
+
│ └── libswiftCore.dylib
|
|
23
|
+
├── Assets.car # Compiled asset catalog
|
|
24
|
+
├── Base.lproj/ # Storyboards / XIBs (compiled)
|
|
25
|
+
│ ├── Main.storyboardc/
|
|
26
|
+
│ └── LaunchScreen.storyboardc/
|
|
27
|
+
├── *.nib # Compiled XIB files
|
|
28
|
+
├── *.momd # Core Data models (compiled)
|
|
29
|
+
├── embedded.mobileprovision # Provisioning profile
|
|
30
|
+
├── _CodeSignature/ # Code signing
|
|
31
|
+
└── [other resources: json, png, html, js, fonts...]
|
|
32
|
+
```
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Step 3: Core Logic & Utils Reconstruction 🧮
|
|
2
|
+
|
|
3
|
+
**Input:** Disassembly/pseudo-code for encryption, hashing, custom utils.
|
|
4
|
+
|
|
5
|
+
## Tasks
|
|
6
|
+
|
|
7
|
+
### 1. Translate ObjC/C crypto logic → Swift
|
|
8
|
+
|
|
9
|
+
Use `CryptoKit` for modern crypto (SHA256, AES-GCM, HMAC).
|
|
10
|
+
Use `CommonCrypto` for legacy-compatible (MD5, AES-CBC).
|
|
11
|
+
Preserve exact input/output signatures.
|
|
12
|
+
|
|
13
|
+
### 2. Common ObjC → Swift crypto patterns
|
|
14
|
+
|
|
15
|
+
```objc
|
|
16
|
+
// ObjC (class-dump + disassembly)
|
|
17
|
+
+ (NSString *)md5Hash:(NSString *)input;
|
|
18
|
+
+ (NSData *)aesEncrypt:(NSData *)data withKey:(NSString *)key;
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
```swift
|
|
22
|
+
// Swift
|
|
23
|
+
import CryptoKit
|
|
24
|
+
import CommonCrypto
|
|
25
|
+
|
|
26
|
+
enum CryptoUtils {
|
|
27
|
+
static func md5Hash(_ input: String) -> String {
|
|
28
|
+
let data = Data(input.utf8)
|
|
29
|
+
var digest = [UInt8](repeating: 0, count: Int(CC_MD5_DIGEST_LENGTH))
|
|
30
|
+
data.withUnsafeBytes { CC_MD5($0.baseAddress, CC_LONG(data.count), &digest) }
|
|
31
|
+
return digest.map { String(format: "%02x", $0) }.joined()
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
static func aesEncrypt(data: Data, key: String) throws -> Data {
|
|
35
|
+
// Implement matching original algorithm exactly
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### 3. Verification
|
|
41
|
+
|
|
42
|
+
XCTest unit tests with known input/output pairs.
|
|
43
|
+
|
|
44
|
+
> ⚠️ **Critical Rule:** Crypto/hash functions MUST produce identical output to the original app.
|
|
45
|
+
> Test with known pairs captured from the running original app.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Step 2: Data Layer Reconstruction 💾
|
|
2
|
+
|
|
3
|
+
**Input:** User provides class-dump headers + Hopper pseudo-code for network/data classes.
|
|
4
|
+
|
|
5
|
+
## Tasks
|
|
6
|
+
|
|
7
|
+
### 1. Models: Convert ObjC interfaces → Swift structs
|
|
8
|
+
|
|
9
|
+
```objc
|
|
10
|
+
// ObjC header (class-dump)
|
|
11
|
+
@interface UserModel : NSObject
|
|
12
|
+
@property (nonatomic, copy) NSString *userId;
|
|
13
|
+
@property (nonatomic, copy) NSString *fullName;
|
|
14
|
+
@property (nonatomic, assign) NSInteger age;
|
|
15
|
+
@end
|
|
16
|
+
```
|
|
17
|
+
```swift
|
|
18
|
+
// Swift
|
|
19
|
+
struct User: Codable, Identifiable {
|
|
20
|
+
let id: String
|
|
21
|
+
let fullName: String
|
|
22
|
+
let age: Int
|
|
23
|
+
|
|
24
|
+
enum CodingKeys: String, CodingKey {
|
|
25
|
+
case id = "user_id"
|
|
26
|
+
case fullName = "full_name"
|
|
27
|
+
case age
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### 2. API Layer
|
|
33
|
+
|
|
34
|
+
Extract base URL, endpoints, headers from disassembly. Create async URLSession-based API client:
|
|
35
|
+
|
|
36
|
+
```swift
|
|
37
|
+
actor APIClient {
|
|
38
|
+
private let session: URLSession
|
|
39
|
+
private let baseURL: URL
|
|
40
|
+
|
|
41
|
+
func request<T: Decodable>(_ endpoint: Endpoint) async throws -> T {
|
|
42
|
+
let (data, response) = try await session.data(for: endpoint.urlRequest(baseURL: baseURL))
|
|
43
|
+
guard let httpResponse = response as? HTTPURLResponse,
|
|
44
|
+
(200...299).contains(httpResponse.statusCode) else {
|
|
45
|
+
throw APIError.invalidResponse
|
|
46
|
+
}
|
|
47
|
+
return try JSONDecoder().decode(T.self, from: data)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### 3. Local Storage
|
|
53
|
+
|
|
54
|
+
- CoreData models → SwiftData `@Model` classes
|
|
55
|
+
- NSUserDefaults keys → `@AppStorage` or typed UserDefaults wrapper
|
|
56
|
+
- Keychain items → KeychainAccess wrapper
|
|
57
|
+
|
|
58
|
+
### 4. Repository Pattern
|
|
59
|
+
|
|
60
|
+
```swift
|
|
61
|
+
// Domain layer - protocol
|
|
62
|
+
protocol UserRepository: Sendable {
|
|
63
|
+
func getUser(id: String) async throws -> User
|
|
64
|
+
func login(email: String, password: String) async throws -> AuthToken
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Data layer - implementation
|
|
68
|
+
final class UserRepositoryImpl: UserRepository {
|
|
69
|
+
private let apiClient: APIClient
|
|
70
|
+
private let modelContext: ModelContext
|
|
71
|
+
|
|
72
|
+
func getUser(id: String) async throws -> User {
|
|
73
|
+
// offline-first: check local → fetch remote → cache
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Step 0: Framework Scanner (PRE-STEP — Always First) 🔍
|
|
2
|
+
|
|
3
|
+
**Purpose:** Scan the IPA structure to identify all third-party frameworks before any coding.
|
|
4
|
+
|
|
5
|
+
## Process
|
|
6
|
+
|
|
7
|
+
1. **Scan `Frameworks/` directory:**
|
|
8
|
+
```
|
|
9
|
+
Frameworks/Alamofire.framework → Alamofire (network)
|
|
10
|
+
Frameworks/SDWebImage.framework → SDWebImage (image loading)
|
|
11
|
+
Frameworks/Realm.framework → Realm (database)
|
|
12
|
+
Frameworks/FBSDKCoreKit.framework → Facebook SDK
|
|
13
|
+
Frameworks/GoogleSignIn.framework → Google Sign-In
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
2. **Scan class-dump headers for imports:**
|
|
17
|
+
```
|
|
18
|
+
#import <AFNetworking/...> → AFNetworking
|
|
19
|
+
#import <Masonry/...> → Masonry (auto-layout)
|
|
20
|
+
#import <MBProgressHUD/...> → MBProgressHUD
|
|
21
|
+
@import Firebase; → Firebase SDK
|
|
22
|
+
@import GoogleMobileAds; → AdMob
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
3. **Check Mach-O linked frameworks:**
|
|
26
|
+
```bash
|
|
27
|
+
otool -L Payload/App.app/App | grep -v /System | grep -v /usr/lib
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
4. **Check embedded dylibs:**
|
|
31
|
+
```bash
|
|
32
|
+
find Payload/App.app -name "*.dylib" -o -name "*.framework" | sort
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
5. **Check for CocoaPods / SPM markers:**
|
|
36
|
+
```
|
|
37
|
+
Pods/ directory presence → was using CocoaPods
|
|
38
|
+
.package.resolved → was using SPM
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
6. **Output: Framework Detection Report**
|
|
42
|
+
```markdown
|
|
43
|
+
## 📦 Framework Detection Report
|
|
44
|
+
|
|
45
|
+
### ✅ Can Reuse (add to Package.swift / Podfile)
|
|
46
|
+
| Framework | Detected | Latest Version | Action |
|
|
47
|
+
|-----------|----------|----------------|--------|
|
|
48
|
+
| Alamofire | Frameworks/Alamofire.framework | 5.9.0 | Evaluate |
|
|
49
|
+
| Kingfisher | (header import) | 7.12.0 | Add via SPM |
|
|
50
|
+
|
|
51
|
+
### 🔄 Must Replace (legacy)
|
|
52
|
+
| Old Framework | Detected | Modern Replacement |
|
|
53
|
+
|---------------|----------|-------------------|
|
|
54
|
+
| AFNetworking | Frameworks/AFNetworking.framework | URLSession async/await |
|
|
55
|
+
| Masonry | header imports | SwiftUI layout |
|
|
56
|
+
|
|
57
|
+
### 🍏 Apple Frameworks Used
|
|
58
|
+
| Framework | Purpose |
|
|
59
|
+
|-----------|---------|
|
|
60
|
+
| MapKit | Maps |
|
|
61
|
+
| CoreLocation | GPS |
|
|
62
|
+
| AVFoundation | Camera/Audio |
|
|
63
|
+
|
|
64
|
+
### 📱 Native (.dylib) — Investigate
|
|
65
|
+
| File | Notes |
|
|
66
|
+
|------|-------|
|
|
67
|
+
| libcrypto.dylib | Custom crypto? |
|
|
68
|
+
|
|
69
|
+
### ❓ Unknown (investigate)
|
|
70
|
+
| Framework/Import | Notes |
|
|
71
|
+
|------------------|-------|
|
|
72
|
+
| CustomSDK.framework | Proprietary? |
|
|
73
|
+
```
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Step 1: Info.plist & Entitlements Analysis + Project Bootstrap 📄
|
|
2
|
+
|
|
3
|
+
**Input:** User provides `Info.plist` + entitlements from IPA.
|
|
4
|
+
|
|
5
|
+
## Tasks
|
|
6
|
+
|
|
7
|
+
1. Extract Bundle ID and display name
|
|
8
|
+
2. List required permissions (Privacy keys):
|
|
9
|
+
```
|
|
10
|
+
NSCameraUsageDescription → Camera
|
|
11
|
+
NSPhotoLibraryUsageDescription → Photo Library
|
|
12
|
+
NSLocationWhenInUseUsageDescription → Location
|
|
13
|
+
NSMicrophoneUsageDescription → Microphone
|
|
14
|
+
```
|
|
15
|
+
3. Identify URL Schemes (deep links)
|
|
16
|
+
4. Check app capabilities from entitlements:
|
|
17
|
+
```
|
|
18
|
+
com.apple.developer.associated-domains → Universal Links
|
|
19
|
+
aps-environment → Push Notifications
|
|
20
|
+
com.apple.developer.in-app-payments → Apple Pay
|
|
21
|
+
```
|
|
22
|
+
5. Analyze class-dump headers for entry points:
|
|
23
|
+
- `AppDelegate` → lifecycle logic
|
|
24
|
+
- Root ViewController → initial screen
|
|
25
|
+
- Tab bar / Navigation structure
|
|
26
|
+
6. **Output:** Propose Clean Architecture project structure
|
|
27
|
+
|
|
28
|
+
## Project Structure Template
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
App/
|
|
32
|
+
├── App.swift # @main entry point
|
|
33
|
+
├── AppDelegate.swift # UIKit lifecycle (if needed for SDKs)
|
|
34
|
+
├── Info.plist
|
|
35
|
+
├── Assets.xcassets/
|
|
36
|
+
├── DI/ # Dependency Injection
|
|
37
|
+
│ └── AppContainer.swift
|
|
38
|
+
├── Data/ # Data Layer
|
|
39
|
+
│ ├── Network/
|
|
40
|
+
│ │ ├── APIClient.swift # URLSession wrapper
|
|
41
|
+
│ │ ├── Endpoints/ # API endpoint definitions
|
|
42
|
+
│ │ └── DTOs/ # Codable response models
|
|
43
|
+
│ ├── Local/
|
|
44
|
+
│ │ ├── SwiftDataModels/ # @Model classes
|
|
45
|
+
│ │ ├── KeychainService.swift
|
|
46
|
+
│ │ └── UserDefaultsKeys.swift
|
|
47
|
+
│ └── Repositories/ # Repository implementations
|
|
48
|
+
├── Domain/ # Domain Layer
|
|
49
|
+
│ ├── Models/ # Business models
|
|
50
|
+
│ ├── Repositories/ # Repository protocols
|
|
51
|
+
│ └── UseCases/
|
|
52
|
+
├── Presentation/ # Presentation Layer
|
|
53
|
+
│ ├── Navigation/
|
|
54
|
+
│ │ ├── AppNavigation.swift # NavigationStack + routes
|
|
55
|
+
│ │ └── Route.swift # Deep link routes
|
|
56
|
+
│ ├── Theme/
|
|
57
|
+
│ │ ├── AppTheme.swift # Colors, fonts, spacing
|
|
58
|
+
│ │ └── Components/ # Reusable SwiftUI components
|
|
59
|
+
│ └── Screens/
|
|
60
|
+
│ ├── Launch/
|
|
61
|
+
│ │ └── LaunchScreen.swift
|
|
62
|
+
│ ├── Auth/
|
|
63
|
+
│ │ ├── LoginScreen.swift
|
|
64
|
+
│ │ └── LoginViewModel.swift
|
|
65
|
+
│ ├── Home/
|
|
66
|
+
│ │ ├── HomeScreen.swift
|
|
67
|
+
│ │ └── HomeViewModel.swift
|
|
68
|
+
│ └── ...
|
|
69
|
+
├── Utilities/
|
|
70
|
+
│ ├── Extensions/
|
|
71
|
+
│ ├── Crypto/ # Encryption/hashing utils
|
|
72
|
+
│ └── Helpers/
|
|
73
|
+
└── Resources/
|
|
74
|
+
├── Localizable.xcstrings
|
|
75
|
+
└── Fonts/
|
|
76
|
+
```
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Step 5: Third-party SDK & Native Library Integration 📦
|
|
2
|
+
|
|
3
|
+
**Input:** Framework Report from Step 0.
|
|
4
|
+
|
|
5
|
+
## Tasks
|
|
6
|
+
|
|
7
|
+
### 1. Swift Package Manager setup
|
|
8
|
+
|
|
9
|
+
```swift
|
|
10
|
+
// Package.swift dependencies (or Xcode SPM UI)
|
|
11
|
+
dependencies: [
|
|
12
|
+
.package(url: "https://github.com/firebase/firebase-ios-sdk", from: "11.0.0"),
|
|
13
|
+
.package(url: "https://github.com/onevcat/Kingfisher", from: "7.12.0"),
|
|
14
|
+
.package(url: "https://github.com/kishikawakatsumi/KeychainAccess", from: "4.2.2"),
|
|
15
|
+
]
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### 2. Native C/C++ libraries
|
|
19
|
+
|
|
20
|
+
```swift
|
|
21
|
+
// Bridging header for C libraries
|
|
22
|
+
// App-Bridging-Header.h
|
|
23
|
+
#include "native_crypto.h"
|
|
24
|
+
|
|
25
|
+
// Swift usage
|
|
26
|
+
func callNativeFunction() -> String {
|
|
27
|
+
let result = native_function_name(param)
|
|
28
|
+
return String(cString: result)
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### 3. App lifecycle for SDK init
|
|
33
|
+
|
|
34
|
+
```swift
|
|
35
|
+
@main
|
|
36
|
+
struct MyApp: App {
|
|
37
|
+
@UIApplicationDelegateAdaptor private var appDelegate: AppDelegate
|
|
38
|
+
|
|
39
|
+
var body: some Scene {
|
|
40
|
+
WindowGroup {
|
|
41
|
+
ContentView()
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
class AppDelegate: NSObject, UIApplicationDelegate {
|
|
47
|
+
func application(_ application: UIApplication,
|
|
48
|
+
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
|
49
|
+
FirebaseApp.configure()
|
|
50
|
+
// Other SDK initialization
|
|
51
|
+
return true
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Step 6: Parity Check & Quality Gate ✅
|
|
57
|
+
|
|
58
|
+
**Per-module checklist:**
|
|
59
|
+
1. **Branch Coverage:** Review all conditional paths from disassembly
|
|
60
|
+
2. **API Parity:** Same requests/responses as original
|
|
61
|
+
3. **Data Parity:** Crypto output matches, local storage compatible
|
|
62
|
+
4. **UI Parity:** Screen-by-screen comparison
|
|
63
|
+
5. **Performance:**
|
|
64
|
+
- Instruments profiling
|
|
65
|
+
- No unnecessary @State re-renders
|
|
66
|
+
- Proper actor isolation (no data races)
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Step 4: UI & ViewModel Reconstruction (Per Screen) 🎨
|
|
2
|
+
|
|
3
|
+
**Input:** Storyboard analysis + class-dump headers for ViewControllers.
|
|
4
|
+
|
|
5
|
+
## Tasks
|
|
6
|
+
|
|
7
|
+
### 1. Resource Extraction (On-Demand)
|
|
8
|
+
|
|
9
|
+
- Extract only images, colors, strings for current screen
|
|
10
|
+
- Use Asset Catalog for organized resources
|
|
11
|
+
- Map ObjC string tables to `Localizable.xcstrings`
|
|
12
|
+
|
|
13
|
+
### 2. UIKit → SwiftUI Migration
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
UIViewController → SwiftUI View struct
|
|
17
|
+
UINavigationController → NavigationStack
|
|
18
|
+
UITabBarController → TabView
|
|
19
|
+
UITableView → List / LazyVStack
|
|
20
|
+
UICollectionView → LazyVGrid / LazyHGrid
|
|
21
|
+
UIScrollView → ScrollView
|
|
22
|
+
UIImageView → AsyncImage / Image
|
|
23
|
+
UILabel → Text
|
|
24
|
+
UITextField → TextField
|
|
25
|
+
UIButton → Button
|
|
26
|
+
UIActivityIndicatorView → ProgressView
|
|
27
|
+
UIAlertController → .alert / .confirmationDialog modifier
|
|
28
|
+
UIPageViewController → TabView(.page)
|
|
29
|
+
UIStackView → VStack / HStack
|
|
30
|
+
MKMapView → Map (MapKit SwiftUI)
|
|
31
|
+
WKWebView → WebView (custom wrapper)
|
|
32
|
+
UIRefreshControl → .refreshable modifier
|
|
33
|
+
UISearchController → .searchable modifier
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### 3. ViewModel Creation
|
|
37
|
+
|
|
38
|
+
```swift
|
|
39
|
+
@Observable
|
|
40
|
+
final class LoginViewModel {
|
|
41
|
+
var email = ""
|
|
42
|
+
var password = ""
|
|
43
|
+
var isLoading = false
|
|
44
|
+
var error: String?
|
|
45
|
+
|
|
46
|
+
private let loginUseCase: LoginUseCase
|
|
47
|
+
|
|
48
|
+
init(loginUseCase: LoginUseCase) {
|
|
49
|
+
self.loginUseCase = loginUseCase
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
func login() async {
|
|
53
|
+
isLoading = true
|
|
54
|
+
defer { isLoading = false }
|
|
55
|
+
do {
|
|
56
|
+
try await loginUseCase.execute(email: email, password: password)
|
|
57
|
+
} catch {
|
|
58
|
+
self.error = error.localizedDescription
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 4. Screen Composable
|
|
65
|
+
|
|
66
|
+
```swift
|
|
67
|
+
struct LoginScreen: View {
|
|
68
|
+
@State private var viewModel: LoginViewModel
|
|
69
|
+
|
|
70
|
+
init(loginUseCase: LoginUseCase) {
|
|
71
|
+
_viewModel = State(initialValue: LoginViewModel(loginUseCase: loginUseCase))
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
var body: some View {
|
|
75
|
+
Form {
|
|
76
|
+
TextField("Email", text: $viewModel.email)
|
|
77
|
+
.textContentType(.emailAddress)
|
|
78
|
+
.keyboardType(.emailAddress)
|
|
79
|
+
|
|
80
|
+
SecureField("Password", text: $viewModel.password)
|
|
81
|
+
.textContentType(.password)
|
|
82
|
+
|
|
83
|
+
Button("Login") {
|
|
84
|
+
Task { await viewModel.login() }
|
|
85
|
+
}
|
|
86
|
+
.disabled(viewModel.isLoading)
|
|
87
|
+
}
|
|
88
|
+
.overlay { if viewModel.isLoading { ProgressView() } }
|
|
89
|
+
.alert("Error", isPresented: .constant(viewModel.error != nil)) {
|
|
90
|
+
Button("OK") { viewModel.error = nil }
|
|
91
|
+
} message: {
|
|
92
|
+
Text(viewModel.error ?? "")
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
```
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# ObjC → Swift Type Mapping Reference
|
|
2
|
+
|
|
3
|
+
## Property Types → Swift
|
|
4
|
+
|
|
5
|
+
```objc
|
|
6
|
+
@property (nonatomic, copy) NSString *name; // → let name: String
|
|
7
|
+
@property (nonatomic, strong) NSArray *items; // → let items: [Any] (refine type)
|
|
8
|
+
@property (nonatomic, assign) BOOL isActive; // → let isActive: Bool
|
|
9
|
+
@property (nonatomic, assign) NSInteger count; // → let count: Int
|
|
10
|
+
@property (nonatomic, assign) CGFloat height; // → let height: CGFloat
|
|
11
|
+
@property (nonatomic, strong) NSDictionary *meta; // → let meta: [String: Any]
|
|
12
|
+
@property (nonatomic, strong) NSDate *createdAt; // → let createdAt: Date
|
|
13
|
+
@property (nonatomic, strong) NSURL *imageURL; // → let imageURL: URL?
|
|
14
|
+
@property (nonatomic, strong) NSData *data; // → let data: Data
|
|
15
|
+
@property (nullable, nonatomic, copy) NSString *bio; // → let bio: String?
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Method Signatures → Swift
|
|
19
|
+
|
|
20
|
+
```objc
|
|
21
|
+
- (void)fetchUserWithId:(NSString *)userId completion:(void (^)(UserModel *, NSError *))completion;
|
|
22
|
+
// → func fetchUser(id: String) async throws -> User
|
|
23
|
+
|
|
24
|
+
+ (instancetype)sharedInstance;
|
|
25
|
+
// → static let shared = ClassName()
|
|
26
|
+
|
|
27
|
+
- (BOOL)validateEmail:(NSString *)email;
|
|
28
|
+
// → func validateEmail(_ email: String) -> Bool
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Delegate Patterns → Swift
|
|
32
|
+
|
|
33
|
+
```objc
|
|
34
|
+
@protocol UserServiceDelegate <NSObject>
|
|
35
|
+
- (void)userServiceDidFetchUser:(UserModel *)user;
|
|
36
|
+
- (void)userServiceDidFailWithError:(NSError *)error;
|
|
37
|
+
@end
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
```swift
|
|
41
|
+
// Replace with async/await:
|
|
42
|
+
func fetchUser() async throws -> User
|
|
43
|
+
// Or AsyncStream for multiple values:
|
|
44
|
+
func userUpdates() -> AsyncStream<User>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Blocks → Closures / async
|
|
48
|
+
|
|
49
|
+
```objc
|
|
50
|
+
typedef void (^CompletionHandler)(NSData * _Nullable data, NSError * _Nullable error);
|
|
51
|
+
- (void)requestWithCompletion:(CompletionHandler)completion;
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
```swift
|
|
55
|
+
// Modern Swift: drop the callback, use async
|
|
56
|
+
func request() async throws -> Data
|
|
57
|
+
```
|