# Shared Image Plugin - Pre-Implementation Decision Checklist

**Date:** 2025-12-03  
**Status:** Pre-Implementation Planning  
**Purpose:** Identify and document decisions needed before implementing SharedImagePlugin

## ✅ Completed Decisions

### 1. Minimum OS Versions
- ✅ **iOS**: Keep at 13.0 (no changes needed)
- ✅ **Android**: Upgraded from API 22 to API 23 (completed)
- ✅ **Rationale**: Meets Capacitor 6 requirements, minimal device impact

### 2. Data Storage Strategy
- ✅ **iOS**: Use App Group UserDefaults (already implemented in Share Extension)
- ✅ **Android**: Use SharedPreferences (to be implemented)
- ✅ **Rationale**: Direct, efficient, no file I/O needed

## 🔍 Decisions Needed Before Implementation

### 1. Plugin Method Design

#### Decision: What methods should the plugin expose?

**Options:**
- **Option A (Minimal)**: Only `getSharedImage()` - read and clear in one call
- **Option B (Recommended)**: `getSharedImage()` + `hasSharedImage()` - allows checking without reading
- **Option C (Extended)**: Add `clearSharedImage()` - explicit clearing without reading

**Recommendation:** **Option B**
- `getSharedImage()`: Returns `{ base64: string, fileName: string } | null`
- `hasSharedImage()`: Returns `{ hasImage: boolean }` - useful for quick checks

**Decision Needed:** ✅ Confirm Option B or choose alternative

---

### 2. Error Handling Strategy

#### Decision: How should the plugin handle errors?

**Options:**
- **Option A**: Return `null` for all errors (no shared image = no error)
- **Option B**: Use `call.reject()` for actual errors, return `null` only when no image exists
- **Option C**: Return error object in result: `{ error: string } | { base64: string, fileName: string }`

**Recommendation:** **Option B**
- `getSharedImage()` returns `null` when no image exists (normal case)
- `call.reject()` for actual errors (UserDefaults unavailable, data corruption, etc.)
- Clear distinction between "no data" (normal) vs "error" (exceptional)

**Decision Needed:** ✅ Confirm Option B or choose alternative

---

### 3. Data Clearing Strategy

#### Decision: When should shared image data be cleared?

**Current Behavior (temp file approach):**
- Data cleared after reading (immediate)

**Options:**
- **Option A**: Clear immediately after reading (current behavior)
- **Option B**: Clear on next read (allow re-reading until consumed)
- **Option C**: Clear after successful storage in temp DB (JS confirms receipt)

**Recommendation:** **Option A** (immediate clearing)
- Prevents accidental re-reading
- Simpler implementation
- Matches current behavior
- If JS fails to store, user can share again

**Decision Needed:** ✅ Confirm Option A or choose alternative

---

### 4. iOS Plugin Registration

#### Decision: How should the iOS plugin be registered?

**Options:**
- **Option A**: Auto-discovery (Capacitor finds plugins by naming convention)
- **Option B**: Manual registration in AppDelegate
- **Option C**: Hybrid (auto-discovery with manual registration as fallback)

