> ## Documentation Index
> Fetch the complete documentation index at: https://docs.contactsmanager.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Events

> Creating and managing events with the ContactsManager SDK

# Events

The ContactsManager SDK provides comprehensive event management features to enhance your app with social events and activities. Events can be used for scheduling meetups, announcing product launches, organizing team activities, or any other social interactions within your app. This guide explains how to implement these features using the SDK.

## Event Flexibility

The event system in ContactsManager is designed to be highly flexible, allowing you to model various types of social interactions beyond traditional calendar events. Using the `eventType` field (a free-form string) and the `metadata` field (a customizable JSON object), you can implement a wide range of social features:

### Use Cases for Events

* **Calendar Events**: Traditional meetups, appointments, or gatherings with time and location
* **Social Posts**: Status updates, photos, or announcements similar to Instagram or Facebook posts
* **Activity Feed Items**: Transactions or actions like those in Venmo ("Alex paid Bob \$20")
* **Product Launches**: Announcements of new features or products
* **Milestones**: Achievements or important dates for users
* **Content Recommendations**: Suggested articles, videos, or other content
* **Group Activities**: Team events, group challenges, or collaborative projects

### Customizing Events with Metadata

The `metadata` field accepts any JSON data, making it extremely versatile:

<CodeGroup>
  ```swift Swift theme={null}
  // Social post with image URL
  let postMetadata: [String: Any] = [
      "postType": "image",
      "imageUrl": "https://example.com/images/vacation.jpg",
      "filter": "summer",
      "likes": 0,
      "commentsEnabled": true
  ]

  // Transaction activity
  let transactionMetadata: [String: Any] = [
      "amount": 25.50,
      "currency": "USD",
      "transactionId": "tx_12345",
      "category": "dining"
  ]

  // Product recommendation
  let recommendationMetadata: [String: Any] = [
      "productId": "prod_789",
      "discount": "15%",
      "expiryDate": "2025-05-01",
      "targetSegment": "new_users"
  ]
  ```

  ```kotlin Kotlin theme={null}
  // Social post with image URL
  val postMetadata = mapOf(
      "postType" to "image",
      "imageUrl" to "https://example.com/images/vacation.jpg",
      "filter" to "summer",
      "likes" to 0,
      "commentsEnabled" to true
  )

  // Transaction activity
  val transactionMetadata = mapOf(
      "amount" to 25.50,
      "currency" to "USD",
      "transactionId" to "tx_12345",
      "category" to "dining"
  )

  // Product recommendation
  val recommendationMetadata = mapOf(
      "productId" to "prod_789",
      "discount" to "15%",
      "expiryDate" to "2025-05-01",
      "targetSegment" to "new_users"
  )
  ```

  ```typescript React Native theme={null}
  // Social post with image URL
  const postMetadata = {
      postType: "image",
      imageUrl: "https://example.com/images/vacation.jpg",
      filter: "summer",
      likes: 0,
      commentsEnabled: true
  };

  // Transaction activity
  const transactionMetadata = {
      amount: 25.50,
      currency: "USD",
      transactionId: "tx_12345",
      category: "dining"
  };

  // Product recommendation
  const recommendationMetadata = {
      productId: "prod_789",
      discount: "15%",
      expiryDate: "2025-05-01",
      targetSegment: "new_users"
  };
  ```

  ```objectivec Objective-C theme={null}
  // Social post with image URL
  NSDictionary *postMetadata = @{
      @"postType": @"image",
      @"imageUrl": @"https://example.com/images/vacation.jpg",
      @"filter": @"summer",
      @"likes": @0,
      @"commentsEnabled": @YES
  };

  // Transaction activity
  NSDictionary *transactionMetadata = @{
      @"amount": @25.50,
      @"currency": @"USD",
      @"transactionId": @"tx_12345",
      @"category": @"dining"
  };

  // Product recommendation
  NSDictionary *recommendationMetadata = @{
      @"productId": @"prod_789",
      @"discount": @"15%",
      @"expiryDate": @"2025-05-01",
      @"targetSegment": @"new_users"
  };
  ```
</CodeGroup>

By creatively using these fields, you can build rich social features that perfectly match your app's requirements without being limited to a rigid event structure.

## Creating an Event

Creating events allows users to share activities and gatherings with their network. Events contain essential information like title, location, time, and visibility settings that determine who can see them.

<CodeGroup>
  ```swift Swift theme={null}
  do {
      let eventData = CreateEventRequest(
          eventType: "meeting",
          title: "Team Sync",
          description: "Weekly team synchronization",
          location: "Conference Room A",
          startTime: Date().addingTimeInterval(86400),  // Tomorrow
          endTime: Date().addingTimeInterval(90000),    // Tomorrow + 1 hour
          metadata: ["department": "Engineering"],
          isPublic: true
      )
      
      let result = try await ContactsService.shared.socialService.createEvent(
          eventData: eventData
      )
      
      if let eventId = result.eventId, let created = result.created, created {
          print("Created event with ID: \(eventId)")
      }
  } catch {
      print("Error creating event: \(error.localizedDescription)")
  }
  ```

  ```kotlin Kotlin theme={null}
  // Get instance of SocialService
  val socialService = SocialService.getInstance(context)

  // Create event data
  val eventData = CreateEventRequest(
      eventType = "meeting",
      title = "Team Sync",
      description = "Weekly team synchronization",
      location = "Conference Room A",
      startTime = Calendar.getInstance().apply { add(Calendar.DAY_OF_YEAR, 1) }.time,
      endTime = Calendar.getInstance().apply { add(Calendar.DAY_OF_YEAR, 1); add(Calendar.HOUR, 1) }.time,
      metadata = mapOf("department" to "Engineering"),
      isPublic = true
  )

  // Launch in a coroutine
  lifecycleScope.launch {
      try {
          val result = socialService.createEvent(eventData).getOrThrow()
          if (result.eventId != null && result.created == true) {
              println("Created event with ID: ${result.eventId}")
          }
      } catch (e: Exception) {
          println("Error creating event: ${e.message}")
      }
  }
  ```

  ```typescript React Native theme={null}
  import { SocialService } from '@contactsmanager/rn';

  try {
    const eventData = {
      eventType: 'meeting',
      title: 'Team Sync',
      description: 'Weekly team synchronization',
      location: 'Conference Room A',
      startTime: new Date(Date.now() + 86400000),  // Tomorrow
      endTime: new Date(Date.now() + 90000000),    // Tomorrow + 1 hour
      metadata: { department: 'Engineering' },
      isPublic: true
    };
    
    const result = await SocialService.createEvent(eventData);
    
    if (result.eventId && result.created) {
      console.log(`Created event with ID: ${result.eventId}`);
    }
  } catch (error) {
    console.error('Error creating event:', error);
  }
  ```

  ```objectivec Objective-C theme={null}
  // Create event data
  CMCreateEventRequest *eventData = [[CMCreateEventRequest alloc] init];
  eventData.eventType = @"meeting";
  eventData.title = @"Team Sync";
  eventData.description = @"Weekly team synchronization";
  eventData.location = @"Conference Room A";
  eventData.startTime = [[NSDate date] dateByAddingTimeInterval:86400]; // Tomorrow
  eventData.endTime = [[NSDate date] dateByAddingTimeInterval:90000];   // Tomorrow + 1 hour
  eventData.metadata = @{@"department": @"Engineering"};
  eventData.isPublic = YES;

  // Get social service from contact service
  CMSocialService *socialService = [CMContactService sharedInstance].socialService;

  // Create event
  [socialService createEvent:eventData
                  completion:^(CMEventActionResponse * _Nullable response, NSError * _Nullable error) {
      if (error) {
          NSLog(@"Error creating event: %@", error.localizedDescription);
          return;
      }
      
      if (response.eventId && response.created) {
          NSLog(@"Created event with ID: %@", response.eventId);
      }
  }];
  ```
