This library is a Swift implementation of the necessary code to check a domain name against the Public Suffix List and identify if the domains should be restricted.
Restricted domains should not be allowed to set cookies, directly host websites or send/receive emails.
As of January 2022, the list contained over 9k entries.
Due to the high number of entries in the Public Suffix list (>9k), you may want to pre-load on a background thread the PublicSuffixRulesRegistry.rules soon after launching the app. Initial loading of the list may require between 100ms to 900ms depending on the host device.
- The Public Suffix List is updated regularly, if your application is published regularly you may be fine by simply pulling the latest version of the SwiftPublicSuffixList library. However it is recommended to have your application retrieve the latest copy of the public suffix list on a somewhat regular basis.
LAST UPDATED: 2022-07-12 19:31:00 EST
You can run the Utilities/update-suffix.swift from the command line to download & process the text file containing the Public Suffix List and re-generate the PublicSuffixRulesRegistry.swift file.
# swift update-suffix.swift
In order to update the PublicSuffixList at runtime, you will want to make sure you use the instance of PublicSuffixList rather than the static functions. You can do this using:
import SwiftPublicSuffixList
let pathToLocalRegistry = FileManager.default
.urls(for: .cachesDirectory, in: .userDomainMask).first!
.appendingPathComponent("public-suffix-list.json")
let publicSuffixList = await PublicSuffixList.list(from: .filePath(pathToLocalRegistry))
To request a registry update:
let success: Bool = await publicSuffixList.updateUsingOnlineRegistry()
To save the updated registry:
try publicSuffixList.export(to: pathToLocalRegistry)
import SwiftPublicSuffixList
Using the default built-in Public Suffix List rules
if let match = PublicSuffixList.match("yahoo.com") {
// match.isRestricted == false
}
// or using a PublicSuffixList instance…
let publicSuffixList = PublicSuffixList()
if let match = publicSuffixList.match("yahoo.com") {
// match.isRestricted == false
}
// or the async equivalent
let publicSuffixList = await PublicSuffixList.list()
if let match = await publicSuffixList.match("yahoo.com") {
// match.isRestricted == false
}
Using a single custom validation rule, requiring domains to end with .com but allow any domain within the .com TLD
if let match = PublicSuffixList.match("yahoo.com", rules: [["com"]]) {
// match.isRestricted == false
// match.prevailingRule == ["com"]
// match.matchedRules == [["com"]]
}
// or using a PublicSuffixList instance…
let publicSuffixList = PublicSuffixList(source: .rules([["com"]]))
if let match = publicSuffixList.match("yahoo.com") {
// match.isRestricted == false
// match.prevailingRule == ["com"]
// match.matchedRules == [["com"]]
}
Using a single custom validation rule, restriction domains that end with .com but allowing any subdomain
if let match = PublicSuffixList.match("yahoo.com", rules: [["*","com"]]) {
// yahoo.com matches \*.com and so it is restricted
// match.isRestricted == true
// match.prevailingRule == ["*","com"]
// match.matchedRules == [["*","com"]]
}
if let match = PublicSuffixList.match("www.yahoo.com", [["*","com"]]) {
// While yahoo.co matches \*.com and is restricted, there are no
// restrictions for subdomains such as www.yahoo.com
// match.isRestricted == false
// match.prevailingRule == ["*","com"]
// match.matchedRules == [["*","com"]]
}
Defining an exception to a more generic rule
if let match = PublicSuffixList.match("yahoo.com", rules: [["*","com"],["!yahoo","com"]]) {
// Even if yahoo.com matches *.com, since there is an exception
// for this domain (defined using !) it will not be restricted
// match.isRestricted == false
// match.prevailingRule == ["!yahoo","com"]
// match.matchedRules == [["*","com"],["!yahoo","com"]]
}
Convenience function that will attempt to retrieve a match then return the value of !match.isRestricted. Will return false if no match was found.
if PublicSuffixList.isUnrestricted("yahoo.com") {
// true! yahoo.com is unrestricted by default
}
// or using PublicSuffixList instance…
let publicSuffixList = PublicSuffixList()
if publicSuffixList.isUnrestricted("yahoo.com") {
// true! yahoo.com is unrestricted by default
}