**Recommendation:** **Option A** (auto-discovery)
- Follows Capacitor best practices
- Less code to maintain
- Other plugins in project use auto-discovery (SafeAreaPlugin uses manual, but that's older pattern)

**Note:** Need to verify plugin naming convention:
- Class name: `SharedImagePlugin`
- File name: `SharedImagePlugin.swift`
- Location: `ios/App/App/SharedImagePlugin.swift`

**Decision Needed:** ✅ Confirm Option A, or if auto-discovery doesn't work, use Option B

---

### 5. TypeScript Interface Design

#### Decision: What should the TypeScript interface look like?

**Proposed Interface:**
```typescript
export interface SharedImageResult {
  base64: string;
  fileName: string;
}

export interface SharedImagePlugin {
  getSharedImage(): Promise<SharedImageResult | null>;
  hasSharedImage(): Promise<{ hasImage: boolean }>;
}
```

**Questions:**
- Should `fileName` be optional? (Currently always provided, but could be empty string)
- Should we include metadata (image size, MIME type)?
- Should `hasSharedImage()` return more info (like fileName without reading)?

**Recommendation:** Keep simple for now:
- `fileName` is always a string (may be default "shared-image.jpg")
- No metadata initially (can add later if needed)
- `hasSharedImage()` only returns boolean (keep it lightweight)

**Decision Needed:** ✅ Confirm interface design or request changes

---

### 6. Android Data Storage Timing

#### Decision: When should Android store shared image data in SharedPreferences?

**Current Flow:**
1. Share intent received in MainActivity
2. Image processed and written to temp file
3. JS reads temp file

**New Flow Options:**
- **Option A**: Store in SharedPreferences immediately when share intent received (in `processSharedImage()`)
- **Option B**: Store when plugin is first called (lazy loading)
- **Option C**: Store in both places during transition (backward compatibility)

**Recommendation:** **Option A** (immediate storage)
- Data available immediately when plugin is called
- No timing issues
- Matches iOS pattern (data stored by Share Extension)

**Implementation:**
- Update `processSharedImage()` in MainActivity to store in SharedPreferences
- Remove temp file writing
- Plugin reads from SharedPreferences

**Decision Needed:** ✅ Confirm Option A

---

### 7. Migration Strategy

#### Decision: How to handle the transition from temp file to plugin?

**Options:**
- **Option A (Clean Break)**: Remove temp file code immediately, use plugin only
- **Option B (Gradual)**: Support both approaches temporarily, remove temp file later
- **Option C (Feature Flag)**: Use feature flag to switch between approaches

**Recommendation:** **Option A** (clean break)
- Simpler implementation
- Less code to maintain
- Temp file approach is buggy anyway (why we're replacing it)
- Can rollback via git if needed

**Rollback Plan:**
- Keep temp file code in git history
- If plugin has issues, can revert commit
- Test thoroughly before removing temp file code

**Decision Needed:** ✅ Confirm Option A

---

### 8. Plugin Naming

#### Decision: What should the plugin be named?

**Options:**
- **Option A**: `SharedImage` (matches file/class names)
- **Option B**: `SharedImagePlugin` (more explicit)
- **Option C**: `NativeShare` (more generic, could handle other share types)

**Recommendation:** **Option A** (`SharedImage`)
- Matches Capacitor naming conventions (plugins are referenced without "Plugin" suffix)
- Examples: `Capacitor.Plugins.Camera`, `Capacitor.Plugins.Filesystem`
- TypeScript: `SharedImage.getSharedImage()`

**Decision Needed:** ✅ Confirm Option A

---

### 9. iOS: Reuse getSharedImageData() or Move to Plugin?

#### Decision: Should the plugin reuse AppDelegate's `getSharedImageData()` or implement its own?

**Current Code:**
- `AppDelegate.getSharedImageData()` exists and works
- Reads from App Group UserDefaults
- Clears data after reading

**Options:**
- **Option A**: Plugin calls `getSharedImageData()` from AppDelegate
- **Option B**: Plugin implements its own logic (duplicate code)
- **Option C**: Move `getSharedImageData()` to a shared utility, both use it

**Recommendation:** **Option C** (shared utility)
- DRY principle
- Single source of truth
- But: May be overkill for simple logic

**Alternative Recommendation:** **Option B** (plugin implements own logic)
- Plugin is self-contained
- No dependency on AppDelegate
- Logic is simple (just UserDefaults read/clear)
- Can remove `getSharedImageData()` from AppDelegate after migration

**Decision:** ✅ **Option C** (shared utility) - **CONFIRMED**
- Create shared utility for reading from App Group UserDefaults
- Both AppDelegate and plugin use the shared utility
- Single source of truth for shared image data access

---

### 10. Android: SharedPreferences Key Names

#### Decision: What keys should be used in SharedPreferences?

**Proposed Keys:**
- `shared_image_base64` - Base64 string
- `shared_image_file_name` - File name
- `shared_image_ready` - Boolean flag (optional, for quick checks)

**Alternative:**
- Use a single JSON object: `shared_image_data` = `{ base64: "...", fileName: "..." }`

**Recommendation:** Separate keys (first option)
- Simpler to read/write
- No JSON parsing needed
- Matches iOS pattern (separate UserDefaults keys)
- Flag is optional but useful for `hasSharedImage()`

**Decision Needed:** ✅ Confirm key naming or request changes

---

### 11. Testing Strategy

#### Decision: What testing approach should we use?

**Options:**
- **Option A**: Manual testing only
- **Option B**: Manual + automated unit tests for plugin methods
- **Option C**: Manual + integration tests

**Recommendation:** **Option A** (manual testing) for now
- Plugins are hard to unit test (require native environment)
- Manual testing is sufficient for initial implementation
- Can add automated tests later if needed

**Test Scenarios:**
1. Share image from Photos app → Verify appears in app
2. Share while app backgrounded → Verify appears when app becomes active
3. Share while app closed → Verify appears on app launch
4. Multiple rapid shares → Verify only latest is processed
5. Share then close app before processing → Verify data persists
6. Share then clear app data → Verify graceful handling

**Decision Needed:** ✅ Confirm testing approach

---

### 12. Documentation Updates

#### Decision: What documentation needs updating?

**Files to Update:**
- ✅ Implementation plan (this document)
- ⚠️ `doc/native-share-target-implementation.md` - Update to reflect plugin approach
- ⚠️ `doc/ios-share-implementation-status.md` - Mark plugin as implemented
- ⚠️ Code comments in `main.capacitor.ts` - Update to reflect plugin usage

**Decision Needed:** ✅ Confirm documentation update list

---

## Summary of Decisions Needed

| # | Decision | Recommendation | Status |
|---|----------|----------------|--------|
| 1 | Plugin Methods | Option B: `getSharedImage()` + `hasSharedImage()` | ✅ Confirmed |
| 2 | Error Handling | Option B: `null` for no data, `reject()` for errors | ✅ Confirmed |
| 3 | Data Clearing | Option A: Clear immediately after reading | ✅ Confirmed |
| 4 | iOS Registration | Option A: Auto-discovery | ✅ Confirmed |
| 5 | TypeScript Interface | Proposed interface (see above) | ✅ Confirmed |
| 6 | Android Storage Timing | Option A: Store immediately on share intent | ✅ Confirmed |
| 7 | Migration Strategy | Option A: Clean break, remove temp file code | ✅ Confirmed |
| 8 | Plugin Naming | Option A: `SharedImage` | ✅ Confirmed |
| 9 | iOS Code Reuse | Option C: Shared utility | ✅ Confirmed |
| 10 | Android Key Names | Separate keys: `shared_image_base64`, `shared_image_file_name` | ✅ Confirmed |
| 11 | Testing Strategy | Option A: Manual testing | ✅ Confirmed |
| 12 | Documentation | Update listed files | ✅ Confirmed |
| - | Multiple Images | Single image only (SharedPhotoView requirement) | ✅ Confirmed |
| - | Backward Compatibility | No temp file backward compatibility | ✅ Confirmed |

## Next Steps

1. **Review this checklist** and confirm or modify recommendations
2. **Make decisions** on all pending items
3. **Update implementation plan** with confirmed decisions
4. **Begin implementation** with clear specifications

## Questions to Consider

- Are there any edge cases not covered?
- Should we support multiple images (currently only first image)?
- Should we add image metadata (size, MIME type) in the future?
- Do we need backward compatibility with temp file approach?
- Should plugin methods be synchronous or async? (Capacitor plugins are async by default)

