Services: Admin-Compliance, Backend-Compliance, AI-Compliance-SDK, Consent-SDK, Developer-Portal, PCA-Platform, DSMS Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
284 lines
10 KiB
TypeScript
284 lines
10 KiB
TypeScript
'use client'
|
|
|
|
import React, { useState } from 'react'
|
|
import { SDKDocsSidebar } from '@/components/SDKDocsSidebar'
|
|
import { Copy, Check, Apple } from 'lucide-react'
|
|
|
|
function CopyButton({ text }: { text: string }) {
|
|
const [copied, setCopied] = useState(false)
|
|
const handleCopy = async () => {
|
|
await navigator.clipboard.writeText(text)
|
|
setCopied(true)
|
|
setTimeout(() => setCopied(false), 2000)
|
|
}
|
|
return (
|
|
<button onClick={handleCopy} className="p-2 hover:bg-gray-700 rounded transition-colors">
|
|
{copied ? <Check className="w-4 h-4 text-green-400" /> : <Copy className="w-4 h-4 text-gray-400" />}
|
|
</button>
|
|
)
|
|
}
|
|
|
|
function CodeBlock({ code, filename }: { code: string; filename?: string }) {
|
|
return (
|
|
<div className="bg-gray-900 rounded-lg overflow-hidden">
|
|
{filename && (
|
|
<div className="px-4 py-2 bg-gray-800 text-gray-400 text-xs border-b border-gray-700">
|
|
{filename}
|
|
</div>
|
|
)}
|
|
<div className="relative">
|
|
<div className="absolute top-2 right-2">
|
|
<CopyButton text={code} />
|
|
</div>
|
|
<pre className="p-4 text-sm text-gray-300 font-mono overflow-x-auto">
|
|
<code>{code}</code>
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default function iOSSDKPage() {
|
|
return (
|
|
<div className="min-h-screen bg-gray-50 flex">
|
|
<SDKDocsSidebar />
|
|
|
|
<main className="flex-1 ml-64">
|
|
<div className="max-w-4xl mx-auto px-8 py-12">
|
|
<div className="flex items-center gap-3 mb-2">
|
|
<div className="w-10 h-10 rounded-lg bg-gray-900 flex items-center justify-center">
|
|
<Apple className="w-6 h-6 text-white" />
|
|
</div>
|
|
<h1 className="text-3xl font-bold text-gray-900">iOS SDK (Swift)</h1>
|
|
</div>
|
|
<p className="text-lg text-gray-600 mb-8">
|
|
Native Swift SDK fuer iOS 15+ und iPadOS mit SwiftUI-Unterstuetzung.
|
|
</p>
|
|
|
|
{/* Requirements */}
|
|
<section className="mb-12">
|
|
<h2 className="text-xl font-semibold text-gray-900 mb-4">Systemvoraussetzungen</h2>
|
|
<div className="bg-white rounded-xl border border-gray-200 overflow-hidden">
|
|
<table className="min-w-full divide-y divide-gray-200">
|
|
<tbody className="divide-y divide-gray-200">
|
|
<tr>
|
|
<td className="px-6 py-4 text-sm font-medium text-gray-900">Swift Version</td>
|
|
<td className="px-6 py-4 text-sm text-gray-600">5.9+</td>
|
|
</tr>
|
|
<tr>
|
|
<td className="px-6 py-4 text-sm font-medium text-gray-900">iOS Deployment Target</td>
|
|
<td className="px-6 py-4 text-sm text-gray-600">iOS 15.0+</td>
|
|
</tr>
|
|
<tr>
|
|
<td className="px-6 py-4 text-sm font-medium text-gray-900">Xcode Version</td>
|
|
<td className="px-6 py-4 text-sm text-gray-600">15.0+</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</section>
|
|
|
|
{/* Installation */}
|
|
<section className="mb-12">
|
|
<h2 className="text-xl font-semibold text-gray-900 mb-4">Installation</h2>
|
|
<h3 className="font-medium text-gray-900 mb-2">Swift Package Manager</h3>
|
|
<CodeBlock
|
|
filename="Package.swift"
|
|
code={`dependencies: [
|
|
.package(url: "https://github.com/breakpilot/consent-sdk-ios.git", from: "1.0.0")
|
|
]`}
|
|
/>
|
|
<p className="text-sm text-gray-600 mt-4">
|
|
Oder in Xcode: File → Add Package Dependencies → URL eingeben
|
|
</p>
|
|
</section>
|
|
|
|
{/* Basic Usage */}
|
|
<section className="mb-12">
|
|
<h2 className="text-xl font-semibold text-gray-900 mb-4">Grundlegende Verwendung</h2>
|
|
<CodeBlock
|
|
filename="AppDelegate.swift"
|
|
code={`import ConsentSDK
|
|
|
|
@main
|
|
class AppDelegate: UIResponder, UIApplicationDelegate {
|
|
func application(
|
|
_ application: UIApplication,
|
|
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
|
) -> Bool {
|
|
|
|
// Consent Manager konfigurieren
|
|
ConsentManager.shared.configure(
|
|
apiEndpoint: "https://api.example.com/consent",
|
|
siteId: "my-ios-app"
|
|
)
|
|
|
|
// Initialisieren
|
|
Task {
|
|
await ConsentManager.shared.initialize()
|
|
}
|
|
|
|
return true
|
|
}
|
|
}`}
|
|
/>
|
|
</section>
|
|
|
|
{/* SwiftUI Integration */}
|
|
<section className="mb-12">
|
|
<h2 className="text-xl font-semibold text-gray-900 mb-4">SwiftUI Integration</h2>
|
|
<CodeBlock
|
|
filename="ContentView.swift"
|
|
code={`import SwiftUI
|
|
import ConsentSDK
|
|
|
|
struct ContentView: View {
|
|
@StateObject private var consent = ConsentManager.shared
|
|
|
|
var body: some View {
|
|
VStack {
|
|
if consent.hasConsent(.analytics) {
|
|
AnalyticsView()
|
|
}
|
|
|
|
Button("Alle akzeptieren") {
|
|
Task {
|
|
await consent.acceptAll()
|
|
}
|
|
}
|
|
}
|
|
.consentBanner() // Zeigt Banner automatisch
|
|
}
|
|
}
|
|
|
|
// Consent Gate Modifier
|
|
struct ProtectedView: View {
|
|
var body: some View {
|
|
Text("Geschuetzter Inhalt")
|
|
.requiresConsent(.marketing) {
|
|
// Fallback wenn kein Consent
|
|
Text("Marketing-Zustimmung erforderlich")
|
|
}
|
|
}
|
|
}`}
|
|
/>
|
|
</section>
|
|
|
|
{/* UIKit Integration */}
|
|
<section className="mb-12">
|
|
<h2 className="text-xl font-semibold text-gray-900 mb-4">UIKit Integration</h2>
|
|
<CodeBlock
|
|
filename="ViewController.swift"
|
|
code={`import UIKit
|
|
import ConsentSDK
|
|
import Combine
|
|
|
|
class ViewController: UIViewController {
|
|
private var cancellables = Set<AnyCancellable>()
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
|
|
// Reaktiv auf Consent-Aenderungen reagieren
|
|
ConsentManager.shared.$consent
|
|
.receive(on: DispatchQueue.main)
|
|
.sink { [weak self] state in
|
|
self?.updateUI(consent: state)
|
|
}
|
|
.store(in: &cancellables)
|
|
}
|
|
|
|
private func updateUI(consent: ConsentState?) {
|
|
if consent?.hasConsent(.analytics) == true {
|
|
loadAnalytics()
|
|
}
|
|
}
|
|
|
|
@IBAction func acceptAllTapped(_ sender: UIButton) {
|
|
Task {
|
|
await ConsentManager.shared.acceptAll()
|
|
}
|
|
}
|
|
}`}
|
|
/>
|
|
</section>
|
|
|
|
{/* Consent Categories */}
|
|
<section className="mb-12">
|
|
<h2 className="text-xl font-semibold text-gray-900 mb-4">Consent-Kategorien</h2>
|
|
<CodeBlock
|
|
code={`// Verfuegbare Kategorien
|
|
enum ConsentCategory {
|
|
case essential // Immer aktiv
|
|
case functional // Funktionale Features
|
|
case analytics // Statistik & Analyse
|
|
case marketing // Werbung & Tracking
|
|
case social // Social Media Integration
|
|
}
|
|
|
|
// Consent pruefen
|
|
if ConsentManager.shared.hasConsent(.analytics) {
|
|
// Analytics laden
|
|
}
|
|
|
|
// Mehrere Kategorien pruefen
|
|
if ConsentManager.shared.hasConsent([.analytics, .marketing]) {
|
|
// Beide Kategorien haben Consent
|
|
}`}
|
|
/>
|
|
</section>
|
|
|
|
{/* API Reference */}
|
|
<section>
|
|
<h2 className="text-xl font-semibold text-gray-900 mb-4">API Referenz</h2>
|
|
<div className="bg-white rounded-xl border border-gray-200 overflow-hidden">
|
|
<table className="min-w-full divide-y divide-gray-200">
|
|
<thead className="bg-gray-50">
|
|
<tr>
|
|
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Methode</th>
|
|
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Beschreibung</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody className="divide-y divide-gray-200">
|
|
<tr>
|
|
<td className="px-6 py-4"><code className="text-violet-600">configure()</code></td>
|
|
<td className="px-6 py-4 text-sm text-gray-600">SDK konfigurieren</td>
|
|
</tr>
|
|
<tr>
|
|
<td className="px-6 py-4"><code className="text-violet-600">initialize()</code></td>
|
|
<td className="px-6 py-4 text-sm text-gray-600">SDK initialisieren (async)</td>
|
|
</tr>
|
|
<tr>
|
|
<td className="px-6 py-4"><code className="text-violet-600">hasConsent(_:)</code></td>
|
|
<td className="px-6 py-4 text-sm text-gray-600">Consent fuer Kategorie pruefen</td>
|
|
</tr>
|
|
<tr>
|
|
<td className="px-6 py-4"><code className="text-violet-600">acceptAll()</code></td>
|
|
<td className="px-6 py-4 text-sm text-gray-600">Alle Kategorien akzeptieren (async)</td>
|
|
</tr>
|
|
<tr>
|
|
<td className="px-6 py-4"><code className="text-violet-600">rejectAll()</code></td>
|
|
<td className="px-6 py-4 text-sm text-gray-600">Alle ablehnen (async)</td>
|
|
</tr>
|
|
<tr>
|
|
<td className="px-6 py-4"><code className="text-violet-600">setConsent(_:)</code></td>
|
|
<td className="px-6 py-4 text-sm text-gray-600">Spezifische Kategorien setzen (async)</td>
|
|
</tr>
|
|
<tr>
|
|
<td className="px-6 py-4"><code className="text-violet-600">showBanner()</code></td>
|
|
<td className="px-6 py-4 text-sm text-gray-600">Banner anzeigen</td>
|
|
</tr>
|
|
<tr>
|
|
<td className="px-6 py-4"><code className="text-violet-600">exportConsent()</code></td>
|
|
<td className="px-6 py-4 text-sm text-gray-600">Consent-Daten exportieren (DSGVO)</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
)
|
|
}
|