</CodeGroup>

The `CreateEventRequest` model includes these key properties:

* `eventType`: A categorical identifier for the event (e.g., meeting, social, post, transaction)
* `title`: The main title of the event
* `description`: Detailed information about the event
* `location`: Where the event will take place
* `startTime` and `endTime`: When the event begins and ends
* `metadata`: Additional custom data as key-value pairs
* `isPublic`: Determines whether the event is visible to all users or only specific contacts

### Example: Creating a Social Post Event

<CodeGroup>
  ```swift Swift theme={null}
  // Create a social post similar to Instagram
  let socialPostEvent = CreateEventRequest(
      eventType: "social_post",
      title: "Beach day!",
      description: "Having an amazing time at Malibu",
      location: "Malibu Beach, CA",
      startTime: Date(),  // Post time is now
      metadata: [
          "postType": "photo",
          "imageUrl": "https://example.com/photos/beach.jpg",
          "filter": "vivid",
          "mentions": ["user_123", "user_456"],
          "hashtags": ["summer", "beach", "vacation"]
      ],
      isPublic: true
  )
  ```

  ```kotlin Kotlin theme={null}
  // Create a social post similar to Instagram
  val socialPostEvent = CreateEventRequest(
      eventType = "social_post",
      title = "Beach day!",
      description = "Having an amazing time at Malibu",
      location = "Malibu Beach, CA",
      startTime = Date(), // Post time is now
      metadata = mapOf(
          "postType" to "photo",
          "imageUrl" to "https://example.com/photos/beach.jpg",
          "filter" to "vivid",
          "mentions" to listOf("user_123", "user_456"),
          "hashtags" to listOf("summer", "beach", "vacation")
      ),
      isPublic = true
  )

  lifecycleScope.launch {
      try {
          val result = socialService.createEvent(socialPostEvent).getOrThrow()
          if (result.eventId != null && result.created == true) {
              println("Created social post with ID: ${result.eventId}")
          }
      } catch (e: Exception) {
          println("Error creating social post: ${e.message}")
      }
  }
  ```

  ```typescript React Native theme={null}
  // Create a social post similar to Instagram
  const socialPostEvent = {
      eventType: 'social_post',
      title: 'Beach day!',
      description: 'Having an amazing time at Malibu',
      location: 'Malibu Beach, CA',
      startTime: new Date(),  // Post time is now
      metadata: {
          postType: 'photo',
          imageUrl: 'https://example.com/photos/beach.jpg',
          filter: 'vivid',
          mentions: ['user_123', 'user_456'],
          hashtags: ['summer', 'beach', 'vacation']
      },
      isPublic: true
  };

  try {
      const result = await SocialService.createEvent(socialPostEvent);
      console.log(`Created social post with ID: ${result.eventId}`);
  } catch (error) {
      console.error('Error creating social post:', error);
  }
  ```

  ```objectivec Objective-C theme={null}
  // Create a social post similar to Instagram
  CMCreateEventRequest *socialPostEvent = [[CMCreateEventRequest alloc] init];
  socialPostEvent.eventType = @"social_post";
  socialPostEvent.title = @"Beach day!";
  socialPostEvent.description = @"Having an amazing time at Malibu";
  socialPostEvent.location = @"Malibu Beach, CA";
  socialPostEvent.startTime = [NSDate date]; // Post time is now
  socialPostEvent.metadata = @{
      @"postType": @"photo",
      @"imageUrl": @"https://example.com/photos/beach.jpg",
      @"filter": @"vivid",
      @"mentions": @[@"user_123", @"user_456"],
      @"hashtags": @[@"summer", @"beach", @"vacation"]
  };
  socialPostEvent.isPublic = YES;
  ```
</CodeGroup>

### Example: Creating a Transaction Activity

