Commit 0918042a authored by Mark Sands's avatar Mark Sands

Extracts SearchyKit

parent 12886130
github "ReactiveX/RxSwift" "3.0.0"
github "thoughtbot/Argo" "master"
github "thoughtbot/Curry" "master"
github "RxSugar/RxSugar" "v0.1.1"
version: 2
jobs:
build-and-test:
macos:
xcode: "9.3.0"
steps:
- checkout
- run:
name: Setup
command: bin/setup
- run:
name: Build and Test
command: bin/test -r
workflows:
version: 2
default:
jobs:
- build-and-test
# OS X Finder
.DS_Store
# Xcode per-user config
*.mode1
*.mode1v3
*.mode2v3
*.perspective
*.perspectivev3
*.pbxuser
xcuserdata
*.xccheckout
# Build products
build/
*.o
*.LinkFileList
*.hmap
# Automatic backup files
*~.nib/
*.swp
*~
*.dat
*.dep
# Cocoapods
Pods
# Carthage
Carthage/
# AppCode specific files
.idea/
*.iml
# Swift Package Manager
.build/
Packages/
Argo.framework.zip
*.xcscmblueprint
[submodule "Carthage/Checkouts/Runes"]
path = Carthage/Checkouts/Runes
url = https://github.com/thoughtbot/Runes.git
[submodule "Carthage/Checkouts/Curry"]
path = Carthage/Checkouts/Curry
url = https://github.com/thoughtbot/Curry.git
swift:
enabled: true
config_file: .swiftlint.yml
disabled_rules:
- variable_name
- line_length
set tabstop=2
set shiftwidth=2
let g:xcode_default_scheme = 'Argo-Mac'
/*:
**Note:** For **Argo** to be imported into the Playground, ensure that the **Argo-Mac** *scheme* is selected from the list of schemes.
* * *
*/
import Foundation
import Argo
import Curry
/*:
**Helper function** – load JSON from a file
*/
func JSONFromFile(file: String) -> AnyObject? {
return NSBundle.mainBundle().pathForResource(file, ofType: "json")
.flatMap { NSData(contentsOfFile: $0) }
.flatMap(JSONObjectWithData)
}
func JSONObjectWithData(data: NSData) -> AnyObject? {
do { return try NSJSONSerialization.JSONObjectWithData(data, options: []) }
catch { return .None }
}
/*:
## Decoding JSON into a simple **User** struct
The **User** struct has three properties, one of which is an Optional value.
(The example JSON file can be found in the **Resources** folder.)
*/
struct User {
let id: Int
let name: String
let email: String?
}
extension User: CustomStringConvertible {
var description: String {
return "name: \(name), id: \(id), email: \(email)"
}
}
extension User: Decodable {
static func decode(j: JSON) -> Decoded<User> {
return curry(self.init)
<^> j <| "id"
<*> j <| "name"
<*> j <|? "email"
}
}
/*:
* * *
*/
let user: User? = JSONFromFile("user_with_email").flatMap(decode)
print(user!)
<?xml version="1.0" encoding="UTF-8"?>
<Timeline
version = "3.0">
<TimelineItems>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=0&amp;EndingColumnNumber=9&amp;EndingLineNumber=67&amp;StartingColumnNumber=1&amp;StartingLineNumber=67&amp;Timestamp=455496627.584604"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=0&amp;EndingColumnNumber=11&amp;EndingLineNumber=71&amp;StartingColumnNumber=1&amp;StartingLineNumber=69&amp;Timestamp=455496627.584762"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=0&amp;EndingColumnNumber=12&amp;EndingLineNumber=73&amp;StartingColumnNumber=1&amp;StartingLineNumber=73&amp;Timestamp=455496627.584881"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=0&amp;EndingColumnNumber=9&amp;EndingLineNumber=67&amp;StartingColumnNumber=1&amp;StartingLineNumber=67&amp;Timestamp=455496627.584995"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=0&amp;EndingColumnNumber=11&amp;EndingLineNumber=67&amp;StartingColumnNumber=1&amp;StartingLineNumber=67&amp;Timestamp=455496627.585106"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=0&amp;EndingColumnNumber=12&amp;EndingLineNumber=67&amp;StartingColumnNumber=1&amp;StartingLineNumber=67&amp;Timestamp=455496627.585219"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=0&amp;EndingColumnNumber=10&amp;EndingLineNumber=75&amp;StartingColumnNumber=1&amp;StartingLineNumber=75&amp;Timestamp=455496627.58533"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=0&amp;EndingColumnNumber=23&amp;EndingLineNumber=75&amp;StartingColumnNumber=1&amp;StartingLineNumber=75&amp;Timestamp=455496627.585446"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=0&amp;EndingColumnNumber=20&amp;EndingLineNumber=75&amp;StartingColumnNumber=1&amp;StartingLineNumber=75&amp;Timestamp=455496627.585559"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=1681&amp;EndingColumnNumber=17&amp;EndingLineNumber=75&amp;StartingColumnNumber=1&amp;StartingLineNumber=75&amp;Timestamp=455498186.272651"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=0&amp;EndingColumnNumber=11&amp;EndingLineNumber=67&amp;StartingColumnNumber=1&amp;StartingLineNumber=67&amp;Timestamp=455496627.585782"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=0&amp;EndingColumnNumber=10&amp;EndingLineNumber=75&amp;StartingColumnNumber=1&amp;StartingLineNumber=75&amp;Timestamp=455496627.585894"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=0&amp;EndingColumnNumber=23&amp;EndingLineNumber=75&amp;StartingColumnNumber=1&amp;StartingLineNumber=75&amp;Timestamp=455496627.586006"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=0&amp;EndingColumnNumber=17&amp;EndingLineNumber=75&amp;StartingColumnNumber=1&amp;StartingLineNumber=75&amp;Timestamp=455496627.586117"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=0&amp;EndingColumnNumber=20&amp;EndingLineNumber=75&amp;StartingColumnNumber=1&amp;StartingLineNumber=75&amp;Timestamp=455496627.58623"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=0&amp;EndingColumnNumber=5&amp;EndingLineNumber=66&amp;StartingColumnNumber=1&amp;StartingLineNumber=66&amp;Timestamp=455496627.586343"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=0&amp;EndingColumnNumber=14&amp;EndingLineNumber=66&amp;StartingColumnNumber=1&amp;StartingLineNumber=66&amp;Timestamp=455496627.586456"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=0&amp;EndingColumnNumber=14&amp;EndingLineNumber=66&amp;StartingColumnNumber=1&amp;StartingLineNumber=66&amp;Timestamp=455496627.586569"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=0&amp;EndingColumnNumber=14&amp;EndingLineNumber=56&amp;StartingColumnNumber=1&amp;StartingLineNumber=56&amp;Timestamp=455496627.586678"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=0&amp;EndingColumnNumber=14&amp;EndingLineNumber=58&amp;StartingColumnNumber=1&amp;StartingLineNumber=58&amp;Timestamp=455496627.586787"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=0&amp;EndingColumnNumber=14&amp;EndingLineNumber=58&amp;StartingColumnNumber=1&amp;StartingLineNumber=58&amp;Timestamp=455496627.586894"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=0&amp;EndingColumnNumber=14&amp;EndingLineNumber=0&amp;StartingColumnNumber=1&amp;StartingLineNumber=0&amp;Timestamp=455491959.867682"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=9&amp;CharacterRangeLoc=1260&amp;EndingColumnNumber=15&amp;EndingLineNumber=56&amp;StartingColumnNumber=1&amp;StartingLineNumber=56&amp;Timestamp=455498186.273935"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=8&amp;CharacterRangeLoc=1260&amp;EndingColumnNumber=15&amp;EndingLineNumber=55&amp;StartingColumnNumber=1&amp;StartingLineNumber=55&amp;Timestamp=455498186.274038"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
</TimelineItems>
</Timeline>
/*:
**Note:** For **Argo** to be imported into the Playground, ensure that the **Argo-Mac** *scheme* is selected from the list of schemes.
* * *
*/
import Foundation
import Argo
import Curry
/*:
**Helper function** – load JSON from a file
*/
func JSONFromFile(file: String) -> AnyObject? {
return NSBundle.mainBundle().pathForResource(file, ofType: "json")
.flatMap { NSData(contentsOfFile: $0) }
.flatMap(JSONObjectWithData)
}
func JSONObjectWithData(data: NSData) -> AnyObject? {
do { return try NSJSONSerialization.JSONObjectWithData(data, options: []) }
catch { return .None }
}
/*:
During JSON decoding, a **String** representation of a date needs to be converted to a **NSDate**.
To achieve this, a **NSDateFormatter** and a helper function will be used.
*/
let jsonDateFormatter: NSDateFormatter = {
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssz"
return dateFormatter
}()
let toNSDate: String -> Decoded<NSDate> = {
.fromOptional(jsonDateFormatter.dateFromString($0))
}
/*:
## Decoding selected entries from the iTunes store JSON format
An example JSON file (**tropos.json**) can be found in the **resources** folder.
*/
struct App {
let name: String
let formattedPrice: String
let averageUserRating: Float?
let releaseDate: NSDate
}
extension App: CustomStringConvertible {
var description: String {
return "name: \(name)\nprice: \(formattedPrice), rating: \(averageUserRating), released: \(releaseDate)"
}
}
extension App: Decodable {
static func decode(j: JSON) -> Decoded<App> {
return curry(self.init)
<^> j <| "trackName"
<*> j <| "formattedPrice"
<*> j <|? "averageUserRating"
<*> (j <| "releaseDate" >>- toNSDate)
}
}
/*:
* * *
*/
let app: App? = (JSONFromFile("tropos")?["results"].flatMap(decode))?.first
print(app!)
{
"resultCount":1,
"results":[
{
"isGameCenterEnabled":false,
"screenshotUrls":[
"http://a5.mzstatic.com/us/r30/Purple5/v4/8b/3e/bd/8b3ebd2c-9dfe-1ce5-cdf5-8c89d854e375/screen322x572.jpeg",
"http://a1.mzstatic.com/us/r30/Purple5/v4/e6/4f/36/e64f369d-d453-f007-dd15-361d21641116/screen322x572.jpeg",
"http://a1.mzstatic.com/us/r30/Purple1/v4/74/77/cd/7477cd91-a094-3c22-fff1-cf75e7474dad/screen322x572.jpeg"
],
"ipadScreenshotUrls":[
],
"artworkUrl60":"http://is2.mzstatic.com/image/pf/us/r30/Purple3/v4/1b/b7/31/1bb731e3-a35a-9eaa-b13e-c536e639851c/AppIcon60x60_U00402x.png",
"artworkUrl512":"http://is4.mzstatic.com/image/pf/us/r30/Purple3/v4/e2/c5/42/e2c542e5-664e-36df-2285-490b7c16941e/mzl.ivsinquu.png",
"artistViewUrl":"https://itunes.apple.com/us/artist/thoughtbot-inc./id337354066?uo=4",
"kind":"software",
"features":[
],
"supportedDevices":[
"iPhone4S",
"iPadThirdGen4G",
"iPodTouchFifthGen",
"iPhone6",
"iPadMini4G",
"iPhone6Plus",
"iPadThirdGen",
"iPadFourthGen",
"iPad23G",
"iPad2Wifi",
"iPadFourthGen4G",
"iPadMini",
"iPhone5c",
"iPhone5",
"iPhone5s"
],
"advisories":[
],
"averageUserRatingForCurrentVersion":5.0,
"artworkUrl100":"http://is4.mzstatic.com/image/pf/us/r30/Purple3/v4/e2/c5/42/e2c542e5-664e-36df-2285-490b7c16941e/mzl.ivsinquu.png",
"trackCensoredName":"Tropos – Weather and forecasts for humans",
"languageCodesISO2A":[
"EN"
],
"fileSizeBytes":"2945254",
"sellerUrl":"http://troposweather.com",
"contentAdvisoryRating":"4+",
"userRatingCountForCurrentVersion":1,
"trackViewUrl":"https://itunes.apple.com/us/app/tropos-weather-forecasts-for/id955209376?mt=8&uo=4",
"trackContentRating":"4+",
"currency":"USD",
"wrapperType":"software",
"version":"1.0.1",
"artistId":337354066,
"artistName":"thoughtbot, inc.",
"genres":[
"Weather"
],
"price":0.99,
"description":"Weather and forecasts for humans. Information you can act on.\n\nMost weather apps throw a lot of information at you but that doesn't answer the question of \"What does it feel like outside?\". Tropos answers this by relating the current conditions to conditions the same time yesterday.\n\nFeatures:\n• Current conditions presented in plain language. For example, “It is warmer tonight than last night.”\n• Intelligent use of color to convey how it feels in your area compared to yesterday.\n• Simple, 3-day forecast that allows you to see how the next few days are trending.\n\nthoughtbot is dedicated to building the best possible application. Your feedback is invaluable to us. Get in touch at help@troposweather.com.",
"bundleId":"com.thoughtbot.carlweathers",
"genreIds":[
"6001"
],
"releaseDate":"2015-03-25T18:34:40Z",
"sellerName":"thoughtbot, inc.",
"trackId":955209376,
"trackName":"Tropos – Weather and forecasts for humans",
"primaryGenreName":"Weather",
"primaryGenreId":6001,
"releaseNotes":"- Fixed an issue where the app could crash if you're going buck-wild messing around with the pull to refresh control.\n- Improved the relative weather description in cases where it's crazy hot or ridiculously cold outside. Tropos will no longer tell you that it's hotter today when it's 10°F outside. (Sorry, Boston)\n- Fixed an issue where the high and low temperatures could be lower or higher than the current temperature, respectively. That's just silly.\n\nFinally, we want to thank everyone for supporting Tropos!",
"minimumOsVersion":"8.0",
"formattedPrice":"$0.99",
"averageUserRating":4.5,
"userRatingCount":10
}
]
}
<?xml version="1.0" encoding="UTF-8"?>
<Timeline
version = "3.0">
<TimelineItems>
</TimelineItems>
</Timeline>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='6.0' target-platform='osx' requires-full-environment='true' display-mode='rendered'/>
\ No newline at end of file
Pod::Spec.new do |spec|
spec.name = 'Argo'
spec.version = '4.1.2'
spec.summary = 'Functional JSON parsing library for Swift.'
spec.homepage = 'https://github.com/thoughtbot/Argo'
spec.license = { :type => 'MIT', :file => 'LICENSE' }
spec.author = {
'Gordon Fontenot' => 'gordon@thoughtbot.com',
'Tony DiPasquale' => 'tony@thoughtbot.com',
'thoughtbot' => nil,
}
spec.social_media_url = 'http://twitter.com/thoughtbot'
spec.source = { :git => 'https://github.com/thoughtbot/Argo.git', :tag => "v#{spec.version}" }
spec.source_files = 'Sources/**/*.{h,swift}'
spec.dependency 'Runes', '>= 4.0.0'
spec.requires_arc = true
spec.compiler_flags = '-whole-module-optimization'
spec.ios.deployment_target = '8.0'
spec.osx.deployment_target = '10.9'
spec.watchos.deployment_target = '2.0'
spec.tvos.deployment_target = '9.0'
end
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:Argo.xcodeproj">
</FileRef>
</Workspace>
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Argo.xcodeproj">
</FileRef>
<FileRef
location = "group:Carthage/Checkouts/Runes/Runes.xcodeproj">
</FileRef>
<FileRef
location = "group:Carthage/Checkouts/Curry/Curry.xcodeproj">
</FileRef>
</Workspace>
import Runes
// pure merge for Dictionaries
func + <T, U>(lhs: [T: U], rhs: [T: U]) -> [T: U] {
var merged = lhs
for (key, val) in rhs {
merged[key] = val
}
return merged
}
extension Dictionary {
func map<T>(_ f: (Value) -> T) -> [Key: T] {
var accum = Dictionary<Key, T>(minimumCapacity: self.count)
for (key, value) in self {
accum[key] = f(value)
}
return accum
}
}
func <^> <T, U, V>(f: (T) -> U, x: [V: T]) -> [V: U] {
return x.map(f)
}
import Foundation
extension NSNumber {
var isBool: Bool {
return CFBooleanGetTypeID() == CFGetTypeID(self)
}
}
/**
Default implementation of `Decodable` for `RawRepresentable` types using
`String` as the raw value.
*/
public extension Decodable where Self.DecodedType == Self, Self: RawRepresentable, Self.RawValue == String {
static func decode(_ json: JSON) -> Decoded<Self> {
switch json {
case let .string(s): return self.init(rawValue: s).map(pure) ?? .typeMismatch(expected: "rawValue for \(self)", actual: json)
default: return .typeMismatch(expected: "String", actual: json)
}
}
}
/**
Default implementation of `Decodable` for `RawRepresentable` types using
`Int` as the raw value.