Activities - GetStream/stream-swift GitHub Wiki

Adding Activities

let userFeed = Client.shared.flatFeed(feedSlug: "user")
let activity = Activity(actor: User.current!, verb: "pin", object: "Place:42")

userFeed?.add(activity) { result in
    if let activity = try? result.get() {
        // Added activity
        print(activity.id)
    }
}

Custom fields

// Create a custom Activity class.
final class ExerciseActivity: EnrichedActivity<User, String, DefaultReaction> {
    private enum CodingKeys: String, CodingKey {
        case course
        case participants
        case startDate = "started_at"
    }
    
    var course: Course
    var participants: [String] = []
    var startDate: Date = Date()
    
    init(verb: Verb, 
         object: String, 
         course: Course,
         participants: [String],
         startDate: Date = Date()) {
        super.init(actor: User.current!, verb: verb, object: object)
        self.course = course
        self.participants = participants
        self.startDate = startDate
    }
    
    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        course = try container.decode(Course.self, forKey: .course)
        participants = try container.decode([String].self, forKey: .participants)
        startDate = try container.decode(Date.self, forKey: .startDate)
        try super.init(from: decoder)
    }
    
    override public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(course, forKey: .course)
        try container.encode(participants, forKey: .participants)
        try container.encode(startDate, forKey: .startDate)
        try super.encode(to: encoder)
    }
}

struct Course: Codable {
    let name: String
    let distance: Float
}

let exerciseActivity = ExerciseActivity(verb: "run", 
                                        object: "Exercise:42", 
                                        course: Course(name: "Golden Gate Park", distance: 10), 
                                        participants: ["Thierry", "Tommaso"])

// Add the exercise activity to the user feed. 
userFeed?.add(exerciseActivity) { result in
    print(result)
}

// Get a list of exercise activities.
userFeed?.get(typeOf: ExerciseActivity.self) { result in
    print(result)
}

Retrieving Activities

// Get activities from 5 to 10.
userFeed?.get(pagination: .limit(5) + .offset(5)) { result in /* ... */ }

// Get the 5 activities added after lastActivity.
userFeed?.get(pagination: .limit(5) + .lessThan(lastActivity.id)) { result in /* ... */ }

// Get the 5 activities added before lastActivity.
userFeed?.get(pagination: .limit(5) + .greaterThan(lastActivity.id)) { result in /* ... */ }

// Get activities sorted by rank (Ranked Feeds Enabled).
userFeed?.get(pagination: .limit(5), ranking: "popularity") { result in /* ... */ }

// Get the 5 activities and enrich them with reactions and collections.
userFeed?.get(enrich: true, pagination: .limit(5), includeReactions: [.own, .latest, .counts]) { result in /* ... */ }

Removing Activities

// Remove an activity by its id.
userFeed?.remove(activityId: "50539e71-d6bf-422d-ad21-c8717df0c325")

// Remove activities foreign_id "run:1".
userFeed?.remove(foreignId: "run:1")

Updating Activities

// Create a custom activity with a `popularity` property.
let activity = Activity(actor: User.current!, verb: "like", object: "3", popularity: 100)

userFeed?.add(activity) { _ in
    activity.popularity = 10
    Client.shared.update(activities: [activity]) { result in /* ... */ }
}

Activity partial update

Client.shared.updateActivity(typeOf: ProductActivity.self,
                             setProperties: ["product.price": 19.99, 
                                             "shares": ["facebook": "...", "twitter": "..."]],
                             unsetProperties: ["daily_likes", "popularity"],
                             activityId: "54a60c1e-4ee3-494b-a1e3-50c06acb5ed4") { result in /* ... */ }

Client.shared.updateActivity(typeOf: ProductActivity.self,
                             setProperties: [...],
                             unsetProperties: [...],
                             foreignId: "product:123",
                             time: "2016-11-10T13:20:00.000000".streamDate!) { result in /* ... */ }

Uniqueness & Foreign ID

let firstActivity = Activity(actor: User.current!, verb: "add", object: "1", foreignId: "activity_1", time: Date())

// Add activity to activity feed:
var firstActivityId: String?
userFeed?.add(firstActivity) { result in
    let addedActivity = try! result.get()
    firstActivityId = addedActivity.id 
}

let secondActivity = Activity(actor: User.current!, verb: "add", object: "1", foreignId: "activity_2", time: Date())

var secondActivityId: String?
userFeed?.add(secondActivity) { result in
    let addedActivity = try! result.get()
    secondActivityId = addedActivity.id 
}

/// The unique combination of `foreignId` and `time` ensure that both
/// activities are unique and therefore the `firstActivityId != secondActivityId`

Advanced

Retrieving activities by ID

// retrieve two activities by ID:
Client.shared.get(typeOf: Activity.self, activityIds: ["01b3c1dd-e7ab-4649-b5b3-b4371d8f7045",
                                                       "ed2837a6-0a3b-4679-adc1-778a1704852d"]) { result in
    /* ... */ 
}

// retrieve an activity by foreign ID and time
Client.shared.get(typeOf: Activity.self, 
                  foreignIds: ["like:1", "post:2"],
                  times: ["2018-07-08T14:09:36.000000".streamDate!, "2018-07-09T20:30:40.000000".streamDate!]) { result in
    /* ... */ 
}