Skip to content

Commit fbea648

Browse files
author
Clément Le Provost
committed
Migrate User-Agent header to new format
- Update to new format (fixes #108). - Provide a more flexible and more strictly typed way of modifying the header through a `userAgents` property.
1 parent 488f7c3 commit fbea648

File tree

2 files changed

+43
-6
lines changed

2 files changed

+43
-6
lines changed

Source/Client.swift

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,24 @@
2424
import Foundation
2525

2626

27+
/// A version of a software library.
28+
/// Used to construct the `User-Agent` header.
29+
///
30+
@objc public class LibraryVersion: NSObject {
31+
@objc public let name: String
32+
@objc public let version: String
33+
34+
@objc public init(name: String, version: String) {
35+
self.name = name
36+
self.version = version
37+
}
38+
}
39+
40+
public func ==(lhs: LibraryVersion, rhs: LibraryVersion) -> Bool {
41+
return lhs.name == rhs.name && lhs.version == rhs.version
42+
}
43+
44+
2745
/// Entry point in the Swift API.
2846
///
2947
/// You should instantiate a Client object with your AppID, ApiKey and Hosts
@@ -41,9 +59,27 @@ import Foundation
4159

4260
@objc public var apiKey: String {
4361
didSet {
44-
headers["X-Algolia-API-Key"] = apiKey
62+
updateHeadersFromAPIKey()
63+
}
64+
}
65+
private func updateHeadersFromAPIKey() {
66+
headers["X-Algolia-API-Key"] = apiKey
67+
}
68+
69+
/// The list of libraries used by this client, passed in the `User-Agent` HTTP header of every request.
70+
/// It is initially set to contain only this API Client, but may be overridden to include other libraries.
71+
///
72+
/// * WARNING: The user agent is crucial to proper statistics in your Algolia dashboard. Please leave it as is.
73+
/// This field is publicly exposed only for the sake of other Algolia libraries.
74+
///
75+
@objc public var userAgents: [LibraryVersion] = [] {
76+
didSet {
77+
updateHeadersFromUserAgents()
4578
}
4679
}
80+
private func updateHeadersFromUserAgents() {
81+
headers["User-Agent"] = userAgents.map({ return "\($0.name) (\($0.version))"}).joinWithSeparator("; ")
82+
}
4783

4884
/// Default timeout for network requests. Default: 30".
4985
@objc public let timeout: NSTimeInterval = 30
@@ -94,6 +130,8 @@ import Foundation
94130
@objc public init(appID: String, apiKey: String) {
95131
self.appID = appID
96132
self.apiKey = apiKey
133+
let version = NSBundle(forClass: self.dynamicType).infoDictionary!["CFBundleShortVersionString"] as! String
134+
self.userAgents = [ LibraryVersion(name: "Algolia for Swift", version: version) ]
97135

98136
// Initialize hosts to their default values.
99137
//
@@ -112,7 +150,6 @@ import Foundation
112150
writeHosts = [ "\(appID).algolia.net" ] + fallbackHosts
113151

114152
// WARNING: Those headers cannot be changed for the lifetime of the session.
115-
let version = NSBundle(forClass: self.dynamicType).infoDictionary!["CFBundleShortVersionString"] as! String
116153
let fixedHTTPHeaders = [
117154
"X-Algolia-Application-Id": self.appID
118155
]
@@ -123,9 +160,9 @@ import Foundation
123160
super.init()
124161

125162
// Other headers are likely to change during the lifetime of the session: they will be passed for every request.
126-
headers["X-Algolia-API-Key"] = self.apiKey // necessary because `didSet` not called during initialization
127-
// NOTE: This one will not change... except it can be overridden by the offline client:
128-
headers["User-Agent"] = "Algolia for Swift \(version)"
163+
// WARNING: `didSet` not called during initialization => we need to update the headers manually here.
164+
updateHeadersFromAPIKey()
165+
updateHeadersFromUserAgents()
129166
}
130167

131168
/// Set an HTTP header that will be sent with every request.

Source/Offline/OfflineClient.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ import Foundation
4242
searchQueue.maxConcurrentOperationCount = 1
4343
rootDataDir = NSSearchPathForDirectoriesInDomains(.ApplicationSupportDirectory, .UserDomainMask, true).first! + "/algolia"
4444
super.init(appID: appID, apiKey: apiKey)
45-
headers["User-Agent"] = headers["User-Agent"]! + ";AlgoliaSearchOfflineCore-iOS \(sdk.versionString)"
45+
userAgents.append(LibraryVersion(name: "AlgoliaSearchOfflineCore-iOS", version: sdk.versionString))
4646
}
4747

4848
var sdk: ASSdk = ASSdk.sharedSdk()

0 commit comments

Comments
 (0)