11 KiB
11 KiB
KeySharing Component
The KeySharing component handles the distribution and sharing of license keys between users.
Pseudocode
class KeySharingManager {
private let keyManager = KeyManager.shared
private let pasteboard = UIPasteboard.general
// MARK: - Sharing Methods
enum SharingMethod {
case copy
case message
case email
case qrCode
case universalLink
}
func shareKey(_ key: String, via method: SharingMethod) -> SharingResult {
// Track sharing event
trackSharing(key: key, method: method)
switch method {
case .copy:
return copyToClipboard(key)
case .message:
return shareViaMessage(key)
case .email:
return shareViaEmail(key)
case .qrCode:
return generateQRCode(key)
case .universalLink:
return generateUniversalLink(key)
}
}
// MARK: - Copy to Clipboard
private func copyToClipboard(_ key: String) -> SharingResult {
let content = """
VoiceUwu Pro License Key:
\(key)
Activate in Settings → Keys for All
"""
pasteboard.string = content
return .success(message: "Key copied to clipboard!")
}
// MARK: - Message Sharing
private func shareViaMessage(_ key: String) -> SharingResult {
let messageContent = MessageContent(
recipients: [],
subject: "VoiceUwu Pro Key",
body: """
Hey! I'm sharing a VoiceUwu Pro key with you 🎁
Your license key: \(key)
To activate:
1. Open VoiceUwu
2. Go to Settings → Keys for All
3. Tap "Have a Key?" and paste this code
This unlocks advanced voice monitoring features!
Enjoy! 🎵
""",
attachments: []
)
MessageComposer.show(messageContent)
return .success(message: "Message composer opened")
}
// MARK: - Email Sharing
private func shareViaEmail(_ key: String) -> SharingResult {
let emailContent = EmailContent(
recipients: [],
subject: "Your VoiceUwu Pro License Key",
body: generateEmailBody(for: key),
isHTML: true
)
EmailComposer.show(emailContent)
return .success(message: "Email composer opened")
}
private func generateEmailBody(for key: String) -> String {
return """
<html>
<body style="font-family: -apple-system, sans-serif; padding: 20px;">
<h2>VoiceUwu Pro License Key</h2>
<p>You've been gifted a VoiceUwu Pro license! This unlocks advanced features for voice training and analysis.</p>
<div style="background-color: #f0f0f0; padding: 15px; border-radius: 8px; margin: 20px 0;">
<strong>Your License Key:</strong><br>
<code style="font-size: 18px; color: #007AFF;">\(key)</code>
</div>
<h3>How to Activate:</h3>
<ol>
<li>Open VoiceUwu on your iOS device</li>
<li>Navigate to Settings → Keys for All</li>
<li>Tap "Have a Key?"</li>
<li>Enter or paste the license key</li>
<li>Tap "Activate"</li>
</ol>
<h3>What You'll Unlock:</h3>
<ul>
<li>Advanced voice monitoring tools</li>
<li>Multiple visualization modes</li>
<li>Enhanced haptic feedback</li>
<li>Professional analysis features</li>
</ul>
<p style="color: #666; font-size: 14px; margin-top: 30px;">
This key can only be used once. If you have any issues, please contact support.
</p>
</body>
</html>
"""
}
// MARK: - QR Code Generation
private func generateQRCode(_ key: String) -> SharingResult {
let qrData = QRCodeData(
type: .licenseKey,
content: key,
metadata: [
"app": "VoiceUwu",
"version": "1.0",
"level": extractLevel(from: key)
]
)
guard let qrImage = QRCodeGenerator.generate(qrData) else {
return .failure(error: .qrGenerationFailed)
}
let qrView = QRCodeShareView(image: qrImage, key: key)
ShareSheet.present(qrView)
return .success(message: "QR code generated")
}
// MARK: - Universal Link
private func generateUniversalLink(_ key: String) -> SharingResult {
// Create shareable link
let baseURL = "https://voiceuwu.app/activate"
let encodedKey = key.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? ""
let link = "\(baseURL)?key=\(encodedKey)"
// Create share content
let shareContent = ShareContent(
text: "Here's your VoiceUwu Pro license key!",
url: URL(string: link),
title: "VoiceUwu Pro License"
)
ShareSheet.present(shareContent)
return .success(message: "Share sheet presented")
}
// MARK: - Tracking
private func trackSharing(key: String, method: SharingMethod) {
let event = SharingEvent(
keyHash: hashKey(key),
method: method,
timestamp: Date()
)
// Store in history
var history = loadSharingHistory()
history.append(event)
saveSharingHistory(history)
// Remove from inventory if sharing from inventory
if let index = keyManager.keyInventory.firstIndex(of: key) {
keyManager.shareKey(at: index)
}
}
}
// MARK: - UI Components
struct KeySharingView: View {
@StateObject private var keyManager = KeyManager.shared
@State private var selectedKey: String?
@State private var sharingMethod: KeySharingManager.SharingMethod = .copy
var body: some View {
VStack(spacing: 20) {
// Inventory status
if keyManager.keyInventory.isEmpty {
EmptyInventoryView()
} else {
// Key selection
GroupBox {
VStack(alignment: .leading, spacing: 12) {
Label("Select Key to Share", systemImage: "key.fill")
.font(.headline)
ForEach(keyManager.keyInventory, id: \.self) { key in
KeySelectionRow(
key: key,
isSelected: selectedKey == key,
onSelect: { selectedKey = key }
)
}
}
}
// Sharing method selection
GroupBox {
VStack(alignment: .leading, spacing: 12) {
Label("Sharing Method", systemImage: "square.and.arrow.up")
.font(.headline)
ForEach(sharingMethods, id: \.method) { option in
SharingMethodRow(
option: option,
isSelected: sharingMethod == option.method,
onSelect: { sharingMethod = option.method }
)
}
}
}
// Share button
Button(action: shareSelectedKey) {
Label("Share Key", systemImage: "paperplane.fill")
}
.buttonStyle(PrimaryButtonStyle())
.disabled(selectedKey == nil)
}
}
.padding()
}
private var sharingMethods: [SharingOption] {
[
SharingOption(method: .copy, title: "Copy to Clipboard", icon: "doc.on.doc"),
SharingOption(method: .message, title: "Send Message", icon: "message"),
SharingOption(method: .email, title: "Send Email", icon: "envelope"),
SharingOption(method: .qrCode, title: "Generate QR Code", icon: "qrcode"),
SharingOption(method: .universalLink, title: "Share Link", icon: "link")
]
}
private func shareSelectedKey() {
guard let key = selectedKey else { return }
let result = KeySharingManager().shareKey(key, via: sharingMethod)
switch result {
case .success(let message):
showToast(message)
selectedKey = nil // Reset selection
case .failure(let error):
showError(error)
}
}
}
// MARK: - QR Code View
struct QRCodeShareView: View {
let image: UIImage
let key: String
@State private var showingKey = false
var body: some View {
VStack(spacing: 20) {
Text("Scan to Activate")
.font(.title2)
.fontWeight(.semibold)
Image(uiImage: image)
.resizable()
.interpolation(.none)
.scaledToFit()
.frame(width: 250, height: 250)
.cornerRadius(12)
Text("VoiceUwu Pro License")
.font(.headline)
if showingKey {
Text(key)
.font(.system(.caption, design: .monospaced))
.foregroundColor(.secondary)
}
Button(showingKey ? "Hide Key" : "Show Key") {
showingKey.toggle()
}
.font(.caption)
Text("This QR code contains a VoiceUwu Pro license key. The recipient can scan it to automatically activate their license.")
.font(.caption)
.foregroundColor(.secondary)
.multilineTextAlignment(.center)
.padding(.horizontal)
}
.padding()
}
}
// MARK: - Supporting Types
struct SharingEvent: Codable {
let keyHash: String
let method: KeySharingManager.SharingMethod
let timestamp: Date
}
struct SharingOption {
let method: KeySharingManager.SharingMethod
let title: String
let icon: String
}
enum SharingResult {
case success(message: String)
case failure(error: SharingError)
}
enum SharingError: Error {
case qrGenerationFailed
case noKeysAvailable
case sharingCancelled
}
Sharing Features
-
Multiple Methods
- Copy to clipboard
- Message/SMS
- Email with formatting
- QR code generation
- Universal links
-
User Experience
- Pre-filled templates
- Clear instructions
- Visual feedback
- Error handling
-
Tracking
- Sharing history
- Inventory management
- Anonymous tracking
-
Security
- Keys removed from inventory when shared
- One-time use enforcement
- No key exposure in URLs