<CodeGroup>
  ```swift Swift theme={null}
  // Create a transaction event like Venmo
  let transactionEvent = CreateEventRequest(
      eventType: "transaction",
      title: "Dinner payment",
      description: "Thanks for dinner last night!",
      startTime: Date(),
      metadata: [
          "amount": 45.50,
          "currency": "USD", 
          "paymentMethod": "credit_card",
          "category": "dining",
          "recipients": ["user_789"],
          "emoji": "🍕"
      ],
      isPublic: true
  )
  ```

  ```kotlin Kotlin theme={null}
  // Create a transaction event like Venmo
  val transactionEvent = CreateEventRequest(
      eventType = "transaction",
      title = "Dinner payment",
      description = "Thanks for dinner last night!",
      startTime = Date(),
      metadata = mapOf(
          "amount" to 45.50,
          "currency" to "USD",
          "paymentMethod" to "credit_card",
          "category" to "dining",
          "recipients" to listOf("user_789"),
          "emoji" to "🍕"
      ),
      isPublic = true
  )

  lifecycleScope.launch {
      try {
          val result = socialService.createEvent(transactionEvent).getOrThrow()
          if (result.eventId != null && result.created == true) {
              println("Created transaction with ID: ${result.eventId}")
          }
      } catch (e: Exception) {
          println("Error creating transaction: ${e.message}")
      }
  }
  ```

  ```typescript React Native theme={null}
  // Create a transaction event like Venmo
  const transactionEvent = {
      eventType: 'transaction',
      title: 'Dinner payment',
      description: 'Thanks for dinner last night!',
      startTime: new Date(),
      metadata: {
          amount: 45.50,
          currency: 'USD',
          paymentMethod: 'credit_card',
          category: 'dining',
          recipients: ['user_789'],
          emoji: '🍕'
      },
      isPublic: true
  };

  try {
      const result = await SocialService.createEvent(transactionEvent);
      console.log(`Created transaction with ID: ${result.eventId}`);
  } catch (error) {
      console.error('Error creating transaction:', error);
  }
  ```

  ```objectivec Objective-C theme={null}
  // Create a transaction event like Venmo
  CMCreateEventRequest *transactionEvent = [[CMCreateEventRequest alloc] init];
  transactionEvent.eventType = @"transaction";
  transactionEvent.title = @"Dinner payment";
  transactionEvent.description = @"Thanks for dinner last night!";
  transactionEvent.startTime = [NSDate date];
  transactionEvent.metadata = @{
      @"amount": @45.50,
      @"currency": @"USD",
      @"paymentMethod": @"credit_card",
      @"category": @"dining",
      @"recipients": @[@"user_789"],
      @"emoji": @"🍕"
  };
  transactionEvent.isPublic = YES;
  ```
</CodeGroup>

## Retrieving Event Details

Once an event is created, users can view its details. This is useful for displaying event information on dedicated event pages or when users receive event invitations.

<CodeGroup>
  ```swift Swift theme={null}
  do {
      let event = try await ContactsService.shared.socialService.getEvent(
          eventId: "event-id"
      )
      
      print("Event: \(event.title)")
      print("Type: \(event.eventType)")
      print("Description: \(event.description ?? "No description")")
      print("Location: \(event.location ?? "No location")")
      
      if let startTime = event.startTime {
          let formatter = DateFormatter()
          formatter.dateStyle = .medium
          formatter.timeStyle = .short
          print("Start time: \(formatter.string(from: startTime))")
      }
      
      // Access custom metadata
      if let metadata = event.metadata as? [String: Any] {
          // Handle different event types based on the metadata
          switch event.eventType {
          case "social_post":
              if let imageUrl = metadata["imageUrl"] as? String {
                  print("Post image: \(imageUrl)")
              }
              if let hashtags = metadata["hashtags"] as? [String] {
                  print("Hashtags: \(hashtags.joined(separator: ", "))")
              }
          case "transaction":
              if let amount = metadata["amount"] as? Double, 
                 let currency = metadata["currency"] as? String {
                  print("Amount: \(amount) \(currency)")
              }
          default:
              print("Other event type with metadata: \(metadata)")
          }
      }
  } catch {
      print("Error retrieving event: \(error.localizedDescription)")
  }
  ```

  ```kotlin Kotlin theme={null}
  lifecycleScope.launch {
      try {
          val event = socialService.getEvent("event-id").getOrThrow()
          
          println("Event: ${event.title}")
          println("Type: ${event.eventType}")
          println("Description: ${event.description ?: "No description"}")
          println("Location: ${event.location ?: "No location"}")
          
          event.startTime?.let { startTime ->
              val formatter = SimpleDateFormat("MMM d, yyyy h:mm a", Locale.getDefault())
              println("Start time: ${formatter.format(startTime)}")
          }
          
          // Access custom metadata
          event.metadata?.let { metadata ->
              when (event.eventType) {
                  "social_post" -> {
                      metadata["imageUrl"]?.let { imageUrl ->
                          println("Post image: $imageUrl")
                      }
                      (metadata["hashtags"] as? List<String>)?.let { hashtags ->
                          println("Hashtags: ${hashtags.joinToString(", ")}")
                      }
                  }
                  "transaction" -> {
                      val amount = metadata["amount"] as? Double
                      val currency = metadata["currency"] as? String
                      if (amount != null && currency != null) {
                          println("Amount: $amount $currency")
                      }
                  }
                  else -> println("Other event type with metadata: $metadata")
              }
          }
      } catch (e: Exception) {
          println("Error retrieving event: ${e.message}")
      }
  }
  ```

  ```typescript React Native theme={null}
  import { SocialService } from '@contactsmanager/rn';

  try {
    const event = await SocialService.getEvent('event-id');
    
    console.log(`Event: ${event.title}`);
    console.log(`Type: ${event.eventType}`);
    console.log(`Description: ${event.description || 'No description'}`);
    console.log(`Location: ${event.location || 'No location'}`);
    
    if (event.startTime) {
      const date = new Date(event.startTime);
      console.log(`Start time: ${date.toLocaleString()}`);
    }
    
    // Access custom metadata
    if (event.metadata) {
      switch (event.eventType) {
        case 'social_post':
          if (event.metadata.imageUrl) {
            console.log(`Post image: ${event.metadata.imageUrl}`);
          }
          if (event.metadata.hashtags) {
            console.log(`Hashtags: ${event.metadata.hashtags.join(', ')}`);
          }
          break;
        case 'transaction':
          if (event.metadata.amount && event.metadata.currency) {
            console.log(`Amount: ${event.metadata.amount} ${event.metadata.currency}`);
          }
          break;
        default:
          console.log('Other event type with metadata:', event.metadata);
      }
    }
  } catch (error) {
    console.error('Error retrieving event:', error);
  }
  ```

  ```objectivec Objective-C theme={null}
  [socialService getEvent:@"event-id"
              completion:^(CMSocialEvent * _Nullable event, NSError * _Nullable error) {
      if (error) {
          NSLog(@"Error retrieving event: %@", error.localizedDescription);
          return;
      }
      
      NSLog(@"Event: %@", event.title);
      NSLog(@"Type: %@", event.eventType);
      NSLog(@"Description: %@", event.description ?: @"No description");
      NSLog(@"Location: %@", event.location ?: @"No location");
      
      if (event.startTime) {
          NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
          formatter.dateStyle = NSDateFormatterMediumStyle;
          formatter.timeStyle = NSDateFormatterShortStyle;
          NSLog(@"Start time: %@", [formatter stringFromDate:event.startTime]);
      }
      
      // Access custom metadata
      if (event.metadata) {
          if ([event.eventType isEqualToString:@"social_post"]) {
              NSString *imageUrl = event.metadata[@"imageUrl"];
              if (imageUrl) {
                  NSLog(@"Post image: %@", imageUrl);
              }
              NSArray *hashtags = event.metadata[@"hashtags"];
              if (hashtags) {
                  NSLog(@"Hashtags: %@", [hashtags componentsJoinedByString:@", "]);
              }
          } else if ([event.eventType isEqualToString:@"transaction"]) {
              NSNumber *amount = event.metadata[@"amount"];
              NSString *currency = event.metadata[@"currency"];
              if (amount && currency) {
                  NSLog(@"Amount: %@ %@", amount, currency);
              }
          } else {
              NSLog(@"Other event type with metadata: %@", event.metadata);
          }
      }
  }];
  ```
