[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6KCJPGE3WA5H2ASZ6EGHF4K":3,"skill-same:01M6KCJPGE3WA5H2ASZ6EGHF4K":83},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":28,"publishedAt":49,"linkOnly":50,"markdownContent":51,"markdownBody":52,"frontMatter":53,"refName":60,"commitSha":61,"skillDirectory":62,"forksCount":63,"repositoryHtmlUrl":64,"repositoryHomepageUrl":6,"ownerHtmlUrl":65,"ownerBlogUrl":66,"ownerDescription":67,"updatedAt":68,"install":69,"resources":82},"01M6KCJPGE3WA5H2ASZ6EGHF4K","mobiai-review-code",null,"Use when reviewing mobile code changes — check for lifecycle issues, memory leaks, thread safety, and platform-specific pitfalls.","ArisGuimera\u002FMobiAI-Core","ArisGuimera","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F16361358?v=4","01M6KC5MVGRKDA14DWT98445V9","AristiDevs","01M6KC5MZKRFFHFFD340B21YN3",492,"MIT","https:\u002F\u002Fgithub.com\u002FArisGuimera\u002FMobiAI-Core\u002Fblob\u002Fmain\u002Fskills\u002Fcore\u002Fskills\u002Fmobiai-review-code\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000009","前端开发","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":26,"taxonomyTypeDesc":27},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48],"review code","mobiai review code","review","code","react","copilot","memory","issues","ios","lifecycle","codex","flutter","check","use","platform","native","for","thread","changes","android","2026-11-10 10:12:30",false,"---\nname: mobiai-review-code\ndescription: Use when reviewing mobile code changes — check for lifecycle issues, memory leaks, thread safety, and platform-specific pitfalls.\nlicense: MIT\ncompatibility: [claude-code, cursor, copilot, codex]\nplatforms: [android, ios, kmp, flutter, react-native]\n---\n\n# Review Code\n\nPerform a mobile-specific code review, checking for common issues that static analysis tools miss.\n\n## When to Use\n\n- User asks for a code review of mobile code changes\n- After applying a fix, to self-review before creating a PR\n- User shares a diff or PR and asks for feedback\n\n## Pre-flight: check the Graph for code structure\n\nThe Graph indexes Kotlin\u002FSwift symbols across the repo, so callers of any symbol modified in the diff can be located instantly. Used during Step 3 (Review Checklist) and Step 4 (Verify Test Coverage) to detect call sites and tests that the diff may have missed.\n\n**If `\u003Crepo>\u002F.mobiai\u002Fgraph\u002Findex.json` exists**:\n\n```bash\n# Freshness — if \"hace Xd\" with X ≥ 1, suggest refresh (don't auto-run):\nmobiai graph status\n\n# For each symbol modified\u002Frenamed in the diff, find callers outside the diff:\nmobiai graph callers \u003CSymbolFromDiff>\n\n# If a symbol was renamed or removed, search for stale references:\nmobiai graph search \u003COldSymbolName>\n```\n\nThe callers list surfaces call sites that the diff may not have updated — a common source of silent breakage when the PR is partial.\n\nIf the index is ≥1 day old:\n\n> \"El índice del Graph es de hace Xd. Si la rama tiene cambios recientes, considerá `mobiai graph init` antes de revisar.\"\n\nDon't run `init` autonomously.\n\n**If `.mobiai\u002Fgraph\u002Findex.json` does not exist** and the project has `.kt` or `.swift` files:\n\n> \"No veo el índice del Graph. Generalo con `mobiai graph init` para que pueda detectar callers fuera del diff.\"\n\nDon't run `init` autonomously.\n\n**Skip silently when**:\n\n- The project has no Kotlin\u002FSwift files (Flutter or RN-only).\n- The diff is purely a config \u002F resource \u002F build-file change.\n\n## Workflow\n\n### Step 1: Identify the Correct Base Branch\n\n\u003CSTOP>\nYou MUST complete this step before reading ANY code or generating ANY diff.\nDo NOT skip this. Do NOT assume `main` or `master`. Get the real target branch first.\n\u003C\u002FSTOP>\n\nDetermine the target branch this change will be merged into:\n\n1. **If reviewing a PR**: `gh pr view --json baseRefName --jq '.baseRefName'` — this is the authoritative answer\n2. **If the user mentioned a branch**: use that branch\n3. **If no PR and no branch mentioned**: ask the user \"What branch is this being merged into?\"\n4. **Only as absolute last resort**: default to the repo's default branch via `gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name'`\n\nThen generate the diff against that branch:\n```bash\nBASE_BRANCH=\"\u003Cthe branch from above>\"\ngit diff \"$BASE_BRANCH\"...HEAD\n```\n\n**Why this matters**: If you diff against the wrong branch, you'll report hundreds of false changes that belong to the base branch, not to this PR. The user will see a noisy, useless review.\n\n### Step 2: Understand the Change\n\n1. Read the diff against the correct base branch (from Step 1)\n2. Understand the intent — what problem does this solve?\n3. Check the related issue\u002Fticket for context\n\n### Step 3: Review Checklist\n\n#### Universal Checks\n- [ ] **Minimal change**: Does the diff only contain what's necessary?\n- [ ] **No unrelated changes**: No formatting, renaming, or refactoring mixed in?\n- [ ] **Error handling**: Are errors handled appropriately (not swallowed silently)?\n- [ ] **Thread safety**: Is shared mutable state properly synchronized?\n- [ ] **Null safety**: Are nullable values handled correctly?\n- [ ] **Edge cases**: Empty collections, null inputs, boundary values?\n\n#### Android-Specific\n- [ ] **Lifecycle awareness**: Are observers\u002Flisteners registered and unregistered properly?\n- [ ] **Memory leaks**: No Activity\u002FFragment\u002FContext references held in long-lived objects?\n- [ ] **Main thread**: No blocking operations (network, disk I\u002FO) on the main thread?\n- [ ] **Configuration changes**: Does the code survive rotation\u002Fdark mode changes?\n- [ ] **ProGuard\u002FR8**: Are keep rules needed for reflection or serialization?\n- [ ] **Backward compatibility**: Uses `@RequiresApi` or checks `Build.VERSION.SDK_INT`?\n\n#### iOS-Specific\n- [ ] **Retain cycles**: No strong reference cycles in closures? Using `[weak self]` where needed?\n- [ ] **Main thread UI**: All UI updates on the main thread?\n- [ ] **Optional handling**: No force unwraps (`!`) on values that could be nil?\n- [ ] **Memory**: No large allocations in tight loops?\n- [ ] **App lifecycle**: Handles `sceneDidEnterBackground` \u002F `applicationWillTerminate`?\n\n#### Flutter-Specific\n- [ ] **Widget rebuilds**: No expensive operations in `build()` methods?\n- [ ] **State management**: Proper use of the chosen state management solution?\n- [ ] **Platform channels**: Error handling for platform-specific calls?\n- [ ] **Dispose**: Controllers, streams, subscriptions disposed properly?\n\n#### React Native-Specific\n- [ ] **Re-renders**: Proper use of `useMemo`, `useCallback`, `React.memo`?\n- [ ] **Native bridges**: Error handling for native module calls?\n- [ ] **Navigation**: Proper cleanup in `useEffect` return?\n- [ ] **Platform-specific code**: `Platform.OS` checks where needed?\n\n### Step 4: Verify Test Coverage\n\nCheck if the changed code has tests. This is a separate step — do not skip it.\n\n1. Look at the diff: identify new logic, bug fixes, or behavior changes\n2. Search for existing tests related to the modified files:\n   - Android: look for test classes in `src\u002Ftest\u002F` or `src\u002FandroidTest\u002F` that test the same classes\n   - iOS: look for test files in the test target that cover the same types\n   - Flutter: look for `_test.dart` files matching the changed files\n   - React Native: look for `.test.js` \u002F `.test.tsx` files\n3. If there are NO tests for the changed code, report it as a **blocking issue** in your review:\n   - \"No unit tests found for [changed class\u002Ffunction]. This [bug fix \u002F new logic \u002F behavior change] should have test coverage.\"\n4. If tests exist but don't cover the new changes, flag it as a suggestion\n\nAlways include a \"Test coverage\" section in your review output, even if tests are present. State what you found.\n\n### Step 5: Provide Feedback\n\nStructure your review as:\n\n1. **Summary**: One-line assessment (looks good \u002F needs changes \u002F has issues)\n2. **Issues found**: Specific problems with file paths and line numbers\n3. **Suggestions**: Optional improvements (clearly marked as non-blocking)\n\n## Handling User Feedback on Your Review\n\nWhen the user responds to your review:\n\n- **Simple edits** (README, changelog, docs, test adjustments) → make the change directly\n- **Code changes in the app** → re-analyze with their feedback as context, apply the fix\n- **Questions** → answer with specific code references\n- **Approval** → done\n","# Review Code\n\nPerform a mobile-specific code review, checking for common issues that static analysis tools miss.\n\n## When to Use\n\n- User asks for a code review of mobile code changes\n- After applying a fix, to self-review before creating a PR\n- User shares a diff or PR and asks for feedback\n\n## Pre-flight: check the Graph for code structure\n\nThe Graph indexes Kotlin\u002FSwift symbols across the repo, so callers of any symbol modified in the diff can be located instantly. Used during Step 3 (Review Checklist) and Step 4 (Verify Test Coverage) to detect call sites and tests that the diff may have missed.\n\n**If `\u003Crepo>\u002F.mobiai\u002Fgraph\u002Findex.json` exists**:\n\n```bash\n# Freshness — if \"hace Xd\" with X ≥ 1, suggest refresh (don't auto-run):\nmobiai graph status\n\n# For each symbol modified\u002Frenamed in the diff, find callers outside the diff:\nmobiai graph callers \u003CSymbolFromDiff>\n\n# If a symbol was renamed or removed, search for stale references:\nmobiai graph search \u003COldSymbolName>\n```\n\nThe callers list surfaces call sites that the diff may not have updated — a common source of silent breakage when the PR is partial.\n\nIf the index is ≥1 day old:\n\n> \"El índice del Graph es de hace Xd. Si la rama tiene cambios recientes, considerá `mobiai graph init` antes de revisar.\"\n\nDon't run `init` autonomously.\n\n**If `.mobiai\u002Fgraph\u002Findex.json` does not exist** and the project has `.kt` or `.swift` files:\n\n> \"No veo el índice del Graph. Generalo con `mobiai graph init` para que pueda detectar callers fuera del diff.\"\n\nDon't run `init` autonomously.\n\n**Skip silently when**:\n\n- The project has no Kotlin\u002FSwift files (Flutter or RN-only).\n- The diff is purely a config \u002F resource \u002F build-file change.\n\n## Workflow\n\n### Step 1: Identify the Correct Base Branch\n\n\u003CSTOP>\nYou MUST complete this step before reading ANY code or generating ANY diff.\nDo NOT skip this. Do NOT assume `main` or `master`. Get the real target branch first.\n\u003C\u002FSTOP>\n\nDetermine the target branch this change will be merged into:\n\n1. **If reviewing a PR**: `gh pr view --json baseRefName --jq '.baseRefName'` — this is the authoritative answer\n2. **If the user mentioned a branch**: use that branch\n3. **If no PR and no branch mentioned**: ask the user \"What branch is this being merged into?\"\n4. **Only as absolute last resort**: default to the repo's default branch via `gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name'`\n\nThen generate the diff against that branch:\n```bash\nBASE_BRANCH=\"\u003Cthe branch from above>\"\ngit diff \"$BASE_BRANCH\"...HEAD\n```\n\n**Why this matters**: If you diff against the wrong branch, you'll report hundreds of false changes that belong to the base branch, not to this PR. The user will see a noisy, useless review.\n\n### Step 2: Understand the Change\n\n1. Read the diff against the correct base branch (from Step 1)\n2. Understand the intent — what problem does this solve?\n3. Check the related issue\u002Fticket for context\n\n### Step 3: Review Checklist\n\n#### Universal Checks\n- [ ] **Minimal change**: Does the diff only contain what's necessary?\n- [ ] **No unrelated changes**: No formatting, renaming, or refactoring mixed in?\n- [ ] **Error handling**: Are errors handled appropriately (not swallowed silently)?\n- [ ] **Thread safety**: Is shared mutable state properly synchronized?\n- [ ] **Null safety**: Are nullable values handled correctly?\n- [ ] **Edge cases**: Empty collections, null inputs, boundary values?\n\n#### Android-Specific\n- [ ] **Lifecycle awareness**: Are observers\u002Flisteners registered and unregistered properly?\n- [ ] **Memory leaks**: No Activity\u002FFragment\u002FContext references held in long-lived objects?\n- [ ] **Main thread**: No blocking operations (network, disk I\u002FO) on the main thread?\n- [ ] **Configuration changes**: Does the code survive rotation\u002Fdark mode changes?\n- [ ] **ProGuard\u002FR8**: Are keep rules needed for reflection or serialization?\n- [ ] **Backward compatibility**: Uses `@RequiresApi` or checks `Build.VERSION.SDK_INT`?\n\n#### iOS-Specific\n- [ ] **Retain cycles**: No strong reference cycles in closures? Using `[weak self]` where needed?\n- [ ] **Main thread UI**: All UI updates on the main thread?\n- [ ] **Optional handling**: No force unwraps (`!`) on values that could be nil?\n- [ ] **Memory**: No large allocations in tight loops?\n- [ ] **App lifecycle**: Handles `sceneDidEnterBackground` \u002F `applicationWillTerminate`?\n\n#### Flutter-Specific\n- [ ] **Widget rebuilds**: No expensive operations in `build()` methods?\n- [ ] **State management**: Proper use of the chosen state management solution?\n- [ ] **Platform channels**: Error handling for platform-specific calls?\n- [ ] **Dispose**: Controllers, streams, subscriptions disposed properly?\n\n#### React Native-Specific\n- [ ] **Re-renders**: Proper use of `useMemo`, `useCallback`, `React.memo`?\n- [ ] **Native bridges**: Error handling for native module calls?\n- [ ] **Navigation**: Proper cleanup in `useEffect` return?\n- [ ] **Platform-specific code**: `Platform.OS` checks where needed?\n\n### Step 4: Verify Test Coverage\n\nCheck if the changed code has tests. This is a separate step — do not skip it.\n\n1. Look at the diff: identify new logic, bug fixes, or behavior changes\n2. Search for existing tests related to the modified files:\n   - Android: look for test classes in `src\u002Ftest\u002F` or `src\u002FandroidTest\u002F` that test the same classes\n   - iOS: look for test files in the test target that cover the same types\n   - Flutter: look for `_test.dart` files matching the changed files\n   - React Native: look for `.test.js` \u002F `.test.tsx` files\n3. If there are NO tests for the changed code, report it as a **blocking issue** in your review:\n   - \"No unit tests found for [changed class\u002Ffunction]. This [bug fix \u002F new logic \u002F behavior change] should have test coverage.\"\n4. If tests exist but don't cover the new changes, flag it as a suggestion\n\nAlways include a \"Test coverage\" section in your review output, even if tests are present. State what you found.\n\n### Step 5: Provide Feedback\n\nStructure your review as:\n\n1. **Summary**: One-line assessment (looks good \u002F needs changes \u002F has issues)\n2. **Issues found**: Specific problems with file paths and line numbers\n3. **Suggestions**: Optional improvements (clearly marked as non-blocking)\n\n## Handling User Feedback on Your Review\n\nWhen the user responds to your review:\n\n- **Simple edits** (README, changelog, docs, test adjustments) → make the change directly\n- **Code changes in the app** → re-analyze with their feedback as context, apply the fix\n- **Questions** → answer with specific code references\n- **Approval** → done\n",{"name":5,"license":15,"platforms":54,"description":7,"compatibility":57},[48,37,55,40,56],"kmp","react-native",[58,59,34,39],"claude-code","cursor","main","2edc6ac1cde2cc280ae0388aa8072902d2e230d5","skills\u002Fcore\u002Fskills\u002Fmobiai-review-code",14,"https:\u002F\u002Fgithub.com\u002FArisGuimera\u002FMobiAI-Core","https:\u002F\u002Fgithub.com\u002FArisGuimera","https:\u002F\u002Faristi.dev","⭐️ GitHub Star\r\n📲 Mobile developer\r\n🎥 Te enseño a programar apps en Youtube (AristiDevs)\r\n✍🏻 Y por escrito en CursoKotlin.com\r\n❤️ Kotlin Fanboy\r\n👇👇👇👇","2026-11-13 22:28:09",{"source":8,"skillName":5,"commands":70,"prompt":80,"zipAvailable":81},[71,74,77],{"tool":72,"command":73},"npx","npx skills add ArisGuimera\u002FMobiAI-Core --skill mobiai-review-code",{"tool":75,"command":76},"bunx","bunx skills add ArisGuimera\u002FMobiAI-Core --skill mobiai-review-code",{"tool":78,"command":79},"pnpm","pnpm dlx skills add ArisGuimera\u002FMobiAI-Core --skill mobiai-review-code","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FArisGuimera\u002FMobiAI-Core\u002Fblob\u002Fmain\u002Fskills\u002Fcore\u002Fskills\u002Fmobiai-review-code\u002FSKILL.md",true,[],[84,104,116,134,152,166],{"skillNo":85,"name":86,"nameZh":6,"description":87,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":88,"categories":89,"keywords":94,"publishedAt":49},"01M6KCMR2WVBEC7T0YY4J2SCAR","mobiai-react-native","Use when working on a React Native project — building, testing, debugging, understanding navigation and state management.","https:\u002F\u002Fgithub.com\u002FArisGuimera\u002FMobiAI-Core\u002Fblob\u002Fmain\u002Fskills\u002Freact-native\u002Fskills\u002Fmobiai-react-native\u002FSKILL.md",[90,93],{"categoryNo":91,"categoryName":92,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[33,95,44,96,97,39,34,98,99,32,100,101,59,42,102,56,58,103],"react native","mobiai react native","testing","debugging","state management","state","management","navigation","project",{"skillNo":105,"name":106,"nameZh":6,"description":107,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":108,"categories":109,"keywords":111,"publishedAt":49},"01M6KCMKFC3DKFW5B2208SM59W","mobiai-kmp","Use when working on a Kotlin Multiplatform project — shared code, expect\u002Factual declarations, platform-specific implementations, building and testing.","https:\u002F\u002Fgithub.com\u002FArisGuimera\u002FMobiAI-Core\u002Fblob\u002Fmain\u002Fskills\u002Fkmp\u002Fskills\u002Fmobiai-kmp\u002FSKILL.md",[110],{"categoryNo":91,"categoryName":92,"taxonomyType":21,"taxonomyTypeDesc":22},[112,97,39,34,32,113,114,59,42,58,115,103,43],"mobiai kmp","kotlin","kotlin multiplatform","shared",{"skillNo":117,"name":118,"nameZh":6,"description":119,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":120,"categories":121,"keywords":123,"publishedAt":49},"01M6KCMEC4YP1FFAX4ZX80Q10R","mobiai-ios-testing","Use when writing or running tests in an iOS project — unit tests, UI tests, snapshot tests, choosing the right framework.","https:\u002F\u002Fgithub.com\u002FArisGuimera\u002FMobiAI-Core\u002Fblob\u002Fmain\u002Fskills\u002Fios\u002Fskills\u002Fmobiai-ios-testing\u002FSKILL.md",[122],{"categoryNo":91,"categoryName":92,"taxonomyType":21,"taxonomyTypeDesc":22},[97,37,124,125,126,39,127,34,32,128,129,130,59,131,42,58,103,132,133],"ios testing","mobiai ios testing","writing","unit tests","framework","running tests","ui","snapshot","tests","unit",{"skillNo":135,"name":136,"nameZh":6,"description":137,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":138,"categories":139,"keywords":140,"publishedAt":49},"01M6KCM78C8P9R6X78EZCQ0YF9","mobiai-ios-device","Use when interacting with an iOS Simulator — run simctl commands, capture screenshots, read device logs, manage simulators.","https:\u002F\u002Fgithub.com\u002FArisGuimera\u002FMobiAI-Core\u002Fblob\u002Fmain\u002Fskills\u002Fios\u002Fskills\u002Fmobiai-ios-device\u002FSKILL.md",[],[37,141,142,143,39,34,144,32,145,146,147,59,42,148,149,58,150,151],"device","mobiai ios device","screenshots","run","logs","capture","read","manage","ios simulator","commands","with",{"skillNo":153,"name":154,"nameZh":6,"description":155,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":156,"categories":157,"keywords":158,"publishedAt":49},"01M6KCM2HE6Z1B7WREJ9DTKKWA","mobiai-ios-build","Use when building an iOS project, configuring schemes, troubleshooting build failures, or managing dependencies with CocoaPods or SPM.","https:\u002F\u002Fgithub.com\u002FArisGuimera\u002FMobiAI-Core\u002Fblob\u002Fmain\u002Fskills\u002Fios\u002Fskills\u002Fmobiai-ios-build\u002FSKILL.md",[],[37,159,160,161,39,34,32,162,59,42,163,58,103,151,164,165],"build","ios build","mobiai ios build","troubleshooting","dependencies","spm","cocoapods",{"skillNo":167,"name":168,"nameZh":6,"description":169,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":170,"categories":171,"keywords":172,"publishedAt":49},"01M6KCKWZNT8P6K5SYXE1YAT9E","mobiai-ios-architecture","Use when creating features, refactoring, or navigating an iOS codebase — understand project structure, find where to make changes, follow existing patterns.","https:\u002F\u002Fgithub.com\u002FArisGuimera\u002FMobiAI-Core\u002Fblob\u002Fmain\u002Fskills\u002Fios\u002Fskills\u002Fmobiai-ios-architecture\u002FSKILL.md",[],[173,37,174,175,39,176,34,32,177,178,59,42,179,180,103,181,47,182,183,184],"architecture","ios architecture","mobiai ios architecture","project structure","refactoring","find","patterns","structure","understand","codebase","Existing","features"]