Sorting a list of phone numbers by teleconference provider and location
Your first attempt

That seems to be a correct implementation, but the same array meeting.phoneNumbers
is filtered repeatedly, which is not very efficient. You could improve it by 
traversing the array once and assign each phone number to one of the four arrays:

func sortParsedNumbers(meeting: Meeting) -&gt; [String] {

    var unknownProviderNumbers: [String] = []
    var incorrectProviderNumbers: [String] = []
    var correctProviderNumbers: [String] = []
    var matchingLocationNumbers: [String] = []

    let userCountry = getUserLocation()
    for phoneNumber in meeting.phoneNumbers {
        // ... append `phoneNumber` to one of the four arrays ...
    }

    return matchingLocationNumbers + correctProviderNumbers + incorrectProviderNumbers + unknownProviderNumbers
}


But this does not scale well if more sorting criteria are added.
Which leads us to 

Your second attempt

There are two problems. First, you sort the arrays with comparison functions like this:

meeting.phoneNumbers.sorted { element, _ in
    someBooleanPredicate(element)
}


But the sorted(by:)
method requires that the given predicate is a "strict weak ordering over the elements",
in particular that


areInIncreasingOrder(a, a) is always false. (Irreflexivity)


and that condition is violated in your code.

Second, you chain multiple sorted(by:) calls. But the sorted() method
is not stable, which means that the later sort can destroy the result of the
previous sorts.

For both reasons, your code may give correct results, but you cannot rely on it.

So (unless you have a stable sort method, which the Swift standard library does not
yet provide), a multi-level sort must be done with a single call to sorted(by:).

Let's start with an example: Assume that you have a Person type with firstName
and lastName properties, then

persons.sort(by: { (lhs, rhs) in
    if lhs.lastName != rhs.lastName {
        return lhs.lastName &lt; rhs.lastName
    }
    return lhs.firstName &lt; rhs.firstName
})


would be a correct way of sorting an array with respect to the last name first,
and with respect to the first name second. This can be simplified to

persons.sort(by: { (lhs, rhs) in
    return (lhs.firstName, lhs.lastName) &lt; (rhs.firstName, rhs.lastName)
})


because the compiler automatically creates a &lt; operator for tuples of
comparable elements, implementing the lexicographical order.

In your case we have two criteria as well: provider and location. First we need some
type to describe and compare the desired sorting order for both criteria.
That could be just an Int, but an integer-based enum describes the intention more clearly:

enum ProviderStatus: Int, Comparable {
    case known
    case unknown
    case correct

    static func &lt;(lhs: ProviderStatus, rhs: ProviderStatus) -&gt; Bool {
        return lhs.rawValue &lt; rhs.rawValue
    }
}

enum LocationStatus: Int, Comparable {
    case notMatching
    case matching

    static func &lt;(lhs: LocationStatus, rhs: LocationStatus) -&gt; Bool {
        return lhs.rawValue &lt; rhs.rawValue
    }
}


Then you can compute a tuple describing the sorting order for each phone
number, and sort the numbers accordingly: 

func sortParsedNumbers(meeting: Meeting) -&gt; [String] {

    let userCountry = getUserLocation()

    func sortOrder(phoneNumber: String) -&gt; (ProviderStatus, LocationStatus) {
        let providerStatus = ...
        let locationStatus = ...
        return (providerStatus, locationStatus)
    }

    return meeting.phoneNumbers.sorted(by: { (lhs, rhs) in
        sortOrder(phoneNumber: lhs) &lt; sortOrder(phoneNumber: rhs)
    })
}


Adding more sorting criteria is straightforward with this approach.

A possible disadvantage is that sortOrder() can be called multiple times for the
same phone number during the sorting process. That can be avoided at the expense
of additional storage:

    return meeting.phoneNumbers
     .map { ($0, sortOrder(phoneNumber: $0))}
     .sorted { $1.1 &gt; $0.1 }
     .map { $0.0 }


The return expression maps each phone number to a (number, sortOrder) pair,
sorts the pairs according to the sort order, and finally extracts the phone number
again. This guarantees that the sortOrder() function is called only once
for each phone number.