</CodeGroup>

## Updating an Event

Event details may need to be modified after creation. Changes to time, location, or other details can be easily updated using the update method.

<CodeGroup>
  ```swift Swift theme={null}
  do {
      let updateData = UpdateEventRequest(
          title: "Updated Team Sync",
          description: "Updated weekly team synchronization",
          location: "Virtual Meeting Room",
          startTime: Date().addingTimeInterval(90000),
          endTime: Date().addingTimeInterval(93600),
          metadata: ["department": "Engineering", "priority": "High"],
          isPublic: true
      )
      
      let result = try await ContactsService.shared.socialService.updateEvent(
          eventId: "event-id",
          eventData: updateData
      )
      
      if let success = result.success, success {
          print("Successfully updated event")
      }
  } catch {
      print("Error updating event: \(error.localizedDescription)")
  }
  ```

  ```kotlin Kotlin theme={null}
  // Get instance of SocialService
  val socialService = SocialService.getInstance(context)

  // Create update data
  val updateData = UpdateEventRequest(
      title = "Updated Team Sync",
      description = "Updated weekly team synchronization",
      location = "Virtual Meeting Room",
      startTime = Calendar.getInstance().apply { add(Calendar.DAY_OF_YEAR, 1) }.time,
      endTime = Calendar.getInstance().apply { add(Calendar.DAY_OF_YEAR, 1); add(Calendar.HOUR, 1) }.time,
      metadata = mapOf("department" to "Engineering", "priority" to "High"),
      isPublic = true
  )

  // Launch in a coroutine
  lifecycleScope.launch {
      try {
          val result = socialService.updateEvent("event-id", updateData).getOrThrow()
          if (result.success == true) {
              println("Successfully updated event")
          }
      } catch (e: Exception) {
          println("Error updating event: ${e.message}")
      }
  }
  ```

  ```typescript React Native theme={null}
  import { SocialService } from '@contactsmanager/rn';

  try {
    const updateData = {
      title: 'Updated Team Sync',
      description: 'Updated weekly team synchronization',
      location: 'Virtual Meeting Room',
      startTime: new Date(Date.now() + 90000000),
      endTime: new Date(Date.now() + 93600000),
      metadata: { department: 'Engineering', priority: 'High' },
      isPublic: true
    };
    
    const result = await SocialService.updateEvent('event-id', updateData);
    
    if (result.success) {
      console.log('Successfully updated event');
    }
  } catch (error) {
    console.error('Error updating event:', error);
  }
  ```

  ```objectivec Objective-C theme={null}
  // Create update data
  CMUpdateEventRequest *updateData = [[CMUpdateEventRequest alloc] init];
  updateData.title = @"Updated Team Sync";
  updateData.description = @"Updated weekly team synchronization";
  updateData.location = @"Virtual Meeting Room";
  updateData.startTime = [[NSDate date] dateByAddingTimeInterval:90000];
  updateData.endTime = [[NSDate date] dateByAddingTimeInterval:93600];
  updateData.metadata = @{@"department": @"Engineering", @"priority": @"High"};
  updateData.isPublic = YES;

  // Get social service from contact service
  CMSocialService *socialService = [CMContactService sharedInstance].socialService;

  // Update event
  [socialService updateEvent:@"event-id"
                  eventData:updateData
                 completion:^(CMEventActionResponse * _Nullable response, NSError * _Nullable error) {
      if (error) {
          NSLog(@"Error updating event: %@", error.localizedDescription);
          return;
      }
      
      if (response.success) {
          NSLog(@"Successfully updated event");
      }
  }];
  ```
</CodeGroup>

The `UpdateEventRequest` model is similar to the creation model, but all fields are optional. Only the properties you want to change need to be included, and existing properties will remain unchanged if not specified.

### Example: Updating a Social Post Event

```swift theme={null}
// Update a social post with likes and comments
let updateSocialPost = UpdateEventRequest(
    metadata: [
        "likes": 42,
        "comments": [
            ["userId": "user_123", "text": "Amazing view!", "timestamp": Date().timeIntervalSince1970],
            ["userId": "user_456", "text": "Wish I was there!", "timestamp": Date().timeIntervalSince1970]
        ]
    ]
)
```

## Deleting an Event

When events are cancelled or no longer needed, they can be removed from the system, which prevents them from appearing in feeds and search results.

<CodeGroup>
  ```swift Swift theme={null}
  do {
      let result = try await ContactsService.shared.socialService.deleteEvent(
          eventId: "event-id"
      )
      
      if let success = result.success, success {
          print("Successfully deleted event")
      }
  } catch {
      print("Error deleting event: \(error.localizedDescription)")
  }
  ```

  ```kotlin Kotlin theme={null}
  lifecycleScope.launch {
      try {
          val result = socialService.deleteEvent("event-id").getOrThrow()
          if (result.success == true) {
              println("Successfully deleted event")
          }
      } catch (e: Exception) {
          println("Error deleting event: ${e.message}")
      }
  }
  ```

  ```typescript React Native theme={null}
  import { SocialService } from '@contactsmanager/rn';

  try {
    const result = await SocialService.deleteEvent('event-id');
    
    if (result.success) {
      console.log('Successfully deleted event');
    }
  } catch (error) {
    console.error('Error deleting event:', error);
  }
  ```

  ```objectivec Objective-C theme={null}
  [socialService deleteEvent:@"event-id"
                  completion:^(CMEventActionResponse * _Nullable response, NSError * _Nullable error) {
      if (error) {
          NSLog(@"Error deleting event: %@", error.localizedDescription);
          return;
      }
      
      if (response.success) {
          NSLog(@"Successfully deleted event");
      }
  }];
  ```
</CodeGroup>

Deleting an event is a permanent operation, so consider implementing confirmation flows in your app UI to prevent accidental deletions.

## Event Feeds

The SDK provides different feed types to display events from users. These feeds are essential for creating engaging social experiences within your app.

### Following Feed

The Following Feed shows events from users the user follows, creating a personalized stream of relevant activities. This helps users stay informed about what people in their network are doing.

<CodeGroup>
  ```swift Swift theme={null}
  do {
      let feed = try await ContactsService.shared.socialService.getFeed(
          skip: 0,
          limit: 20
      )
      
      print("Your feed has \(feed.total) events")
      
      for event in feed.items {
          print("\(event.title) by \(event.creatorName ?? "Unknown")")
          
          if let startTime = event.startTime {
              let formatter = DateFormatter()
              formatter.dateStyle = .medium
              formatter.timeStyle = .short
              print("When: \(formatter.string(from: startTime))")
          }
          
          // Handle different event types in the feed
          if let metadata = event.metadata as? [String: Any] {
              switch event.eventType {
              case "social_post":
                  print("Post: \(event.description ?? "")")
                  if let imageUrl = metadata["imageUrl"] as? String {
                      // Load and display image
                      print("Image: \(imageUrl)")
                  }
              case "transaction":
                  if let amount = metadata["amount"] as? Double,
                     let currency = metadata["currency"] as? String,
                     let emoji = metadata["emoji"] as? String {
                      print("\(emoji) \(amount) \(currency)")
                  }
              default:
                  print("Event: \(event.eventType)")
              }
          }
      }
  } catch {
      print("Error retrieving feed: \(error.localizedDescription)")
  }
  ```

  ```kotlin Kotlin theme={null}
  lifecycleScope.launch {
      try {
          val feed = socialService.getFeed(
              skip = 0,
              limit = 20
          ).getOrThrow()
          
          println("Your feed has ${feed.total} events")
          
          feed.items.forEach { event ->
              println("${event.title} by ${event.creatorName ?: "Unknown"}")
              
              event.startTime?.let { startTime ->
                  val formatter = SimpleDateFormat("MMM d, yyyy h:mm a", Locale.getDefault())
                  println("When: ${formatter.format(startTime)}")
              }
              
              // Handle different event types in the feed
              event.metadata?.let { metadata ->
                  when (event.eventType) {
                      "social_post" -> {
                          println("Post: ${event.description ?: ""}")
                          if (metadata["imageUrl"] != null) {
                              // Load and display image
                              println("Image: ${metadata["imageUrl"]}")
                          }
                      }
                      "transaction" -> {
                          val amount = metadata["amount"] as? Double
                          val currency = metadata["currency"] as? String
                          val emoji = metadata["emoji"] as? String
                          if (amount != null && currency != null && emoji != null) {
                              println("$emoji $amount $currency")
                          }
                      }
                      else -> println("Event: ${event.eventType}")
                  }
              }
          }
      } catch (e: Exception) {
          println("Error retrieving feed: ${e.message}")
      }
  }
  ```

  ```typescript React Native theme={null}
  import { SocialService } from '@contactsmanager/rn';

  try {
    const feed = await SocialService.getFeed(0, 20);
    
    console.log(`Your feed has ${feed.total} events`);
    
    for (const event of feed.items) {
      console.log(`${event.title} by ${event.creatorName || 'Unknown'}`);
      
      if (event.startTime) {
        const date = new Date(event.startTime);
        console.log(`When: ${date.toLocaleString()}`);
      }
      
      // Handle different event types in the feed
      if (event.metadata) {
        switch (event.eventType) {
          case 'social_post':
            console.log(`Post: ${event.description || ''}`);
            if (event.metadata.imageUrl) {
              // Load and display image
              console.log(`Image: ${event.metadata.imageUrl}`);
            }
            break;
          case 'transaction':
            if (event.metadata.amount && event.metadata.currency && event.metadata.emoji) {
              console.log(`${event.metadata.emoji} ${event.metadata.amount} ${event.metadata.currency}`);
            }
            break;
          default:
            console.log(`Event: ${event.eventType}`);
        }
      }
    }
  } catch (error) {
    console.error('Error retrieving feed:', error);
  }
  ```

  ```objectivec Objective-C theme={null}
  [socialService getFeedWithSkip:0
                         limit:20
                    completion:^(CMPaginatedEventList * _Nullable feed, NSError * _Nullable error) {
      if (error) {
          NSLog(@"Error retrieving feed: %@", error.localizedDescription);
          return;
      }
      
      NSLog(@"Your feed has %ld events", (long)feed.total);
      
      for (CMSocialEvent *event in feed.items) {
          NSLog(@"%@ by %@", event.title, event.creatorName ?: @"Unknown");
          
          if (event.startTime) {
              NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
              formatter.dateStyle = NSDateFormatterMediumStyle;
              formatter.timeStyle = NSDateFormatterShortStyle;
              NSLog(@"When: %@", [formatter stringFromDate:event.startTime]);
          }
          
          // Handle different event types in the feed
          if (event.metadata) {
              if ([event.eventType isEqualToString:@"social_post"]) {
                  NSString *description = event.description;
                  if (description) {
                      NSLog(@"Post: %@", description);
                  }
                  if (event.metadata[@"imageUrl"]) {
                      // Load and display image
                      NSLog(@"Image: %@", event.metadata[@"imageUrl"]);
                  }
              } else if ([event.eventType isEqualToString:@"transaction"]) {
                  NSNumber *amount = event.metadata[@"amount"];
                  NSString *currency = event.metadata[@"currency"];
                  NSString *emoji = event.metadata[@"emoji"];
                  if (amount && currency && emoji) {
                      NSLog(@"%@ %@ %@", emoji, amount, currency);
                  }
              } else {
                  NSLog(@"Event: %@", event.eventType);
              }
          }
      }
  }];
  ```
</CodeGroup>

### "For You" Feed

The "For You" feed includes all public events in the user's network, not limited to people they follow.

<CodeGroup>
  ```swift Swift theme={null}
  do {
      let forYouFeed = try await ContactsService.shared.socialService.getForYouFeed(
          skip: 0,
          limit: 20
      )
      
      print("For You feed has \(forYouFeed.total) events")
      
      for event in forYouFeed.items {
          print("\(event.title) - \(event.eventType)")
      }
  } catch {
      print("Error retrieving For You feed: \(error.localizedDescription)")
  }
  ```

  ```kotlin Kotlin theme={null}
  lifecycleScope.launch {
      try {
          val forYouFeed = socialService.getForYouFeed(
              skip = 0,
              limit = 20
          ).getOrThrow()
          
          println("For You feed has ${forYouFeed.total} events")
          
          forYouFeed.items.forEach { event ->
              println("${event.title} - ${event.eventType}")
          }
      } catch (e: Exception) {
          println("Error retrieving For You feed: ${e.message}")
      }
  }
  ```

  ```typescript React Native theme={null}
  import { SocialService } from '@contactsmanager/rn';

  try {
    const forYouFeed = await SocialService.getForYouFeed(0, 20);
    
    console.log(`For You feed has ${forYouFeed.total} events`);
    
    for (const event of forYouFeed.items) {
      console.log(`${event.title} - ${event.eventType}`);
    }
  } catch (error) {
    console.error('Error retrieving For You feed:', error);
  }
  ```

  ```objectivec Objective-C theme={null}
  [socialService getForYouFeedWithSkip:0
                               limit:20
                          completion:^(CMPaginatedEventList * _Nullable feed, NSError * _Nullable error) {
      if (error) {
          NSLog(@"Error retrieving For You feed: %@", error.localizedDescription);
          return;
      }
      
      NSLog(@"For You feed has %ld events", (long)feed.total);
      
      for (CMSocialEvent *event in feed.items) {
          NSLog(@"%@ - %@", event.title, event.eventType);
      }
  }];
  ```
</CodeGroup>

### Upcoming Events

The Upcoming Events feed shows events scheduled in the future, helping users plan ahead.

<CodeGroup>
  ```swift Swift theme={null}
  do {
      let upcomingEvents = try await ContactsService.shared.socialService.getUpcomingEvents(
          skip: 0,
          limit: 20
      )
      
      print("Found \(upcomingEvents.total) upcoming events")
  } catch {
      print("Error retrieving upcoming events: \(error.localizedDescription)")
  }
  ```

  ```kotlin Kotlin theme={null}
  lifecycleScope.launch {
      try {
          val upcomingEvents = socialService.getUpcomingEvents(
              skip = 0,
              limit = 20
          ).getOrThrow()
          
          println("Found ${upcomingEvents.total} upcoming events")
          
          upcomingEvents.items.forEach { event ->
              val formatter = SimpleDateFormat("MMM d, yyyy", Locale.getDefault())
              val eventDate = formatter.format(event.startTime)
              println("${event.title} - $eventDate")
          }
      } catch (e: Exception) {
          println("Error retrieving upcoming events: ${e.message}")
      }
  }
  ```

  ```typescript React Native theme={null}
  import { SocialService } from '@contactsmanager/rn';

  try {
    const upcomingEvents = await SocialService.getUpcomingEvents(0, 20);
    
    console.log(`Found ${upcomingEvents.total} upcoming events`);
    
    for (const event of upcomingEvents.items) {
      const eventDate = new Date(event.startTime);
      console.log(`${event.title} - ${eventDate.toLocaleDateString()}`);
    }
  } catch (error) {
    console.error('Error retrieving upcoming events:', error);
  }
  ```

  ```objectivec Objective-C theme={null}
  [socialService getUpcomingEventsWithSkip:0
                                   limit:20
                              completion:^(CMPaginatedEventList * _Nullable events, NSError * _Nullable error) {
      if (error) {
          NSLog(@"Error retrieving upcoming events: %@", error.localizedDescription);
          return;
      }
      
      NSLog(@"Found %ld upcoming events", (long)events.total);
      
      NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
      formatter.dateStyle = NSDateFormatterMediumStyle;
      formatter.timeStyle = NSDateFormatterNoStyle;
      
      for (CMSocialEvent *event in events.items) {
          NSString *eventDate = [formatter stringFromDate:event.startTime];
          NSLog(@"%@ - %@", event.title, eventDate);
      }
  }];
  ```
</CodeGroup>

### User Events

This feed shows events created by a specific user, which is useful for profile pages.

<CodeGroup>
  ```swift Swift theme={null}
  do {
      let userEvents = try await ContactsService.shared.socialService.getUserEvents(
          userId: "user-id",
          skip: 0,
          limit: 20
      )
      
      print("User has created \(userEvents.total) events")
  } catch {
      print("Error retrieving user events: \(error.localizedDescription)")
  }
  ```

  ```kotlin Kotlin theme={null}
  lifecycleScope.launch {
      try {
          val userEvents = socialService.getUserEvents(
              userId = "user-id",
              skip = 0,
              limit = 20
          ).getOrThrow()
          
          println("User has created ${userEvents.total} events")
          
          userEvents.items.forEach { event ->
              println("${event.title} (${event.eventType})")
          }
      } catch (e: Exception) {
          println("Error retrieving user events: ${e.message}")
      }
  }
  ```

  ```typescript React Native theme={null}
  import { SocialService } from '@contactsmanager/rn';

  try {
    const userEvents = await SocialService.getUserEvents('user-id', 0, 20);
    
    console.log(`User has created ${userEvents.total} events`);
    
    for (const event of userEvents.items) {
      console.log(`${event.title} (${event.eventType})`);
    }
  } catch (error) {
    console.error('Error retrieving user events:', error);
  }
  ```

  ```objectivec Objective-C theme={null}
  [socialService getUserEventsWithUserId:@"user-id"
                                  skip:0
                                 limit:20
                            completion:^(CMPaginatedEventList * _Nullable events, NSError * _Nullable error) {
      if (error) {
          NSLog(@"Error retrieving user events: %@", error.localizedDescription);
          return;
      }
      
      NSLog(@"User has created %ld events", (long)events.total);
      
      for (CMSocialEvent *event in events.items) {
          NSLog(@"%@ (%@)", event.title, event.eventType);
      }
  }];
  ```
</CodeGroup>

All feed methods support pagination through the `skip` and `limit` parameters, allowing you to implement infinite scrolling or load-more functionality.

## Filtering Events by Type

The API provides server-side filtering by event type, which is more efficient than client-side filtering. Use the `eventType` parameter in feed requests to get only the events you need:

<CodeGroup>
  ```swift Swift theme={null}
  // Get only social post events
  func getSocialPosts() async throws -> [SocialEvent] {
      let feed = try await ContactsService.shared.socialService.getFeed(
          skip: 0,
          limit: 50,
          eventType: "social_post"  // Server-side filtering
      )
      
      return feed.items
  }

  // Get only transaction events
  func getTransactions() async throws -> [SocialEvent] {
      let feed = try await ContactsService.shared.socialService.getFeed(
          skip: 0,
          limit: 50,
          eventType: "transaction"  // Server-side filtering
      )
      
      return feed.items
  }

  // Get all event types (no filtering)
  func getAllEvents() async throws -> [SocialEvent] {
      let feed = try await ContactsService.shared.socialService.getFeed(
          skip: 0,
          limit: 50
          // No eventType parameter = all events
      )
      
      return feed.items
  }
  ```

  ```kotlin Kotlin theme={null}
  // Get only social post events
  suspend fun getSocialPosts(): List<SocialEvent> {
      val feed = socialService.getFeed(
          skip = 0,
          limit = 50,
          eventType = "social_post"  // Server-side filtering
      ).getOrThrow()
      
      return feed.items
  }

  // Get only transaction events
  suspend fun getTransactions(): List<SocialEvent> {
      val feed = socialService.getFeed(
          skip = 0,
          limit = 50,
          eventType = "transaction"  // Server-side filtering
      ).getOrThrow()
      
      return feed.items
  }

  // Get all event types (no filtering)
  suspend fun getAllEvents(): List<SocialEvent> {
      val feed = socialService.getFeed(
          skip = 0,
          limit = 50
          // No eventType parameter = all events
      ).getOrThrow()
      
      return feed.items
  }
  ```

  ```typescript React Native theme={null}
  // Get only social post events
  const getSocialPosts = async (): Promise<SocialEvent[]> => {
      const feed = await SocialService.getFeed(
          0,
          50,
          'social_post'  // Server-side filtering
      );
      
      return feed.items;
  };

  // Get only transaction events
  const getTransactions = async (): Promise<SocialEvent[]> => {
      const feed = await SocialService.getFeed(
          0,
          50,
          'transaction'  // Server-side filtering
      );
      
      return feed.items;
  };

  // Get all event types (no filtering)
  const getAllEvents = async (): Promise<SocialEvent[]> => {
      const feed = await SocialService.getFeed(
          0,
          50
          // No eventType parameter = all events
      );
      
      return feed.items;
  };
  ```

  ```objectivec Objective-C theme={null}
  // Get only social post events
  - (void)getSocialPostsWithCompletion:(void (^)(NSArray<CMSocialEvent *> *events, NSError *error))completion {
      [socialService getFeedWithSkip:0
                             limit:50
                         eventType:@"social_post"  // Server-side filtering
                        completion:^(CMPaginatedEventList *feed, NSError *error) {
          if (error) {
              completion(nil, error);
              return;
          }
          completion(feed.items, nil);
      }];
  }

  // Get only transaction events
  - (void)getTransactionsWithCompletion:(void (^)(NSArray<CMSocialEvent *> *events, NSError *error))completion {
      [socialService getFeedWithSkip:0
                             limit:50
                         eventType:@"transaction"  // Server-side filtering
                        completion:^(CMPaginatedEventList *feed, NSError *error) {
          if (error) {
              completion(nil, error);
              return;
          }
          completion(feed.items, nil);
      }];
  }

  // Get all event types (no filtering)
  - (void)getAllEventsWithCompletion:(void (^)(NSArray<CMSocialEvent *> *events, NSError *error))completion {
      [socialService getFeedWithSkip:0
                             limit:50
                         eventType:nil  // No filtering
                        completion:^(CMPaginatedEventList *feed, NSError *error) {
          if (error) {
              completion(nil, error);
              return;
          }
          completion(feed.items, nil);
      }];
  }
  ```
</CodeGroup>

### Available Event Types

The API supports filtering by these common event types:

* `"social_post"` - Social media style posts with images, text, hashtags
* `"transaction"` - Payment or financial transactions
* `"meeting"` - Calendar events and appointments
* `"activity"` - General activities and milestones
* `"announcement"` - Product launches and announcements
* `"recommendation"` - Content or product recommendations

You can also use custom event types that match your app's specific needs.

### Performance Benefits

Server-side filtering provides several advantages over client-side filtering:

* **Reduced bandwidth**: Only relevant events are transferred
* **Better performance**: No need to fetch and filter large datasets
* **Consistent pagination**: Skip/limit work correctly with filtered results
* **Database optimization**: Indexes can be used for efficient filtering

## Building an Event Interface

Here's an example of building an event detail view with SwiftUI, demonstrating how to create a polished and functional event interface:

> This example shows a complete event detail view with dynamic content based on event type. You can adapt this interface to match your app's design and requirements.

```swift EventDetailView.swift [expandable] theme={null}
struct EventDetailView: View {
    let eventId: String
    
    @State private var event: SocialEvent?
    @State private var isLoading = true
    @State private var error: Error?
    
    var body: some View {
        ScrollView {
            if isLoading {
                ProgressView("Loading event...")
                    .padding()
            } else if let error = error {
                VStack(spacing: 12) {
                    Image(systemName: "exclamationmark.triangle")
                        .font(.largeTitle)
                        .foregroundColor(.red)
                    
                    Text("Failed to load event")
                        .font(.headline)
                    
                    Text(error.localizedDescription)
                        .font(.subheadline)
                        .multilineTextAlignment(.center)
                        .foregroundColor(.secondary)
                    
                    Button("Try Again") {
                        loadEvent()
                    }
                    .padding()
                    .background(Color.blue)
                    .foregroundColor(.white)
                    .cornerRadius(8)
                }
                .padding()
            } else if let event = event {
                // Event header
                VStack(alignment: .leading, spacing: 16) {
                    // Event type badge
                    Text(event.eventType.uppercased())
                        .font(.caption)
                        .padding(.horizontal, 12)
                        .padding(.vertical, 6)
                        .background(Color.blue.opacity(0.2))
                        .foregroundColor(.blue)
                        .cornerRadius(16)
                    
                    // Title
                    Text(event.title)
                        .font(.largeTitle)
                        .fontWeight(.bold)
                    
                    // Creator info
                    HStack {
                        Circle()
                            .fill(Color.gray.opacity(0.3))
                            .frame(width: 36, height: 36)
                        
                        VStack(alignment: .leading) {
                            Text("Created by")
                                .font(.caption)
                                .foregroundColor(.secondary)
                            Text(event.creatorName ?? "Unknown")
                                .font(.subheadline)
                        }
                        
                        Spacer()
                        
                        // Public/private indicator
                        if event.isPublic {
                            Label("Public", systemImage: "globe")
                                .font(.subheadline)
                        } else {
                            Label("Private", systemImage: "lock")
                                .font(.subheadline)
                        }
                    }
                    
                    Divider()
                    
                    // Event time
                    if let startTime = event.startTime {
                        HStack(alignment: .top) {
                            Image(systemName: "calendar")
                                .frame(width: 24)
                            
                            VStack(alignment: .leading) {
                                Text(formattedDate(startTime))
                                    .font(.headline)
                                
                                if let endTime = event.endTime {
                                    Text("\(formattedTime(startTime)) - \(formattedTime(endTime))")
                                        .font(.subheadline)
                                        .foregroundColor(.secondary)
                                } else {
                                    Text(formattedTime(startTime))
                                        .font(.subheadline)
                                        .foregroundColor(.secondary)
                                }
                            }
                            
                            Spacer()
                            
                            Button(action: {
                                // Add to calendar action
                            }) {
                                Text("Add to Calendar")
                                    .font(.subheadline)
                            }
                            .buttonStyle(.bordered)
                        }
                        
                        Divider()
                    }
                    
                    // Location
                    if let location = event.location, !location.isEmpty {
                        HStack(alignment: .top) {
                            Image(systemName: "location.fill")
                                .frame(width: 24)
                            
                            VStack(alignment: .leading) {
                                Text("Location")
                                    .font(.caption)
                                    .foregroundColor(.secondary)
                                Text(location)
                                    .font(.subheadline)
                            }
                            
                            Spacer()
                            
                            Button(action: {
                                // Open maps action
                            }) {
                                Text("Directions")
                                    .font(.subheadline)
                            }
                            .buttonStyle(.bordered)
                        }
                        
                        Divider()
                    }
                    
                    // Description
                    if let description = event.description, !description.isEmpty {
                        VStack(alignment: .leading, spacing: 8) {
                            Text("About")
                                .font(.headline)
                            
                            Text(description)
                                .font(.body)
                        }
                        
                        Divider()
                    }
                    
                    // Custom metadata display based on event type
                    if let metadata = event.metadata as? [String: Any] {
                        VStack(alignment: .leading, spacing: 8) {
                            Text("Details")
                                .font(.headline)
                            
                            // Render different UI elements based on event type
                            switch event.eventType {
                            case "social_post":
                                if let imageUrl = metadata["imageUrl"] as? String {
                                    // This would be an AsyncImage in a real app
                                    Text("Image: \(imageUrl)")
                                        .font(.caption)
                                }
                                if let hashtags = metadata["hashtags"] as? [String] {
                                    Text(hashtags.map { "#\($0)" }.joined(separator: " "))
                                        .font(.caption)
                                        .foregroundColor(.blue)
                                }
                            case "transaction":
                                if let amount = metadata["amount"] as? Double,
                                   let currency = metadata["currency"] as? String {
                                    HStack {
                                        Text("Amount:")
                                        Spacer()
                                        Text("\(amount) \(currency)")
                                            .fontWeight(.semibold)
                                    }
                                }
                                if let category = metadata["category"] as? String {
                                    HStack {
                                        Text("Category:")
                                        Spacer()
                                        Text(category.capitalized)
                                    }
                                }
                            default:
                                ForEach(Array(metadata.keys.sorted()), id: \.self) { key in
                                    if let value = metadata[key] {
                                        HStack {
                                            Text("\(key.capitalized):")
                                            Spacer()
                                            Text("\(String(describing: value))")
                                        }
                                    }
                                }
                            }
                        }
                        
                        Divider()
                    }
                    
                    // Action buttons
                    HStack {
                        Button(action: {
                            // Share event
                        }) {
                            HStack {
                                Image(systemName: "square.and.arrow.up")
                                Text("Share")
                            }
                            .frame(maxWidth: .infinity)
                        }
                        .buttonStyle(.bordered)
                        
                        Spacer()
                            .frame(width: 16)
                        
                        Button(action: {
                            // RSVP action
                        }) {
                            HStack {
                                Image(systemName: "checkmark.circle")
                                Text("RSVP")
                            }
                            .frame(maxWidth: .infinity)
                        }
                        .buttonStyle(.borderedProminent)
                    }
                }
                .padding()
            }
        }
        .navigationTitle("Event Details")
        .navigationBarTitleDisplayMode(.inline)
        .onAppear {
            loadEvent()
        }
    }
    
    private func loadEvent() {
        isLoading = true
        error = nil
        
        Task {
            do {
                let loadedEvent = try await ContactsService.shared.socialService.getEvent(
                    eventId: eventId
                )
                
                await MainActor.run {
                    self.event = loadedEvent
                    self.isLoading = false
                }
            } catch {
                await MainActor.run {
                    self.error = error
                    self.isLoading = false
                }
            }
        }
    }
    
    private func formattedDate(_ date: Date) -> String {
        let formatter = DateFormatter()
        formatter.dateStyle = .long
        formatter.timeStyle = .none
        return formatter.string(from: date)
    }
    
    private func formattedTime(_ date: Date) -> String {
        let formatter = DateFormatter()
        formatter.dateStyle = .none
        formatter.timeStyle = .short
        return formatter.string(from: date)
    }
}
```

This example demonstrates how to:

* Load and display event details
* Handle loading states and errors
* Format date and time information
* Create an intuitive layout with proper visual hierarchy
* Implement action buttons for user interaction
* Dynamically display different UI based on event type and metadata

## Best Practices for Events

1. **Validation**: Implement client-side validation for event data to ensure all required fields are filled correctly before submission
2. **Timezone Handling**: Be explicit about timezones when displaying event times to avoid confusion for users in different locations
3. **Cancellation Flow**: Implement a proper flow for cancelling or rescheduling events, including notifications to affected users
4. **Event Reminders**: Provide options for users to set reminders for events, improving user engagement and attendance
5. **Calendar Integration**: Make it easy for users to add events to their device calendars with a simple tap
6. **Pagination**: Implement proper pagination for event lists to maintain performance with large datasets
7. **Event Types**: Create a consistent taxonomy of event types across your app for better filtering and display
8. **Metadata Structure**: Document your metadata structure for different event types to ensure consistency

## Troubleshooting

### Common Issues

1. **Date Formatting Issues**
   * Ensure proper date formatting across different locales by testing on various device settings
   * Be explicit about timezones when working with event dates, especially for events with global attendance

2. **Event Visibility**
   * Check the `isPublic` flag when creating events to ensure proper visibility settings
   * Ensure proper permissions are set for viewing private events, especially in multi-user contexts

3. **Loading Performance**
   * Use pagination to improve performance when loading large event lists
   * Implement caching for frequently accessed events to reduce network requests
   * Consider prefetching upcoming events data to improve perceived performance
