├── Cartfile
├── Gemfile
├── .travis.yml
├── .gitignore
├── fastlane
├── Fastfile
└── Appfile
├── MTGSDKSwift.xcodeproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── xcuserdata
│ └── reedcarson.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
├── xcshareddata
│ └── xcschemes
│ │ ├── MTGSDKSwiftTests.xcscheme
│ │ └── MTGSDKSwift.xcscheme
└── project.pbxproj
├── MTGSDKSwift
├── Models
│ ├── NetworkError.swift
│ ├── CardSet.swift
│ ├── MTGSearchConfiguration.swift
│ ├── Constants.swift
│ ├── SearchParameter.swift
│ └── Card.swift
├── MTGSDKSwift.h
├── Info.plist
├── URLBuilder.swift
├── MTGAPIService.swift
└── MagicalCardManager.swift
├── TestApplication
├── AppDelegate.swift
├── ViewController.swift
├── Info.plist
├── Base.lproj
│ ├── Main.storyboard
│ └── LaunchScreen.storyboard
└── Assets.xcassets
│ └── AppIcon.appiconset
│ └── Contents.json
├── .github
└── PULL_REQUEST_TEMPLATE.MD
├── MTGSDKSwiftTests
├── Info.plist
├── MTGSDKSwiftTests.swift
└── Resources
│ └── karn.json
├── Package.swift
├── MTGSDKSwift.podspec
├── LICENSE
├── Gemfile.lock
└── README.md
/Cartfile:
--------------------------------------------------------------------------------
1 | github "MagicTheGathering/mtg-sdk-swift" ~> 0.1
2 |
3 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 |
3 | gem "fastlane"
4 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: objective-c
2 | osx_image: xcode10
3 | script:
4 | - bundle exec fastlane test
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | .DS_Store
3 | xcuserdata
4 |
5 | # Fastlane
6 | fastlane/README.md
7 | fastlane/report.xml
8 | fastlane/test_output/
9 |
--------------------------------------------------------------------------------
/fastlane/Fastfile:
--------------------------------------------------------------------------------
1 |
2 | update_fastlane
3 |
4 | default_platform(:ios)
5 |
6 | platform :ios do
7 | desc "Runs the tests"
8 | lane :test do
9 | scan(scheme: 'MTGSDKSwift')
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/MTGSDKSwift.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/MTGSDKSwift.xcodeproj/xcuserdata/reedcarson.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/fastlane/Appfile:
--------------------------------------------------------------------------------
1 | # app_identifier("[[APP_IDENTIFIER]]") # The bundle identifier of your app
2 | # apple_id("[[APPLE_ID]]") # Your Apple email address
3 |
4 |
5 | # For more information about the Appfile, see:
6 | # https://docs.fastlane.tools/advanced/#appfile
7 |
--------------------------------------------------------------------------------
/MTGSDKSwift.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/MTGSDKSwift/Models/NetworkError.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NetworkError.swift
3 | // MTGSDKSwift
4 | //
5 | // Created by Reed Carson on 3/3/17.
6 | // Copyright © 2017 Reed Carson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public enum NetworkError: Error {
12 | case requestError(Error)
13 | case unexpectedHTTPResponse(HTTPURLResponse)
14 | case fetchCardImageError(String)
15 | case miscError(String)
16 | case decodableError(Error)
17 | }
18 |
--------------------------------------------------------------------------------
/MTGSDKSwift/MTGSDKSwift.h:
--------------------------------------------------------------------------------
1 | //
2 | // MTGSDKSwift.h
3 | // MTGSDKSwift
4 | //
5 | // Created by Reed Carson on 2/27/17.
6 | // Copyright © 2017 Reed Carson. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for MTGSDKSwift.
12 | FOUNDATION_EXPORT double MTGSDKSwiftVersionNumber;
13 |
14 | //! Project version string for MTGSDKSwift.
15 | FOUNDATION_EXPORT const unsigned char MTGSDKSwiftVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/TestApplication/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // TestApplication
4 | //
5 | // Created by Reed Carson on 3/14/18.
6 | // Copyright © 2018 Reed Carson. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/MTGSDKSwift/Models/CardSet.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CardSet.swift
3 | // MTGSDKSwift
4 | //
5 | // Created by Reed Carson on 2/27/17.
6 | // Copyright © 2017 Reed Carson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public struct CardSet: Decodable {
12 | public init() {}
13 |
14 | public var code: String?
15 | public var name: String?
16 | public var block: String?
17 | public var type: String?
18 | public var border: String?
19 | public var releaseDate: String?
20 | public var magicCardsInfoCode: String?
21 | public var booster: [[String]]?
22 | }
23 |
24 | public struct SetsResponse: ResponseObject, Decodable {
25 | public var sets: [CardSet]
26 | }
27 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.MD:
--------------------------------------------------------------------------------
1 | ### Background
2 | Describe the purpose of this pull request.
3 |
4 | ### Breaking Changes
5 | Describe any breaking changes that this pull request will introduce.
6 |
7 |
8 | ### Checklist
9 |
10 | - [ ] Appropriate label has been added to this PR (i.e., Bug, Enhancement, etc.).
11 | - [ ] Documentation has been added to all `open`, `public`, and `internal` scoped methods and properties.
12 | - [ ] Tests have have been added to all new features.
13 | - [ ] Image/GIFs have been added for all UI related changed.
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/MTGSDKSwiftTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/MTGSDKSwift/Models/MTGSearchConfiguration.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MTGSearchConfiguration.swift
3 | // MTGSDKSwift
4 | //
5 | // Created by Reed Carson on 4/16/18.
6 | // Copyright © 2018 Reed Carson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public struct MTGSearchConfiguration {
12 | public static var defaultConfiguration: MTGSearchConfiguration {
13 | return MTGSearchConfiguration(pageSize: Int(Constants.defaultPageSize) ?? 12,
14 | pageTotal: Int(Constants.defaultPageTotal) ?? 1)
15 | }
16 |
17 | public let pageSize: Int
18 | public let pageTotal: Int
19 |
20 | public init(pageSize: Int, pageTotal: Int) {
21 | self.pageSize = pageSize
22 | self.pageTotal = pageTotal
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.5
2 | // The swift-tools-version declares the minimum version of Swift required to build this package.
3 |
4 | import PackageDescription
5 |
6 | let package = Package(
7 | name: "MTGSDKSwift",
8 | platforms: [
9 | .iOS(.v15),
10 | .macOS(.v12)
11 | ],
12 | products: [
13 | .library(
14 | name: "MTGSDKSwift",
15 | targets: ["MTGSDKSwift"]),
16 | ],
17 | dependencies: [],
18 | targets: [
19 | .target(
20 | name: "MTGSDKSwift",
21 | dependencies: [],
22 | path: "MTGSDKSwift"
23 | ),
24 | .testTarget(
25 | name: "MTGSDKSwiftTests",
26 | dependencies: [],
27 | path: "MTGSDKSwiftTests"
28 | ),
29 | ]
30 | )
31 |
--------------------------------------------------------------------------------
/MTGSDKSwift.podspec:
--------------------------------------------------------------------------------
1 | #
2 | # Be sure to run `pod lib lint mtg-sdk-swift.podspec' to ensure this is a
3 | # valid spec before submitting.
4 | #
5 |
6 | Pod::Spec.new do |s|
7 | s.name = 'MTGSDKSwift'
8 | s.version = '1.1.1'
9 | s.summary = 'Magic: The Gathering SDK - Swift'
10 | s.description = <<-DESC
11 | A lightweight framework that makes interacting with the magicthegathering.io api quick, easy and safe.
12 | DESC
13 |
14 | s.homepage = 'https://github.com/MagicTheGathering/mtg-sdk-swift'
15 | s.license = { :type => 'MIT', :file => 'LICENSE' }
16 | s.author = { 'Reed Carson' => 'rpcarson27@gmail.com' }
17 | s.source = { :git => 'https://github.com/MagicTheGathering/mtg-sdk-swift.git', :tag => s.version.to_s }
18 |
19 | s.ios.deployment_target = '10.2'
20 | s.osx.deployment_target = '12.4'
21 | s.source_files = 'MTGSDKSwift/**/*.swift'
22 | s.swift_version = '4.1'
23 | end
24 |
--------------------------------------------------------------------------------
/MTGSDKSwift.xcodeproj/xcuserdata/reedcarson.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | MTGSDKSwift.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 | MTGSDKSwiftTests.xcscheme_^#shared#^_
13 |
14 | orderHint
15 | 1
16 |
17 | TestApplication.xcscheme
18 |
19 | orderHint
20 | 1
21 |
22 | TestApplication.xcscheme_^#shared#^_
23 |
24 | orderHint
25 | 2
26 |
27 |
28 | SuppressBuildableAutocreation
29 |
30 | 5BD04DB11E64943C00E5ED27
31 |
32 | primary
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017 Reed Carson
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/MTGSDKSwift/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | $(MARKETING_VERSION)
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSAppTransportSecurity
22 |
23 | NSExceptionDomains
24 |
25 | wizards.com
26 |
27 | NSIncludesSubdomains
28 |
29 | NSTemporaryExceptionAllowsInsecureHTTPLoads
30 |
31 | NSTemporaryExceptionMinimumTLSVersion
32 | TLSv1.1
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/TestApplication/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // TestApplication
4 | //
5 | // Created by Reed Carson on 3/14/18.
6 | // Copyright © 2018 Reed Carson. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import MTGSDKSwift
11 |
12 | class ViewController: UIViewController {
13 |
14 | let magic = Magic()
15 |
16 | override func viewDidLoad() {
17 | super.viewDidLoad()
18 |
19 | let color = CardSearchParameter(parameterType: .colors, value: "black")
20 | let type = CardSearchParameter(parameterType: .type, value: "planeswalker")
21 | let loyal = CardSearchParameter(parameterType: .loyalty, value: "5")
22 | let legal = CardSearchParameter(parameterType: .legality, value: "Banned")
23 | let config = MTGSearchConfiguration(pageSize: 60, pageTotal: 1)
24 |
25 | magic.fetchCards([color], configuration: config) { (result) in
26 | switch result {
27 | case .error(let error):
28 | print(error.localizedDescription)
29 | case .success(let cards):
30 | print("CARDS COUNT: \(cards.count)")
31 | for c in cards {
32 | print("Card: \(c) \n")
33 | }
34 | }
35 | }
36 | }
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/MTGSDKSwift/Models/Constants.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Constants.swift
3 | // MTGSDKSwift
4 | //
5 | // Created by Reed Carson on 4/16/18.
6 | // Copyright © 2018 Reed Carson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | struct Constants {
12 | static let baseEndpoint = "https://api.magicthegathering.io/v1"
13 | static let generateBoosterPath = "/booster"
14 | static let cardsEndpoint = "/v1/cards"
15 | static let setsEndpoint = "/v1/sets"
16 | static let host = "api.magicthegathering.io"
17 | static let scheme = "https"
18 | static let defaultPageSize = "12"
19 | static let defaultPageTotal = "1"
20 | }
21 |
22 | /// If logging is enabled, this function performs debug logging to the console for you with the
23 | /// context of where it came from.
24 | /// ## Example
25 | /// ```
26 | /// [MTGAPIService.swift:67:performOperation(completion:)]: MTGSDK HTTPResponse - status code: 200
27 | /// ```
28 | ///
29 | /// - Parameters:
30 | /// - message: The message you'd like logged.
31 | /// - file: The message source code file.
32 | /// - function: The message source function.
33 | /// - line: The message source line.
34 | func debugPrint(_ message: String, file: String = #file, function: String = #function, line: Int = #line ) {
35 | guard Magic.enableLogging else {
36 | return
37 | }
38 | print("[\((file as NSString).lastPathComponent):\(line):\(function)]: \(message)")
39 | }
40 |
--------------------------------------------------------------------------------
/MTGSDKSwift/Models/SearchParameter.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SearchParameter.swift
3 | // MTGSDKSwift
4 | //
5 | // Created by Reed Carson on 2/27/17.
6 | // Copyright © 2017 Reed Carson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 | public class SearchParameter {
13 | public var name: String = ""
14 | public var value: String = ""
15 | }
16 |
17 | public final class CardSearchParameter: SearchParameter {
18 |
19 | public enum CardQueryParameterType: String {
20 | case name
21 | case cmc
22 | case colors
23 | case contains
24 | case type
25 | case supertypes
26 | case subtypes
27 | case rarity
28 | case text
29 | case set
30 | case artist
31 | case power
32 | case toughness
33 | case multiverseid
34 | case gameFormat
35 | case loyalty
36 | case legality
37 | case releaseDate
38 | }
39 |
40 | public init(parameterType: CardQueryParameterType, value: String) {
41 | super.init()
42 | self.name = parameterType.rawValue
43 | self.value = value
44 | }
45 | }
46 |
47 | public final class SetSearchParameter: SearchParameter {
48 |
49 | public enum SetQueryParameterType: String {
50 | case name
51 | case block
52 | }
53 |
54 | public init(parameterType: SetQueryParameterType, value: String) {
55 | super.init()
56 | self.name = parameterType.rawValue
57 | self.value = value
58 |
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/TestApplication/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/TestApplication/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/TestApplication/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/TestApplication/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | }
88 | ],
89 | "info" : {
90 | "version" : 1,
91 | "author" : "xcode"
92 | }
93 | }
--------------------------------------------------------------------------------
/MTGSDKSwift/URLBuilder.swift:
--------------------------------------------------------------------------------
1 | //
2 | // URLBuilder.swift
3 | // MTGSDKSwift
4 | //
5 | // Created by Reed Carson on 4/5/18.
6 | // Copyright © 2018 Reed Carson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | final class URLBuilder {
12 | static func buildURLWithParameters(_ parameters: [SearchParameter],
13 | andConfig config: MTGSearchConfiguration = MTGSearchConfiguration.defaultConfiguration) -> URL? {
14 | var urlComponents = URLComponents()
15 | urlComponents.scheme = Constants.scheme
16 | urlComponents.host = Constants.host
17 | urlComponents.path = {
18 | if parameters is [CardSearchParameter] {
19 | return Constants.cardsEndpoint
20 | } else {
21 | return Constants.setsEndpoint
22 | }
23 | }()
24 |
25 | urlComponents.queryItems = buildQueryItemsFromParameters(parameters, config)
26 |
27 | debugPrint("MTGSDK URL: \(String(describing: urlComponents.url))\n")
28 |
29 | return urlComponents.url
30 | }
31 |
32 | private static func buildQueryItemsFromParameters(_ parameters: [SearchParameter],
33 | _ config: MTGSearchConfiguration = MTGSearchConfiguration.defaultConfiguration) -> [URLQueryItem] {
34 | var queryItems = [URLQueryItem]()
35 |
36 | let pageSizeQuery = URLQueryItem(name: "pageSize", value: String(config.pageSize))
37 | let pageQuery = URLQueryItem(name: "page", value: String(config.pageTotal))
38 | queryItems.append(pageQuery)
39 | queryItems.append(pageSizeQuery)
40 |
41 | for parameter in parameters {
42 | let name = parameter.name
43 | let value = parameter.value
44 | let item = URLQueryItem(name: name, value: value)
45 | queryItems.append(item)
46 | }
47 |
48 | return queryItems
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/MTGSDKSwift/Models/Card.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Card.swift
3 | // mtg-sdk-swift
4 | //
5 | // Created by Reed Carson on 2/24/17.
6 | // Copyright © 2017 Reed Carson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public struct Card: Equatable, Decodable {
12 | public init() {}
13 |
14 | public var name: String?
15 | public var names: [String]?
16 | public var manaCost: String?
17 | public var cmc: Int?
18 | public var colors: [String]?
19 | public var colorIdentity: [String]?
20 | public var type: String?
21 | public var supertypes: [String]?
22 | public var types: [String]?
23 | public var subtypes: [String]?
24 | public var rarity: String?
25 | public var set: String?
26 | public var setName: String?
27 | public var text: String?
28 | public var artist: String?
29 | public var number: String?
30 | public var power: String?
31 | public var toughness: String?
32 | public var layout: String?
33 | public var multiverseid: String?
34 | public var imageUrl: String?
35 | public var rulings: [[String:String]]?
36 | public var foreignNames: [ForeignName]?
37 | public var printings: [String]?
38 | public var originalText: String?
39 | public var originalType: String?
40 | public var id: String?
41 | public var flavor: String?
42 | public var loyalty: String?
43 | public var gameFormat: String?
44 | public var releaseDate: String?
45 | public var legalities: [Legality]?
46 |
47 | public static func ==(lhs: Card, rhs: Card) -> Bool {
48 | return lhs.id == rhs.id
49 | }
50 | }
51 |
52 | public struct ForeignName: Decodable {
53 | public var name: String
54 | public var language: String
55 | public var multiverseid: Int?
56 | }
57 |
58 | public struct Legality: Decodable {
59 | public var format: String
60 | public var legality: String
61 | }
62 |
63 | public struct CardsResponse: ResponseObject, Decodable {
64 | public var cards: [Card]
65 | }
66 |
--------------------------------------------------------------------------------
/MTGSDKSwift.xcodeproj/xcshareddata/xcschemes/MTGSDKSwiftTests.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
14 |
15 |
17 |
23 |
24 |
25 |
26 |
27 |
37 |
38 |
44 |
45 |
47 |
48 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/MTGSDKSwift.xcodeproj/xcshareddata/xcschemes/MTGSDKSwift.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
40 |
42 |
48 |
49 |
50 |
51 |
52 |
62 |
63 |
69 |
70 |
71 |
72 |
78 |
79 |
85 |
86 |
87 |
88 |
90 |
91 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/MTGSDKSwiftTests/MTGSDKSwiftTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MTGSDKSwiftTests.swift
3 | // MTGSDKSwiftTests
4 | //
5 | // Created by Reed Carson on 2/27/17.
6 | // Copyright © 2017 Reed Carson. All rights reserved.
7 | //
8 |
9 | import MTGSDKSwift
10 | import XCTest
11 |
12 | class MTGSDKSwiftTests: XCTestCase {
13 |
14 | var magic: Magic = Magic()
15 |
16 | override func setUp() {
17 | super.setUp()
18 | }
19 | }
20 |
21 | // MARK: - Card Search Tests
22 |
23 | extension MTGSDKSwiftTests {
24 |
25 | func testCardSearchNoResults() {
26 | let param = CardSearchParameter(parameterType: .name, value: "abcdefghijk")
27 | let exp = expectation(description: "fetchCards")
28 |
29 | magic.fetchCards([param]) { (result) in
30 | defer {
31 | exp.fulfill()
32 | }
33 |
34 | switch result {
35 | case .success(let cards):
36 | XCTAssertTrue(cards.count == 0)
37 | case .error(let error):
38 | XCTFail("Error fetching cards: \(error.localizedDescription)")
39 | }
40 | }
41 | waitForExpectations(timeout: 10, handler: nil)
42 | }
43 |
44 | func testCardSearchWithCards() {
45 | let param = CardSearchParameter(parameterType: .name, value: "lotus")
46 | let exp = expectation(description: "fetchCards")
47 |
48 | magic.fetchCards([param]) { (result) in
49 | defer {
50 | exp.fulfill()
51 | }
52 |
53 | switch result {
54 | case .success(let cards):
55 | XCTAssertTrue(cards.count > 0)
56 | case .error(let error):
57 | XCTFail("Error fetching cards: \(error.localizedDescription)")
58 | }
59 | }
60 | waitForExpectations(timeout: 10, handler: nil)
61 | }
62 | }
63 |
64 | // MARK: - Fetch Planeswalker
65 |
66 | extension MTGSDKSwiftTests {
67 |
68 | func testFetchKarnAndVerify() {
69 | let param = CardSearchParameter(parameterType: .name, value: "Karn Liberated")
70 |
71 | let exp = expectation(description: "fetchCards")
72 |
73 | magic.fetchCards([param]) { (result) in
74 | defer {
75 | exp.fulfill()
76 | }
77 |
78 | switch result {
79 | case .success(let cards):
80 | guard let card = cards.first(where: {$0.id == "fc5dff7e-489f-5a42-bf3f-926985aaef4a" }) else {
81 | XCTFail("unable to fetch expected test card")
82 | return
83 | }
84 | XCTAssertEqual("Karn Liberated", card.name)
85 | XCTAssertEqual("6", cards.first?.loyalty)
86 | XCTAssertEqual("{7}", card.manaCost)
87 | XCTAssertEqual(7, card.cmc)
88 | XCTAssertEqual(nil, card.colors)
89 | XCTAssertEqual(nil, card.colorIdentity)
90 | XCTAssertEqual("Legendary Planeswalker — Karn", card.type)
91 | XCTAssertEqual(["Legendary"], card.supertypes)
92 | case .error(let error):
93 | XCTFail("Error fetching cards: \(error.localizedDescription)")
94 | }
95 | }
96 | waitForExpectations(timeout: 10, handler: nil)
97 | }
98 | }
99 |
100 | // MARK: - Fetch Image Tests
101 |
102 | extension MTGSDKSwiftTests {
103 | func testFetchValidImage() {
104 | var card = Card()
105 | card.imageUrl = "http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=391870&type=card"
106 |
107 | let exp = expectation(description: "fetchImageForCard")
108 |
109 | magic.fetchImageForCard(card) { (result) in
110 | defer {
111 | exp.fulfill()
112 | }
113 |
114 | switch result {
115 | case .success:
116 | break
117 | case .error(let error):
118 | XCTFail("Error getting image: \(error.localizedDescription)")
119 | }
120 | }
121 |
122 | waitForExpectations(timeout: 10, handler: nil)
123 | }
124 |
125 | func testFetchImageError() {
126 | let card = Card()
127 | let exp = expectation(description: "fetchImageForCard")
128 |
129 | magic.fetchImageForCard(card) { (result) in
130 | defer {
131 | exp.fulfill()
132 | }
133 |
134 | switch result {
135 | case .success:
136 | XCTFail("Got an image back for a card without an image")
137 | case .error:
138 | break
139 | }
140 | }
141 |
142 | waitForExpectations(timeout: 10, handler: nil)
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/MTGSDKSwift/MTGAPIService.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MTGAPIService.swift
3 | // mtg-sdk-swift
4 | //
5 | // Created by Reed Carson on 2/24/17.
6 | // Copyright © 2017 Reed Carson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public typealias JSONResults = [String:Any]
12 | typealias JSONDataCompletion = (Result<(data: Data, json: JSONResults)>) -> Void
13 |
14 | public enum Result {
15 | case success(T)
16 | case error(NetworkError)
17 | }
18 |
19 | protocol ResponseObject: Decodable {}
20 |
21 | final class MTGAPIService {
22 |
23 | /// Performs A query against the MTG APIs and calls back to the provided completion handler
24 | /// with a success or failure.
25 | ///
26 | /// - Parameters:
27 | /// - url: The MTG URL to hit.
28 | /// - completion: The completion handler block to handle the response.
29 | func mtgAPIQuery(url: URL, responseObject: T.Type, completion: @escaping (Result) -> Void) {
30 | let networkOperation = NetworkOperation(url: url)
31 | networkOperation.performOperation {
32 | result in
33 | switch result {
34 | case .success(let json):
35 | do {
36 | let result = try JSONDecoder().decode(T.self, from: json.data)
37 | completion(Result.success(result))
38 | } catch {
39 | completion(Result.error(NetworkError.decodableError(error)))
40 | }
41 | case .error(let error):
42 | completion(Result.error(error))
43 | }
44 | }
45 | }
46 |
47 | @available(iOS 15.0, *)
48 | func mtgAPIQuery(url: URL, responseObject: T.Type) async throws -> T {
49 | let networkOperation = NetworkOperation(url: url)
50 |
51 | let responseData = try await networkOperation.performOperation()
52 |
53 | do {
54 | return try JSONDecoder().decode(T.self, from: responseData)
55 | } catch {
56 | throw NetworkError.decodableError(error)
57 | }
58 | }
59 |
60 | func jsonQuery(url: URL, completion: @escaping (Result) -> Void) {
61 | let networkOperation = NetworkOperation(url: url)
62 | networkOperation.performOperation {
63 | result in
64 | switch result {
65 | case .success(let json):
66 | completion(Result.success(json.json))
67 | case .error(let error):
68 | completion(Result.error(error))
69 | }
70 | }
71 | }
72 | }
73 |
74 | final private class NetworkOperation {
75 | let url: URL
76 |
77 | init(url: URL) {
78 | self.url = url
79 | }
80 |
81 | func performOperation(completion: @escaping JSONDataCompletion) {
82 | URLSession.shared.dataTask(with: URLRequest(url: url)) { (data, response, error) in
83 | if let error = error {
84 | return completion(Result.error(NetworkError.requestError(error)))
85 | }
86 |
87 | guard let data = data else {
88 | return completion(Result.error(NetworkError.miscError("Network operation - No data returned")))
89 | }
90 |
91 | if let httpResponse = (response as? HTTPURLResponse) {
92 | debugPrint("MTGSDK HTTPResponse - status code: \(httpResponse.statusCode)")
93 |
94 | switch httpResponse.statusCode {
95 | case 200..<300:
96 | break
97 | default:
98 | return completion(Result.error(NetworkError.unexpectedHTTPResponse(httpResponse)))
99 | }
100 | }
101 |
102 | do {
103 | let jsonResponse = try JSONSerialization.jsonObject(with: data, options: [])
104 | guard let json = jsonResponse as? JSONResults else {
105 | return completion(Result.error(NetworkError.miscError("Network operation - invalid json response")))
106 | }
107 | completion(Result.success((data, json)))
108 | } catch {
109 | completion(Result.error(NetworkError.miscError("json serialization error")))
110 | }
111 | }.resume()
112 | }
113 |
114 | @available(iOS 15.0, *)
115 | func performOperation() async throws -> Data {
116 | let (data, response) = try await URLSession.shared.data(for: URLRequest(url: url))
117 |
118 | guard data.count > 0 else {
119 | throw NetworkError.miscError("Network operation - No data returned")
120 | }
121 |
122 | if let httpResponse = (response as? HTTPURLResponse) {
123 | debugPrint("MTGSDK HTTPResponse - status code: \(httpResponse.statusCode)")
124 | switch httpResponse.statusCode {
125 | case 200..<300:
126 | break
127 | default:
128 | throw NetworkError.unexpectedHTTPResponse(httpResponse)
129 | }
130 | }
131 |
132 | return data
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/MTGSDKSwiftTests/Resources/karn.json:
--------------------------------------------------------------------------------
1 | {
2 | "cards": [
3 | {
4 | "name": "Karn Liberated",
5 | "manaCost": "{7}",
6 | "cmc": 7,
7 | "type": "Legendary Planeswalker — Karn",
8 | "supertypes": [
9 | "Legendary"
10 | ],
11 | "types": [
12 | "Planeswalker"
13 | ],
14 | "subtypes": [
15 | "Karn"
16 | ],
17 | "rarity": "Mythic Rare",
18 | "set": "MM2",
19 | "setName": "Modern Masters 2015 Edition",
20 | "text": "+4: Target player exiles a card from their hand.\n−3: Exile target permanent.\n−14: Restart the game, leaving in exile all non-Aura permanent cards exiled with Karn Liberated. Then put those cards onto the battlefield under your control.",
21 | "artist": "Jason Chan",
22 | "number": "4",
23 | "layout": "normal",
24 | "multiverseid": 397828,
25 | "imageUrl": "http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=397828&type=card",
26 | "loyalty": 6,
27 | "rulings": [
28 | {
29 | "date": "2011-06-01",
30 | "text": "Karn's first and third abilities are linked. Similarly, Karn's second and third abilities are linked. Only cards exiled by either of Karn's first two abilities will remain in exile when the game restarts."
31 | },
32 | {
33 | "date": "2011-06-01",
34 | "text": "A game that restarts immediately ends. The players in that game then immediately begin a new game. No player wins, loses, or draws the original game as a result of Karn's ability."
35 | },
36 | {
37 | "date": "2011-06-01",
38 | "text": "In a multiplayer games (a game that started with three or more players in it), any player that left the game before it was restarted with Karn's ability won't be involved in the new game."
39 | },
40 | {
41 | "date": "2011-06-01",
42 | "text": "The player who controlled the ability that restarted the game is the starting player in the new game. The new game starts like a game normally does: -- Each player shuffles their deck (except the cards left in exile by Karn's ability). -- Each player's life total becomes 20 (or the starting life total for whatever format you're playing). -- Players draw a hand of seven cards. Players may take mulligans. -- Players may take actions based on cards in their opening hands, such as Chancellors and Leylines."
43 | },
44 | {
45 | "date": "2011-06-01",
46 | "text": "After the pre-game procedure is complete, but before the new game's first turn, Karn's ability finishes resolving and the cards left in exile are put onto the battlefield. If this causes any triggered abilities to trigger, those abilities are put onto the stack at the beginning of the first upkeep step."
47 | },
48 | {
49 | "date": "2011-06-01",
50 | "text": "Creatures put onto the battlefield due to Karn's ability will have been under their controller's control continuously since the beginning of the first turn. They can attack and their activated abilities with {T} in the cost can be activated."
51 | },
52 | {
53 | "date": "2011-06-01",
54 | "text": "Any permanents put onto the battlefield with Karn's ability that entered the battlefield tapped will untap during their controller's first untap step."
55 | },
56 | {
57 | "date": "2011-06-01",
58 | "text": "No actions taken in the game that was restarted apply to the new game. For example, if you were dealt damage by Stigma Lasher in the original game, the effect that states you can't gain life doesn't carry over to the new game."
59 | },
60 | {
61 | "date": "2011-06-01",
62 | "text": "Players won't have any poison counters or emblems they had in the original game."
63 | },
64 | {
65 | "date": "2011-06-01",
66 | "text": "In a Commander game, players put their commanders into the command zone before shuffling their deck."
67 | },
68 | {
69 | "date": "2011-06-01",
70 | "text": "The number of times a player has cast their commander from the command zone resets to zero. Also, the amount of combat damage dealt to players by each commander is reset to 0."
71 | },
72 | {
73 | "date": "2011-06-01",
74 | "text": "If a player's commander was exiled with Karn at the game restarted, that commander won't be put into the command zone at the beginning of the game. It will be put onto the battlefield when Karn's ability finishes resolving."
75 | },
76 | {
77 | "date": "2011-06-01",
78 | "text": "In a multiplayer game using the limited range of influence option, all players are affected and will restart the game, not just those within the range of influence of the ability's controller."
79 | }
80 | ],
81 | "foreignNames": [
82 | {
83 | "name": "重获自由的卡恩",
84 | "imageUrl": "http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=398077&type=card",
85 | "language": "Chinese Simplified",
86 | "multiverseid": 398077
87 | },
88 | {
89 | "name": "解放された者、カーン",
90 | "imageUrl": "http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=398326&type=card",
91 | "language": "Japanese",
92 | "multiverseid": 398326
93 | }
94 | ],
95 | "printings": [
96 | "NPH",
97 | "MM2"
98 | ],
99 | "originalText": "+4: Target player exiles a card from his or her hand.\n−3: Exile target permanent.\n−14: Restart the game, leaving in exile all non-Aura permanent cards exiled with Karn Liberated. Then put those cards onto the battlefield under your control.",
100 | "originalType": "Planeswalker — Karn",
101 | "legalities": [
102 | {
103 | "format": "Commander",
104 | "legality": "Legal"
105 | },
106 | {
107 | "format": "Legacy",
108 | "legality": "Legal"
109 | },
110 | {
111 | "format": "Modern",
112 | "legality": "Legal"
113 | },
114 | {
115 | "format": "Vintage",
116 | "legality": "Legal"
117 | }
118 | ],
119 | "id": "6dbb000f1dffa20fbb9159b7ac36b814d209558c"
120 | }
121 | ]
122 | }
123 |
--------------------------------------------------------------------------------
/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | CFPropertyList (3.0.3)
5 | addressable (2.8.0)
6 | public_suffix (>= 2.0.2, < 5.0)
7 | artifactory (3.0.15)
8 | atomos (0.1.3)
9 | aws-eventstream (1.1.1)
10 | aws-partitions (1.472.0)
11 | aws-sdk-core (3.115.0)
12 | aws-eventstream (~> 1, >= 1.0.2)
13 | aws-partitions (~> 1, >= 1.239.0)
14 | aws-sigv4 (~> 1.1)
15 | jmespath (~> 1.0)
16 | aws-sdk-kms (1.44.0)
17 | aws-sdk-core (~> 3, >= 3.112.0)
18 | aws-sigv4 (~> 1.1)
19 | aws-sdk-s3 (1.96.1)
20 | aws-sdk-core (~> 3, >= 3.112.0)
21 | aws-sdk-kms (~> 1)
22 | aws-sigv4 (~> 1.1)
23 | aws-sigv4 (1.2.3)
24 | aws-eventstream (~> 1, >= 1.0.2)
25 | babosa (1.0.4)
26 | claide (1.0.3)
27 | colored (1.2)
28 | colored2 (3.1.2)
29 | commander (4.6.0)
30 | highline (~> 2.0.0)
31 | declarative (0.0.20)
32 | digest-crc (0.6.3)
33 | rake (>= 12.0.0, < 14.0.0)
34 | domain_name (0.5.20190701)
35 | unf (>= 0.0.5, < 1.0.0)
36 | dotenv (2.7.6)
37 | emoji_regex (3.2.2)
38 | excon (0.83.0)
39 | faraday (1.4.3)
40 | faraday-em_http (~> 1.0)
41 | faraday-em_synchrony (~> 1.0)
42 | faraday-excon (~> 1.1)
43 | faraday-net_http (~> 1.0)
44 | faraday-net_http_persistent (~> 1.1)
45 | multipart-post (>= 1.2, < 3)
46 | ruby2_keywords (>= 0.0.4)
47 | faraday-cookie_jar (0.0.7)
48 | faraday (>= 0.8.0)
49 | http-cookie (~> 1.0.0)
50 | faraday-em_http (1.0.0)
51 | faraday-em_synchrony (1.0.0)
52 | faraday-excon (1.1.0)
53 | faraday-net_http (1.0.1)
54 | faraday-net_http_persistent (1.1.0)
55 | faraday_middleware (1.0.0)
56 | faraday (~> 1.0)
57 | fastimage (2.2.4)
58 | fastlane (2.187.0)
59 | CFPropertyList (>= 2.3, < 4.0.0)
60 | addressable (>= 2.3, < 3.0.0)
61 | artifactory (~> 3.0)
62 | aws-sdk-s3 (~> 1.0)
63 | babosa (>= 1.0.3, < 2.0.0)
64 | bundler (>= 1.12.0, < 3.0.0)
65 | colored
66 | commander (~> 4.6)
67 | dotenv (>= 2.1.1, < 3.0.0)
68 | emoji_regex (>= 0.1, < 4.0)
69 | excon (>= 0.71.0, < 1.0.0)
70 | faraday (~> 1.0)
71 | faraday-cookie_jar (~> 0.0.6)
72 | faraday_middleware (~> 1.0)
73 | fastimage (>= 2.1.0, < 3.0.0)
74 | gh_inspector (>= 1.1.2, < 2.0.0)
75 | google-apis-androidpublisher_v3 (~> 0.1)
76 | google-apis-playcustomapp_v1 (~> 0.1)
77 | google-cloud-storage (~> 1.31)
78 | highline (~> 2.0)
79 | json (< 3.0.0)
80 | jwt (>= 2.1.0, < 3)
81 | mini_magick (>= 4.9.4, < 5.0.0)
82 | multipart-post (~> 2.0.0)
83 | naturally (~> 2.2)
84 | plist (>= 3.1.0, < 4.0.0)
85 | rubyzip (>= 2.0.0, < 3.0.0)
86 | security (= 0.1.3)
87 | simctl (~> 1.6.3)
88 | terminal-notifier (>= 2.0.0, < 3.0.0)
89 | terminal-table (>= 1.4.5, < 2.0.0)
90 | tty-screen (>= 0.6.3, < 1.0.0)
91 | tty-spinner (>= 0.8.0, < 1.0.0)
92 | word_wrap (~> 1.0.0)
93 | xcodeproj (>= 1.13.0, < 2.0.0)
94 | xcpretty (~> 0.3.0)
95 | xcpretty-travis-formatter (>= 0.0.3)
96 | gh_inspector (1.1.3)
97 | google-apis-androidpublisher_v3 (0.7.0)
98 | google-apis-core (>= 0.3, < 2.a)
99 | google-apis-core (0.4.0)
100 | addressable (~> 2.5, >= 2.5.1)
101 | googleauth (>= 0.16.2, < 2.a)
102 | httpclient (>= 2.8.1, < 3.a)
103 | mini_mime (~> 1.0)
104 | representable (~> 3.0)
105 | retriable (>= 2.0, < 4.a)
106 | rexml
107 | webrick
108 | google-apis-iamcredentials_v1 (0.5.0)
109 | google-apis-core (>= 0.3, < 2.a)
110 | google-apis-playcustomapp_v1 (0.4.0)
111 | google-apis-core (>= 0.3, < 2.a)
112 | google-apis-storage_v1 (0.5.0)
113 | google-apis-core (>= 0.3, < 2.a)
114 | google-cloud-core (1.6.0)
115 | google-cloud-env (~> 1.0)
116 | google-cloud-errors (~> 1.0)
117 | google-cloud-env (1.5.0)
118 | faraday (>= 0.17.3, < 2.0)
119 | google-cloud-errors (1.1.0)
120 | google-cloud-storage (1.32.0)
121 | addressable (~> 2.5)
122 | digest-crc (~> 0.4)
123 | google-apis-iamcredentials_v1 (~> 0.1)
124 | google-apis-storage_v1 (~> 0.1)
125 | google-cloud-core (~> 1.6)
126 | googleauth (>= 0.16.2, < 2.a)
127 | mini_mime (~> 1.0)
128 | googleauth (0.16.2)
129 | faraday (>= 0.17.3, < 2.0)
130 | jwt (>= 1.4, < 3.0)
131 | memoist (~> 0.16)
132 | multi_json (~> 1.11)
133 | os (>= 0.9, < 2.0)
134 | signet (~> 0.14)
135 | highline (2.0.3)
136 | http-cookie (1.0.4)
137 | domain_name (~> 0.5)
138 | httpclient (2.8.3)
139 | jmespath (1.4.0)
140 | json (2.5.1)
141 | jwt (2.2.3)
142 | memoist (0.16.2)
143 | mini_magick (4.11.0)
144 | mini_mime (1.1.0)
145 | multi_json (1.15.0)
146 | multipart-post (2.0.0)
147 | nanaimo (0.3.0)
148 | naturally (2.2.1)
149 | os (1.1.1)
150 | plist (3.6.0)
151 | public_suffix (4.0.6)
152 | rake (13.0.3)
153 | representable (3.1.1)
154 | declarative (< 0.1.0)
155 | trailblazer-option (>= 0.1.1, < 0.2.0)
156 | uber (< 0.2.0)
157 | retriable (3.1.2)
158 | rexml (3.2.5)
159 | rouge (2.0.7)
160 | ruby2_keywords (0.0.4)
161 | rubyzip (2.3.0)
162 | security (0.1.3)
163 | signet (0.15.0)
164 | addressable (~> 2.3)
165 | faraday (>= 0.17.3, < 2.0)
166 | jwt (>= 1.5, < 3.0)
167 | multi_json (~> 1.10)
168 | simctl (1.6.8)
169 | CFPropertyList
170 | naturally
171 | terminal-notifier (2.0.0)
172 | terminal-table (1.8.0)
173 | unicode-display_width (~> 1.1, >= 1.1.1)
174 | trailblazer-option (0.1.1)
175 | tty-cursor (0.7.1)
176 | tty-screen (0.8.1)
177 | tty-spinner (0.9.3)
178 | tty-cursor (~> 0.7)
179 | uber (0.1.0)
180 | unf (0.1.4)
181 | unf_ext
182 | unf_ext (0.0.7.7)
183 | unicode-display_width (1.7.0)
184 | webrick (1.7.0)
185 | word_wrap (1.0.0)
186 | xcodeproj (1.19.0)
187 | CFPropertyList (>= 2.3.3, < 4.0)
188 | atomos (~> 0.1.3)
189 | claide (>= 1.0.2, < 2.0)
190 | colored2 (~> 3.1)
191 | nanaimo (~> 0.3.0)
192 | xcpretty (0.3.0)
193 | rouge (~> 2.0.7)
194 | xcpretty-travis-formatter (1.0.1)
195 | xcpretty (~> 0.2, >= 0.0.7)
196 |
197 | PLATFORMS
198 | x86_64-darwin-20
199 | x86_64-linux
200 |
201 | DEPENDENCIES
202 | fastlane
203 |
204 | BUNDLED WITH
205 | 2.2.21
206 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## MTGSDKSwift
2 | #### Magic: The Gathering SDK - Swift
3 | ##### A lightweight framework that makes interacting with the magicthegathering.io api quick, easy and safe.
4 |
5 |
6 |
7 |
8 |
9 |
10 | #### Installation
11 |
12 | ##### Install with SPM
13 |
14 | ##### Install with Cocoapods
15 | - add `pod 'MTGSDKSwift'` to your podfile
16 | - run pod install
17 |
18 | ##### Install with Carthage
19 |
20 | * copy the Cartfile above into your project folder
21 | * in terminal, navigate to your project folder and run the command 'carthage update'
22 | * drag the .framework file into your project in xcode. It will be in the newly created Carthage/Build/iOS folder in your project directory
23 | * drag the framework to the Linked Frameworks And Libraries slot and Embedded Frameworks slot
24 |
25 | You can also just download this project and drag the framework file into your project instead of messing with Carthage.
26 |
27 |
28 | #### Use
29 |
30 | ````swift
31 | import MTGSDKSwift
32 |
33 | let magic = Magic()
34 | ````
35 | You can
36 |
37 | ````swift
38 | fetchCards(_:completion:)
39 | fetchSets(_:completion:)
40 | fetchJSON(_:completion:)
41 | fetchImageForCard(_:completion:)
42 | generateBoosterForSet(_:completion:)
43 | ````
44 | ##### First: Configure your search parameters
45 | Parameters can be constructed as follows:
46 |
47 | ````swift
48 | let color = CardSearchParameter(parameterType: .colors, value: "black")
49 | let cmc = CardSearchParameter(parameterType: .cmc, value: "2")
50 | let setCode = CardSearchParameter(parameterType: .set, value: "AER")
51 | ````
52 |
53 | Search parameters come in two flavors: Card and SetSearchParameter. Each one contains an enum holding the valid query names for either cards or sets searches.
54 |
55 | Desired search parameters are grouped into an array and passed to the fetch method.
56 |
57 | ````swift
58 | magic.fetchCards(withParameters: [color,cmc,setCode]) {
59 | cards, error in
60 |
61 | if let error = error {
62 | //handle your error
63 | }
64 |
65 | for c in cards! {
66 | print(c.name)
67 | }
68 |
69 | }
70 | ````
71 |
72 |
73 | The completion contains an optional array of the appropriate type and an optional error type enum, NetworkError. Details for this enum are further down.
74 |
75 | The default number of results that will be retreived is 12. This can be set to 100, and for more results the number of pages must be increased. Page number and page size can be set by calling
76 |
77 | ````swift
78 | magic.pageTotal = "1"
79 | //and
80 | magic.pageSize = "9000"
81 | ````
82 | Additionally, some helpful console messages such as the URL string that is being sent to the server, how many cards or sets were retreived, and a message indicating that the network query has begun can be enabled by calling a static method on Magic.
83 |
84 | ````swift
85 | Magic.enableLogging = true
86 | ````
87 | ##### Fetching unparsed json
88 | fetchJSON(_:completion:) can be used to get the unparsed json in case you want to do something specific with it.
89 |
90 | ##### Fetching The Card Image
91 |
92 | fetchImageForCard works similarly to fetchCards, and will retreive the card image of the card you pass to it, if one is available. Some promo and special cards do not contain imageURL data. NetworkError will communicate this if true. Notably, cards in sets whose set code is prepended with "p" (pMEI, pGMD etc) may be missing this data. Most promotional cards will be missing image data as well.
93 |
94 | __Important note on image fetching:__ the card imageUrl refers to an HTTP address (gathere.wizards.com), which are as of ios9 by default blocked by App Transport Security. In order for image fetch to succede you must paste the following entry into your plist. This can also be added through the ios Target Properties menu but this is just quicker. [StackOverflow has a more detailed description of this issue.](http://stackoverflow.com/questions/31254725/transport-security-has-blocked-a-cleartext-http)
95 |
96 | ````xml
97 | NSAppTransportSecurity
98 |
99 | NSExceptionDomains
100 |
101 | wizards.com
102 |
103 | NSIncludesSubdomains
104 |
105 | NSTemporaryExceptionAllowsInsecureHTTPLoads
106 |
107 | NSTemporaryExceptionMinimumTLSVersion
108 | TLSv1.1
109 |
110 |
111 |
112 | ````
113 |
114 | ##### Simulating a Booster
115 |
116 | generateBoosterForSet(_:completion:) will return an array of [Card] which simulates what one might find opening a physical booster.
117 |
118 |
119 | #### class - Card
120 | ````swift
121 | public var name: String?
122 | public var names: [String]?
123 | public var manaCost: String?
124 | public var cmc: Int?
125 | public var colors: [String]?
126 | public var colorIdentity: [String]?
127 | public var type: String?
128 | public var supertypes: [String]?
129 | public var types: [String]?
130 | public var subtypes: [String]?
131 | public var rarity: String?
132 | public var set: String?
133 | public var text: String?
134 | public var artist: String?
135 | public var number: String?
136 | public var power: String?
137 | public var toughness: String?
138 | public var layout: String?
139 | public var multiverseid: Int?
140 | public var imageURL: String?
141 | public var rulings: [[String:String]]?
142 | public var foreignNames: [[String:String]]?
143 | public var printings: [String]?
144 | public var originalText: String?
145 | public var originalType: String?
146 | public var id: String?
147 | public var flavor: String?
148 |
149 | public static func ==(lhs: Card, rhs: Card) -> Bool {
150 | return lhs.id == rhs.id
151 | }
152 | ````
153 | Not all properties will exist for all mtg cards.
154 |
155 | The ID property is a unique identifier given to all cards and is useful for conforming Card to Equatable for example. Card names are not reliable for use as identifiers: There will be multiple "Serra Angel"s for example, one for each printing, but each one will have a unique ID.
156 |
157 | The following static function is provided for convienence in order to filter duplicate cards out of an array of [Card], if you have results containing the same card in multiple printings.
158 |
159 | ````swift
160 | FilterResults.removeDuplicateCardsByName(_:) -> [Card]
161 | ````
162 |
163 | #### class CardSet
164 | ````swift
165 | public var code: String?
166 | public var name: String?
167 | public var block: String?
168 | public var type: String?
169 | public var border: String?
170 | public var releaseDate: String?
171 | public var magicCardsInfoCode: String?
172 | public var booster: [[String]]?
173 | ````
174 | #### class CardSearchParameter, available parameters
175 |
176 | ````swift
177 | case name
178 | case cmc
179 | case colors
180 | case type
181 | case supertypes
182 | case subtypes
183 | case rarity
184 | case text
185 | case set
186 | case artist
187 | case power
188 | case toughness
189 | case multiverseid
190 | case gameFormat
191 | ````
192 |
193 | * colors
194 | * "red,black,white" in quotes will return exact match
195 | * red,black,white will include multicolors
196 | * red|black|white will not return multicolors
197 | * red,black|white will return multicolor red and black, or red and white cards
198 |
199 | see the official API documentation for more information about expected inputs and return -
200 | [magicthegathering.io docs](http://docs.magicthegathering.io/#overview)
201 |
202 | #### class SetSearchParameter, vailable parameters
203 | ````swift
204 | case name
205 | case block
206 | ````
207 |
208 | #### enum NetworkError
209 |
210 | ````swift
211 | public enum NetworkError: Error {
212 | case requestError(Error)
213 | case unexpectedHTTPResponse(HTTPURLResponse)
214 | case fetchCardImageError(String)
215 | case miscError(String)
216 | }
217 | ````
218 | * case requestError(Error)
219 | * will contain the error generated by the dataTask completion if it exists
220 | * case unexpectedHTTPResponse(HTTPURLResponse)
221 | * will contain the HTTPresponse generated by dataTask completion if anything other than success 200..<300 is generated
222 | * case fetchCardImageError(String)
223 | * associated value will contain information about a failed image fetch
224 | * case miscError(String)
225 | * associated value will contain information about errors such as constructing URL failures
226 |
227 | #### Typealiases
228 | ````swift
229 | public typealias JSONResults = [String:Any]
230 | public typealias JSONCompletionWithError = (JSONResults?, NetworkError?) -> Void
231 | public typealias CardImageCompletion = (UIImage?, NetworkError?) -> Void
232 | public typealias CardCompletion = ([Card]?, NetworkError?) -> Void
233 | public typealias SetCompletion = ([CardSet]?, NetworkError?) -> Void
234 |
--------------------------------------------------------------------------------
/MTGSDKSwift/MagicalCardManager.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MagicalCardManager.swift
3 | // MTGSDKSwift
4 | //
5 | // Created by Reed Carson on 3/1/17.
6 | // Copyright © 2017 Reed Carson. All rights reserved.
7 | //
8 | #if canImport(AppKit)
9 | import AppKit
10 | #elseif canImport(UIKit)
11 | import UIKit
12 | #endif
13 |
14 | final public class Magic {
15 | public typealias CardCompletion = (Result<[Card]>) -> Void
16 | public typealias SetCompletion = (Result<[CardSet]>) -> Void
17 |
18 | /// Should the Magic API log messages to the `print` function? Defaults to true.
19 | public static var enableLogging = true
20 |
21 | private let mtgAPIService = MTGAPIService()
22 |
23 | /// Default initialization
24 | public init() { }
25 |
26 | /// Reteives an array of Cards which match the parameters given.
27 | /// See https://docs.magicthegathering.io/#api_v1cards_list for more info.
28 | ///
29 | /// - Parameters:
30 | /// - parameters: The Card Search Parameters that you'd like to search with.
31 | /// - configuration: The Search Configuration (defaults to `.defaultConfiguration`).
32 | /// - completion: The completion handler (for success / failure response).
33 | public func fetchCards(_ parameters: [CardSearchParameter],
34 | configuration: MTGSearchConfiguration = .defaultConfiguration,
35 | completion: @escaping CardCompletion) {
36 |
37 | guard let url = URLBuilder.buildURLWithParameters(parameters, andConfig: configuration) else {
38 | completion(Result.error(NetworkError.miscError("fetchCards url build failed")))
39 | return
40 | }
41 |
42 | mtgAPIService.mtgAPIQuery(url: url, responseObject: CardsResponse.self) {
43 | result in
44 | switch result {
45 | case .success(let results):
46 | completion(Result.success(results.cards))
47 | case .error(let error):
48 | completion(Result.error(error))
49 | }
50 | }
51 | }
52 |
53 | /// Retrieves an array of Cards which match the parameters given using Swift concurrency and utilizes `async await`.
54 | /// See https://docs.magicthegathering.io/#api_v1cards_list for more info.
55 | ///
56 | /// - Parameters:
57 | /// - parameters: The Card Search Parameters that you'd like to search with.
58 | /// - configuration: The Search Configuration (defaults to `.defaultConfiguration`).
59 | @available(iOS 15.0, *)
60 | public func fetchCards(_ parameters: [CardSearchParameter],
61 | configuration: MTGSearchConfiguration = .defaultConfiguration) async throws -> [Card] {
62 | guard let url = URLBuilder.buildURLWithParameters(parameters, andConfig: configuration) else {
63 | throw NetworkError.miscError("fetchCards URL build failed")
64 | }
65 |
66 | return try await mtgAPIService.mtgAPIQuery(url: url, responseObject: CardsResponse.self).cards
67 | }
68 |
69 | /// Reteives an array of CardSet which matches the parameters given.
70 | /// See https://docs.magicthegathering.io/#api_v1sets_list for more info.
71 | ///
72 | /// - Parameters:
73 | /// - parameters: The Card Set search parameters you want to search for.
74 | /// - configuration: The Search Configuration, defaults to `.defaultConfiguration`.
75 | /// - completion: The completion handler (for success / failure response).
76 | public func fetchSets(_ parameters: [SetSearchParameter],
77 | configuration: MTGSearchConfiguration = .defaultConfiguration,
78 | completion: @escaping SetCompletion) {
79 | guard let url = URLBuilder.buildURLWithParameters(parameters, andConfig: configuration) else {
80 | return completion(Result.error(NetworkError.miscError("fetchSets url build failed")))
81 | }
82 |
83 | mtgAPIService.mtgAPIQuery(url: url, responseObject: SetsResponse.self) {
84 | result in
85 | switch result {
86 | case .success(let setsResponse):
87 | completion(Result.success(setsResponse.sets))
88 | case .error(let error):
89 | completion(Result.error(error))
90 | }
91 | }
92 | }
93 |
94 | /// Fetch JSON returns the raw json data rather than an Array of Card or CardSet. It will return json
95 | /// for sets or cards depending on what you feed it.
96 | ///
97 | /// - Parameters:
98 | /// - parameters: either [CardSearchParameter] or [SetSearchParameter]
99 | /// - configuration: The Search Configuration, defaults to `.defaultConfiguration`.
100 | /// - completion: The completion handler (for success / failure response).
101 | public func fetchJSON(_ parameters: [SearchParameter],
102 | configuration: MTGSearchConfiguration = .defaultConfiguration,
103 | completion: @escaping (Result) -> Void) {
104 |
105 | guard let url = URLBuilder.buildURLWithParameters(parameters, andConfig: configuration) else {
106 | completion(Result.error(NetworkError.miscError("fetchJSON url build failed")))
107 | return
108 | }
109 |
110 | mtgAPIService.jsonQuery(url: url) {
111 | result in
112 | switch result {
113 | case .success:
114 | completion(result)
115 | case .error(let error):
116 | completion(Result.error(NetworkError.requestError(error)))
117 | return
118 | }
119 | }
120 | }
121 |
122 | #if canImport(UIKit)
123 | public typealias CardImageCompletion = (Result) -> Void
124 |
125 | /// Retreives a UIImage based on the imageURL of the Card passed in
126 | ///
127 | /// - Parameters:
128 | /// - card: The card you wish to get the image for.
129 | /// - completion: The completion handler (for success / failure response).
130 | public func fetchImageForCard(_ card: Card, completion: @escaping CardImageCompletion) {
131 | guard let imgurl = card.imageUrl else {
132 | return completion(Result.error(NetworkError.fetchCardImageError("fetchImageForCard card imageURL was nil")))
133 | }
134 |
135 | guard let url = URL(string: imgurl) else {
136 | return completion(Result.error(NetworkError.fetchCardImageError("fetchImageForCard url build failed")))
137 | }
138 |
139 | do {
140 | let data = try Data(contentsOf: url)
141 | guard let img = UIImage(data: data) else {
142 | return completion(Result.error(NetworkError.fetchCardImageError("could not create uiimage from data")))
143 | }
144 | completion(Result.success(img))
145 | } catch {
146 | completion(Result.error(NetworkError.fetchCardImageError("data from contents of url failed")))
147 | }
148 | }
149 | #endif
150 |
151 | #if canImport(AppKit)
152 | public typealias CardImageCompletion = (Result) -> Void
153 |
154 | /// Retreives a NSImage based on the imageURL of the Card passed in
155 | ///
156 | /// - Parameters:
157 | /// - card: The card you wish to get the image for.
158 | /// - completion: The completion handler (for success / failure response).
159 | public func fetchImageForCard(_ card: Card, completion: @escaping CardImageCompletion) {
160 | guard let imgurl = card.imageUrl else {
161 | return completion(Result.error(NetworkError.fetchCardImageError("fetchImageForCard card imageURL was nil")))
162 | }
163 |
164 | guard let url = URL(string: imgurl) else {
165 | return completion(Result.error(NetworkError.fetchCardImageError("fetchImageForCard url build failed")))
166 | }
167 |
168 | do {
169 | let data = try Data(contentsOf: url)
170 | guard let img = NSImage(data: data) else {
171 | return completion(Result.error(NetworkError.fetchCardImageError("could not create uiimage from data")))
172 | }
173 | completion(Result.success(img))
174 | } catch {
175 | completion(Result.error(NetworkError.fetchCardImageError("data from contents of url failed")))
176 | }
177 | }
178 | #endif
179 |
180 | /// This function simulates opening a booster pack for the given set, producing an array of [Card]
181 | ///
182 | /// - Parameters:
183 | /// - setCode: the set code of the desired set
184 | /// - completion: The completion handler (for success / failure response).
185 | public func generateBoosterForSet(_ setCode: String, completion: @escaping CardCompletion) {
186 | let urlString = Constants.baseEndpoint + setCode + Constants.generateBoosterPath
187 |
188 | guard let url = URL(string: urlString) else {
189 | return completion(Result.error(NetworkError.miscError("generateBooster - build url fail")))
190 | }
191 |
192 | mtgAPIService.mtgAPIQuery(url: url, responseObject: CardsResponse.self) {
193 | result in
194 | switch result {
195 | case .success(let results):
196 | completion(Result.success(results.cards))
197 | case .error(let error):
198 | completion(Result.error(error))
199 | }
200 | }
201 | }
202 | }
203 |
204 | final public class ResultsFilter {
205 |
206 | /**
207 | If an array of Card contains cards with identical names, likely due to multiple printings, this function leaves only one version of that card. You will only have one "Scathe Zombie" instead of 5 "Scathe Zombie", the only difference between them being the set they were printed in.
208 |
209 | - parameter cards: [Card]
210 | - returns: [Card] consisting of Cards without duplicate names
211 | */
212 |
213 | static public func removeDuplicateCardsByName(_ cards: [Card]) -> [Card] {
214 | var uniqueNames = [String]()
215 | var uniqueCards = [Card]()
216 |
217 | for c in cards {
218 | if let name = c.name {
219 | if !uniqueNames.contains(name) {
220 | uniqueCards.append(c)
221 | }
222 | uniqueNames.append(name)
223 | }
224 | }
225 |
226 | return uniqueCards
227 | }
228 | }
229 |
--------------------------------------------------------------------------------
/MTGSDKSwift.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 5B18A9821E69EB0B0026E648 /* NetworkError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B18A9811E69EB0B0026E648 /* NetworkError.swift */; };
11 | 5B6092D9215EA8E000CDD46A /* Resources in Resources */ = {isa = PBXBuildFile; fileRef = 5B6092D8215EA8DF00CDD46A /* Resources */; };
12 | 5B6DC20C1E64A01A000DF60C /* CardSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6DC20B1E64A01A000DF60C /* CardSet.swift */; };
13 | 5B6DC20E1E64A1A0000DF60C /* SearchParameter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6DC20D1E64A1A0000DF60C /* SearchParameter.swift */; };
14 | 5B71E73A282BED55006C7D1F /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = 5B71E739282BED55006C7D1F /* README.md */; };
15 | 5B87D68720596D6B0098553C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B87D68620596D6B0098553C /* AppDelegate.swift */; };
16 | 5B87D68920596D6B0098553C /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B87D68820596D6B0098553C /* ViewController.swift */; };
17 | 5B87D68C20596D6B0098553C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5B87D68A20596D6B0098553C /* Main.storyboard */; };
18 | 5B87D68E20596D6B0098553C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5B87D68D20596D6B0098553C /* Assets.xcassets */; };
19 | 5B87D69120596D6B0098553C /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5B87D68F20596D6B0098553C /* LaunchScreen.storyboard */; };
20 | 5BB0E88B205FF9AA00FE67F6 /* MTGSDKSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BD04DA91E64943C00E5ED27 /* MTGSDKSwift.framework */; };
21 | 5BB0E88C205FF9AA00FE67F6 /* MTGSDKSwift.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 5BD04DA91E64943C00E5ED27 /* MTGSDKSwift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
22 | 5BC6D7EE1E67B7A00090650A /* MagicalCardManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BC6D7ED1E67B7A00090650A /* MagicalCardManager.swift */; };
23 | 5BD04DB31E64943C00E5ED27 /* MTGSDKSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BD04DA91E64943C00E5ED27 /* MTGSDKSwift.framework */; };
24 | 5BD04DB81E64943C00E5ED27 /* MTGSDKSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD04DB71E64943C00E5ED27 /* MTGSDKSwiftTests.swift */; };
25 | 5BD04DBA1E64943C00E5ED27 /* MTGSDKSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 5BD04DAC1E64943C00E5ED27 /* MTGSDKSwift.h */; settings = {ATTRIBUTES = (Public, ); }; };
26 | 5BD04DC51E64945800E5ED27 /* Card.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD04DC31E64945800E5ED27 /* Card.swift */; };
27 | 5BD04DC61E64945800E5ED27 /* MTGAPIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD04DC41E64945800E5ED27 /* MTGAPIService.swift */; };
28 | 5BDF34C820854F1B007265DF /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BDF34C720854F1B007265DF /* Constants.swift */; };
29 | 5BDF34CB2085500E007265DF /* MTGSearchConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BDF34CA2085500E007265DF /* MTGSearchConfiguration.swift */; };
30 | 5BE24D202076D14A00EB0573 /* URLBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BE24D1F2076D14A00EB0573 /* URLBuilder.swift */; };
31 | /* End PBXBuildFile section */
32 |
33 | /* Begin PBXContainerItemProxy section */
34 | 5BB0E88D205FF9AA00FE67F6 /* PBXContainerItemProxy */ = {
35 | isa = PBXContainerItemProxy;
36 | containerPortal = 5BD04DA01E64943C00E5ED27 /* Project object */;
37 | proxyType = 1;
38 | remoteGlobalIDString = 5BD04DA81E64943C00E5ED27;
39 | remoteInfo = MTGSDKSwift;
40 | };
41 | 5BD04DB41E64943C00E5ED27 /* PBXContainerItemProxy */ = {
42 | isa = PBXContainerItemProxy;
43 | containerPortal = 5BD04DA01E64943C00E5ED27 /* Project object */;
44 | proxyType = 1;
45 | remoteGlobalIDString = 5BD04DA81E64943C00E5ED27;
46 | remoteInfo = MTGSDKSwift;
47 | };
48 | /* End PBXContainerItemProxy section */
49 |
50 | /* Begin PBXCopyFilesBuildPhase section */
51 | 5BB0E88F205FF9AA00FE67F6 /* Embed Frameworks */ = {
52 | isa = PBXCopyFilesBuildPhase;
53 | buildActionMask = 2147483647;
54 | dstPath = "";
55 | dstSubfolderSpec = 10;
56 | files = (
57 | 5BB0E88C205FF9AA00FE67F6 /* MTGSDKSwift.framework in Embed Frameworks */,
58 | );
59 | name = "Embed Frameworks";
60 | runOnlyForDeploymentPostprocessing = 0;
61 | };
62 | /* End PBXCopyFilesBuildPhase section */
63 |
64 | /* Begin PBXFileReference section */
65 | 5B18A9811E69EB0B0026E648 /* NetworkError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkError.swift; sourceTree = ""; };
66 | 5B6092D8215EA8DF00CDD46A /* Resources */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Resources; sourceTree = ""; };
67 | 5B6DC20B1E64A01A000DF60C /* CardSet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CardSet.swift; sourceTree = ""; };
68 | 5B6DC20D1E64A1A0000DF60C /* SearchParameter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchParameter.swift; sourceTree = ""; };
69 | 5B71E739282BED55006C7D1F /* README.md */ = {isa = PBXFileReference; explicitFileType = net.daringfireball.markdown; fileEncoding = 4; path = README.md; sourceTree = ""; };
70 | 5B71E73B282BEFFD006C7D1F /* Package.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; };
71 | 5B87D68420596D6B0098553C /* TestApplication.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TestApplication.app; sourceTree = BUILT_PRODUCTS_DIR; };
72 | 5B87D68620596D6B0098553C /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
73 | 5B87D68820596D6B0098553C /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
74 | 5B87D68B20596D6B0098553C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
75 | 5B87D68D20596D6B0098553C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
76 | 5B87D69020596D6B0098553C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
77 | 5B87D69220596D6B0098553C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
78 | 5BC6D7ED1E67B7A00090650A /* MagicalCardManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MagicalCardManager.swift; sourceTree = ""; };
79 | 5BD04DA91E64943C00E5ED27 /* MTGSDKSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MTGSDKSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; };
80 | 5BD04DAC1E64943C00E5ED27 /* MTGSDKSwift.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTGSDKSwift.h; sourceTree = ""; };
81 | 5BD04DAD1E64943C00E5ED27 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
82 | 5BD04DB21E64943C00E5ED27 /* MTGSDKSwiftTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MTGSDKSwiftTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
83 | 5BD04DB71E64943C00E5ED27 /* MTGSDKSwiftTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MTGSDKSwiftTests.swift; sourceTree = ""; };
84 | 5BD04DB91E64943C00E5ED27 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
85 | 5BD04DC31E64945800E5ED27 /* Card.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Card.swift; sourceTree = ""; };
86 | 5BD04DC41E64945800E5ED27 /* MTGAPIService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MTGAPIService.swift; sourceTree = ""; };
87 | 5BDF34C720854F1B007265DF /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; };
88 | 5BDF34CA2085500E007265DF /* MTGSearchConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MTGSearchConfiguration.swift; sourceTree = ""; };
89 | 5BE24D1F2076D14A00EB0573 /* URLBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLBuilder.swift; sourceTree = ""; };
90 | /* End PBXFileReference section */
91 |
92 | /* Begin PBXFrameworksBuildPhase section */
93 | 5B87D68120596D6B0098553C /* Frameworks */ = {
94 | isa = PBXFrameworksBuildPhase;
95 | buildActionMask = 2147483647;
96 | files = (
97 | 5BB0E88B205FF9AA00FE67F6 /* MTGSDKSwift.framework in Frameworks */,
98 | );
99 | runOnlyForDeploymentPostprocessing = 0;
100 | };
101 | 5BD04DA51E64943C00E5ED27 /* Frameworks */ = {
102 | isa = PBXFrameworksBuildPhase;
103 | buildActionMask = 2147483647;
104 | files = (
105 | );
106 | runOnlyForDeploymentPostprocessing = 0;
107 | };
108 | 5BD04DAF1E64943C00E5ED27 /* Frameworks */ = {
109 | isa = PBXFrameworksBuildPhase;
110 | buildActionMask = 2147483647;
111 | files = (
112 | 5BD04DB31E64943C00E5ED27 /* MTGSDKSwift.framework in Frameworks */,
113 | );
114 | runOnlyForDeploymentPostprocessing = 0;
115 | };
116 | /* End PBXFrameworksBuildPhase section */
117 |
118 | /* Begin PBXGroup section */
119 | 073F02172CCFC58D00AF05D1 /* Frameworks */ = {
120 | isa = PBXGroup;
121 | children = (
122 | );
123 | name = Frameworks;
124 | sourceTree = "";
125 | };
126 | 5B6092D5215EA5F400CDD46A /* Recovered References */ = {
127 | isa = PBXGroup;
128 | children = (
129 | );
130 | name = "Recovered References";
131 | sourceTree = "";
132 | };
133 | 5B87D68520596D6B0098553C /* TestApplication */ = {
134 | isa = PBXGroup;
135 | children = (
136 | 5B87D68620596D6B0098553C /* AppDelegate.swift */,
137 | 5B87D68820596D6B0098553C /* ViewController.swift */,
138 | 5B87D68A20596D6B0098553C /* Main.storyboard */,
139 | 5B87D68D20596D6B0098553C /* Assets.xcassets */,
140 | 5B87D68F20596D6B0098553C /* LaunchScreen.storyboard */,
141 | 5B87D69220596D6B0098553C /* Info.plist */,
142 | );
143 | path = TestApplication;
144 | sourceTree = "";
145 | };
146 | 5BD04D9F1E64943C00E5ED27 = {
147 | isa = PBXGroup;
148 | children = (
149 | 5B71E739282BED55006C7D1F /* README.md */,
150 | 5B71E73B282BEFFD006C7D1F /* Package.swift */,
151 | 5BD04DAB1E64943C00E5ED27 /* MTGSDKSwift */,
152 | 5BD04DB61E64943C00E5ED27 /* MTGSDKSwiftTests */,
153 | 5B87D68520596D6B0098553C /* TestApplication */,
154 | 5BD04DAA1E64943C00E5ED27 /* Products */,
155 | 5B6092D5215EA5F400CDD46A /* Recovered References */,
156 | 073F02172CCFC58D00AF05D1 /* Frameworks */,
157 | );
158 | sourceTree = "";
159 | };
160 | 5BD04DAA1E64943C00E5ED27 /* Products */ = {
161 | isa = PBXGroup;
162 | children = (
163 | 5BD04DA91E64943C00E5ED27 /* MTGSDKSwift.framework */,
164 | 5BD04DB21E64943C00E5ED27 /* MTGSDKSwiftTests.xctest */,
165 | 5B87D68420596D6B0098553C /* TestApplication.app */,
166 | );
167 | name = Products;
168 | sourceTree = "";
169 | };
170 | 5BD04DAB1E64943C00E5ED27 /* MTGSDKSwift */ = {
171 | isa = PBXGroup;
172 | children = (
173 | 5BDF34C920854F72007265DF /* Models */,
174 | 5BD04DAD1E64943C00E5ED27 /* Info.plist */,
175 | 5BD04DAC1E64943C00E5ED27 /* MTGSDKSwift.h */,
176 | 5BD04DC41E64945800E5ED27 /* MTGAPIService.swift */,
177 | 5BE24D1F2076D14A00EB0573 /* URLBuilder.swift */,
178 | 5BC6D7ED1E67B7A00090650A /* MagicalCardManager.swift */,
179 | );
180 | path = MTGSDKSwift;
181 | sourceTree = "";
182 | };
183 | 5BD04DB61E64943C00E5ED27 /* MTGSDKSwiftTests */ = {
184 | isa = PBXGroup;
185 | children = (
186 | 5B6092D8215EA8DF00CDD46A /* Resources */,
187 | 5BD04DB71E64943C00E5ED27 /* MTGSDKSwiftTests.swift */,
188 | 5BD04DB91E64943C00E5ED27 /* Info.plist */,
189 | );
190 | path = MTGSDKSwiftTests;
191 | sourceTree = "";
192 | };
193 | 5BDF34C920854F72007265DF /* Models */ = {
194 | isa = PBXGroup;
195 | children = (
196 | 5BDF34C720854F1B007265DF /* Constants.swift */,
197 | 5B18A9811E69EB0B0026E648 /* NetworkError.swift */,
198 | 5B6DC20B1E64A01A000DF60C /* CardSet.swift */,
199 | 5BD04DC31E64945800E5ED27 /* Card.swift */,
200 | 5B6DC20D1E64A1A0000DF60C /* SearchParameter.swift */,
201 | 5BDF34CA2085500E007265DF /* MTGSearchConfiguration.swift */,
202 | );
203 | path = Models;
204 | sourceTree = "";
205 | };
206 | /* End PBXGroup section */
207 |
208 | /* Begin PBXHeadersBuildPhase section */
209 | 5BD04DA61E64943C00E5ED27 /* Headers */ = {
210 | isa = PBXHeadersBuildPhase;
211 | buildActionMask = 2147483647;
212 | files = (
213 | 5BD04DBA1E64943C00E5ED27 /* MTGSDKSwift.h in Headers */,
214 | );
215 | runOnlyForDeploymentPostprocessing = 0;
216 | };
217 | /* End PBXHeadersBuildPhase section */
218 |
219 | /* Begin PBXNativeTarget section */
220 | 5B87D68320596D6B0098553C /* TestApplication */ = {
221 | isa = PBXNativeTarget;
222 | buildConfigurationList = 5B87D69320596D6B0098553C /* Build configuration list for PBXNativeTarget "TestApplication" */;
223 | buildPhases = (
224 | 5B87D68020596D6B0098553C /* Sources */,
225 | 5B87D68120596D6B0098553C /* Frameworks */,
226 | 5B87D68220596D6B0098553C /* Resources */,
227 | 5BB0E88F205FF9AA00FE67F6 /* Embed Frameworks */,
228 | );
229 | buildRules = (
230 | );
231 | dependencies = (
232 | 5BB0E88E205FF9AA00FE67F6 /* PBXTargetDependency */,
233 | );
234 | name = TestApplication;
235 | productName = TestApplication;
236 | productReference = 5B87D68420596D6B0098553C /* TestApplication.app */;
237 | productType = "com.apple.product-type.application";
238 | };
239 | 5BD04DA81E64943C00E5ED27 /* MTGSDKSwift */ = {
240 | isa = PBXNativeTarget;
241 | buildConfigurationList = 5BD04DBD1E64943C00E5ED27 /* Build configuration list for PBXNativeTarget "MTGSDKSwift" */;
242 | buildPhases = (
243 | 5BD04DA41E64943C00E5ED27 /* Sources */,
244 | 5BD04DA51E64943C00E5ED27 /* Frameworks */,
245 | 5BD04DA61E64943C00E5ED27 /* Headers */,
246 | 5BD04DA71E64943C00E5ED27 /* Resources */,
247 | );
248 | buildRules = (
249 | );
250 | dependencies = (
251 | );
252 | name = MTGSDKSwift;
253 | productName = MTGSDKSwift;
254 | productReference = 5BD04DA91E64943C00E5ED27 /* MTGSDKSwift.framework */;
255 | productType = "com.apple.product-type.framework";
256 | };
257 | 5BD04DB11E64943C00E5ED27 /* MTGSDKSwiftTests */ = {
258 | isa = PBXNativeTarget;
259 | buildConfigurationList = 5BD04DC01E64943C00E5ED27 /* Build configuration list for PBXNativeTarget "MTGSDKSwiftTests" */;
260 | buildPhases = (
261 | 5BD04DAE1E64943C00E5ED27 /* Sources */,
262 | 5BD04DAF1E64943C00E5ED27 /* Frameworks */,
263 | 5BD04DB01E64943C00E5ED27 /* Resources */,
264 | );
265 | buildRules = (
266 | );
267 | dependencies = (
268 | 5BD04DB51E64943C00E5ED27 /* PBXTargetDependency */,
269 | );
270 | name = MTGSDKSwiftTests;
271 | productName = MTGSDKSwiftTests;
272 | productReference = 5BD04DB21E64943C00E5ED27 /* MTGSDKSwiftTests.xctest */;
273 | productType = "com.apple.product-type.bundle.unit-test";
274 | };
275 | /* End PBXNativeTarget section */
276 |
277 | /* Begin PBXProject section */
278 | 5BD04DA01E64943C00E5ED27 /* Project object */ = {
279 | isa = PBXProject;
280 | attributes = {
281 | LastSwiftUpdateCheck = 0910;
282 | LastUpgradeCheck = 0820;
283 | ORGANIZATIONNAME = "Reed Carson";
284 | TargetAttributes = {
285 | 5B87D68320596D6B0098553C = {
286 | CreatedOnToolsVersion = 9.1;
287 | DevelopmentTeam = X68KF89T7U;
288 | ProvisioningStyle = Automatic;
289 | };
290 | 5BD04DA81E64943C00E5ED27 = {
291 | CreatedOnToolsVersion = 8.2.1;
292 | ProvisioningStyle = Automatic;
293 | };
294 | 5BD04DB11E64943C00E5ED27 = {
295 | CreatedOnToolsVersion = 8.2.1;
296 | DevelopmentTeam = X68KF89T7U;
297 | LastSwiftMigration = 0940;
298 | ProvisioningStyle = Automatic;
299 | };
300 | };
301 | };
302 | buildConfigurationList = 5BD04DA31E64943C00E5ED27 /* Build configuration list for PBXProject "MTGSDKSwift" */;
303 | compatibilityVersion = "Xcode 3.2";
304 | developmentRegion = English;
305 | hasScannedForEncodings = 0;
306 | knownRegions = (
307 | English,
308 | en,
309 | Base,
310 | );
311 | mainGroup = 5BD04D9F1E64943C00E5ED27;
312 | productRefGroup = 5BD04DAA1E64943C00E5ED27 /* Products */;
313 | projectDirPath = "";
314 | projectRoot = "";
315 | targets = (
316 | 5BD04DA81E64943C00E5ED27 /* MTGSDKSwift */,
317 | 5BD04DB11E64943C00E5ED27 /* MTGSDKSwiftTests */,
318 | 5B87D68320596D6B0098553C /* TestApplication */,
319 | );
320 | };
321 | /* End PBXProject section */
322 |
323 | /* Begin PBXResourcesBuildPhase section */
324 | 5B87D68220596D6B0098553C /* Resources */ = {
325 | isa = PBXResourcesBuildPhase;
326 | buildActionMask = 2147483647;
327 | files = (
328 | 5B87D69120596D6B0098553C /* LaunchScreen.storyboard in Resources */,
329 | 5B87D68E20596D6B0098553C /* Assets.xcassets in Resources */,
330 | 5B87D68C20596D6B0098553C /* Main.storyboard in Resources */,
331 | );
332 | runOnlyForDeploymentPostprocessing = 0;
333 | };
334 | 5BD04DA71E64943C00E5ED27 /* Resources */ = {
335 | isa = PBXResourcesBuildPhase;
336 | buildActionMask = 2147483647;
337 | files = (
338 | 5B71E73A282BED55006C7D1F /* README.md in Resources */,
339 | );
340 | runOnlyForDeploymentPostprocessing = 0;
341 | };
342 | 5BD04DB01E64943C00E5ED27 /* Resources */ = {
343 | isa = PBXResourcesBuildPhase;
344 | buildActionMask = 2147483647;
345 | files = (
346 | 5B6092D9215EA8E000CDD46A /* Resources in Resources */,
347 | );
348 | runOnlyForDeploymentPostprocessing = 0;
349 | };
350 | /* End PBXResourcesBuildPhase section */
351 |
352 | /* Begin PBXSourcesBuildPhase section */
353 | 5B87D68020596D6B0098553C /* Sources */ = {
354 | isa = PBXSourcesBuildPhase;
355 | buildActionMask = 2147483647;
356 | files = (
357 | 5B87D68920596D6B0098553C /* ViewController.swift in Sources */,
358 | 5B87D68720596D6B0098553C /* AppDelegate.swift in Sources */,
359 | );
360 | runOnlyForDeploymentPostprocessing = 0;
361 | };
362 | 5BD04DA41E64943C00E5ED27 /* Sources */ = {
363 | isa = PBXSourcesBuildPhase;
364 | buildActionMask = 2147483647;
365 | files = (
366 | 5BC6D7EE1E67B7A00090650A /* MagicalCardManager.swift in Sources */,
367 | 5B18A9821E69EB0B0026E648 /* NetworkError.swift in Sources */,
368 | 5BD04DC51E64945800E5ED27 /* Card.swift in Sources */,
369 | 5BD04DC61E64945800E5ED27 /* MTGAPIService.swift in Sources */,
370 | 5B6DC20E1E64A1A0000DF60C /* SearchParameter.swift in Sources */,
371 | 5BDF34CB2085500E007265DF /* MTGSearchConfiguration.swift in Sources */,
372 | 5BE24D202076D14A00EB0573 /* URLBuilder.swift in Sources */,
373 | 5B6DC20C1E64A01A000DF60C /* CardSet.swift in Sources */,
374 | 5BDF34C820854F1B007265DF /* Constants.swift in Sources */,
375 | );
376 | runOnlyForDeploymentPostprocessing = 0;
377 | };
378 | 5BD04DAE1E64943C00E5ED27 /* Sources */ = {
379 | isa = PBXSourcesBuildPhase;
380 | buildActionMask = 2147483647;
381 | files = (
382 | 5BD04DB81E64943C00E5ED27 /* MTGSDKSwiftTests.swift in Sources */,
383 | );
384 | runOnlyForDeploymentPostprocessing = 0;
385 | };
386 | /* End PBXSourcesBuildPhase section */
387 |
388 | /* Begin PBXTargetDependency section */
389 | 5BB0E88E205FF9AA00FE67F6 /* PBXTargetDependency */ = {
390 | isa = PBXTargetDependency;
391 | target = 5BD04DA81E64943C00E5ED27 /* MTGSDKSwift */;
392 | targetProxy = 5BB0E88D205FF9AA00FE67F6 /* PBXContainerItemProxy */;
393 | };
394 | 5BD04DB51E64943C00E5ED27 /* PBXTargetDependency */ = {
395 | isa = PBXTargetDependency;
396 | target = 5BD04DA81E64943C00E5ED27 /* MTGSDKSwift */;
397 | targetProxy = 5BD04DB41E64943C00E5ED27 /* PBXContainerItemProxy */;
398 | };
399 | /* End PBXTargetDependency section */
400 |
401 | /* Begin PBXVariantGroup section */
402 | 5B87D68A20596D6B0098553C /* Main.storyboard */ = {
403 | isa = PBXVariantGroup;
404 | children = (
405 | 5B87D68B20596D6B0098553C /* Base */,
406 | );
407 | name = Main.storyboard;
408 | sourceTree = "";
409 | };
410 | 5B87D68F20596D6B0098553C /* LaunchScreen.storyboard */ = {
411 | isa = PBXVariantGroup;
412 | children = (
413 | 5B87D69020596D6B0098553C /* Base */,
414 | );
415 | name = LaunchScreen.storyboard;
416 | sourceTree = "";
417 | };
418 | /* End PBXVariantGroup section */
419 |
420 | /* Begin XCBuildConfiguration section */
421 | 5B87D69420596D6B0098553C /* Debug */ = {
422 | isa = XCBuildConfiguration;
423 | buildSettings = {
424 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
425 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
426 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
427 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
428 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
429 | CLANG_WARN_COMMA = YES;
430 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
431 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
432 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
433 | CLANG_WARN_STRICT_PROTOTYPES = YES;
434 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
435 | CODE_SIGN_IDENTITY = "iPhone Developer";
436 | CODE_SIGN_STYLE = Automatic;
437 | DEVELOPMENT_TEAM = X68KF89T7U;
438 | GCC_C_LANGUAGE_STANDARD = gnu11;
439 | INFOPLIST_FILE = TestApplication/Info.plist;
440 | IPHONEOS_DEPLOYMENT_TARGET = 15.0;
441 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
442 | PRODUCT_BUNDLE_IDENTIFIER = com.rpcarson.MTGSDKSwift.Test;
443 | PRODUCT_NAME = "$(TARGET_NAME)";
444 | SWIFT_VERSION = 4.0;
445 | TARGETED_DEVICE_FAMILY = "1,2";
446 | };
447 | name = Debug;
448 | };
449 | 5B87D69520596D6B0098553C /* Release */ = {
450 | isa = XCBuildConfiguration;
451 | buildSettings = {
452 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
453 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
454 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
455 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
456 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
457 | CLANG_WARN_COMMA = YES;
458 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
459 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
460 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
461 | CLANG_WARN_STRICT_PROTOTYPES = YES;
462 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
463 | CODE_SIGN_IDENTITY = "iPhone Developer";
464 | CODE_SIGN_STYLE = Automatic;
465 | DEVELOPMENT_TEAM = X68KF89T7U;
466 | GCC_C_LANGUAGE_STANDARD = gnu11;
467 | INFOPLIST_FILE = TestApplication/Info.plist;
468 | IPHONEOS_DEPLOYMENT_TARGET = 15.0;
469 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
470 | PRODUCT_BUNDLE_IDENTIFIER = com.rpcarson.MTGSDKSwift.Test;
471 | PRODUCT_NAME = "$(TARGET_NAME)";
472 | SWIFT_VERSION = 4.0;
473 | TARGETED_DEVICE_FAMILY = "1,2";
474 | };
475 | name = Release;
476 | };
477 | 5BD04DBB1E64943C00E5ED27 /* Debug */ = {
478 | isa = XCBuildConfiguration;
479 | buildSettings = {
480 | ALWAYS_SEARCH_USER_PATHS = NO;
481 | CLANG_ANALYZER_NONNULL = YES;
482 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
483 | CLANG_CXX_LIBRARY = "libc++";
484 | CLANG_ENABLE_MODULES = YES;
485 | CLANG_ENABLE_OBJC_ARC = YES;
486 | CLANG_WARN_BOOL_CONVERSION = YES;
487 | CLANG_WARN_CONSTANT_CONVERSION = YES;
488 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
489 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
490 | CLANG_WARN_EMPTY_BODY = YES;
491 | CLANG_WARN_ENUM_CONVERSION = YES;
492 | CLANG_WARN_INFINITE_RECURSION = YES;
493 | CLANG_WARN_INT_CONVERSION = YES;
494 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
495 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
496 | CLANG_WARN_UNREACHABLE_CODE = YES;
497 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
498 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
499 | COPY_PHASE_STRIP = NO;
500 | CURRENT_PROJECT_VERSION = 1;
501 | DEBUG_INFORMATION_FORMAT = dwarf;
502 | ENABLE_STRICT_OBJC_MSGSEND = YES;
503 | ENABLE_TESTABILITY = YES;
504 | GCC_C_LANGUAGE_STANDARD = gnu99;
505 | GCC_DYNAMIC_NO_PIC = NO;
506 | GCC_NO_COMMON_BLOCKS = YES;
507 | GCC_OPTIMIZATION_LEVEL = 0;
508 | GCC_PREPROCESSOR_DEFINITIONS = (
509 | "DEBUG=1",
510 | "$(inherited)",
511 | );
512 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
513 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
514 | GCC_WARN_UNDECLARED_SELECTOR = YES;
515 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
516 | GCC_WARN_UNUSED_FUNCTION = YES;
517 | GCC_WARN_UNUSED_VARIABLE = YES;
518 | IPHONEOS_DEPLOYMENT_TARGET = 10.2;
519 | MTL_ENABLE_DEBUG_INFO = YES;
520 | ONLY_ACTIVE_ARCH = YES;
521 | SDKROOT = iphoneos;
522 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
523 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
524 | TARGETED_DEVICE_FAMILY = "1,2";
525 | VERSIONING_SYSTEM = "apple-generic";
526 | VERSION_INFO_PREFIX = "";
527 | };
528 | name = Debug;
529 | };
530 | 5BD04DBC1E64943C00E5ED27 /* Release */ = {
531 | isa = XCBuildConfiguration;
532 | buildSettings = {
533 | ALWAYS_SEARCH_USER_PATHS = NO;
534 | CLANG_ANALYZER_NONNULL = YES;
535 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
536 | CLANG_CXX_LIBRARY = "libc++";
537 | CLANG_ENABLE_MODULES = YES;
538 | CLANG_ENABLE_OBJC_ARC = YES;
539 | CLANG_WARN_BOOL_CONVERSION = YES;
540 | CLANG_WARN_CONSTANT_CONVERSION = YES;
541 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
542 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
543 | CLANG_WARN_EMPTY_BODY = YES;
544 | CLANG_WARN_ENUM_CONVERSION = YES;
545 | CLANG_WARN_INFINITE_RECURSION = YES;
546 | CLANG_WARN_INT_CONVERSION = YES;
547 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
548 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
549 | CLANG_WARN_UNREACHABLE_CODE = YES;
550 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
551 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
552 | COPY_PHASE_STRIP = NO;
553 | CURRENT_PROJECT_VERSION = 1;
554 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
555 | ENABLE_NS_ASSERTIONS = NO;
556 | ENABLE_STRICT_OBJC_MSGSEND = YES;
557 | GCC_C_LANGUAGE_STANDARD = gnu99;
558 | GCC_NO_COMMON_BLOCKS = YES;
559 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
560 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
561 | GCC_WARN_UNDECLARED_SELECTOR = YES;
562 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
563 | GCC_WARN_UNUSED_FUNCTION = YES;
564 | GCC_WARN_UNUSED_VARIABLE = YES;
565 | IPHONEOS_DEPLOYMENT_TARGET = 10.2;
566 | MTL_ENABLE_DEBUG_INFO = NO;
567 | SDKROOT = iphoneos;
568 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
569 | TARGETED_DEVICE_FAMILY = "1,2";
570 | VALIDATE_PRODUCT = YES;
571 | VERSIONING_SYSTEM = "apple-generic";
572 | VERSION_INFO_PREFIX = "";
573 | };
574 | name = Release;
575 | };
576 | 5BD04DBE1E64943C00E5ED27 /* Debug */ = {
577 | isa = XCBuildConfiguration;
578 | buildSettings = {
579 | CODE_SIGN_IDENTITY = "iPhone Developer";
580 | DEFINES_MODULE = YES;
581 | DEVELOPMENT_TEAM = "";
582 | DYLIB_COMPATIBILITY_VERSION = 1;
583 | DYLIB_CURRENT_VERSION = 1;
584 | DYLIB_INSTALL_NAME_BASE = "@rpath";
585 | INFOPLIST_FILE = MTGSDKSwift/Info.plist;
586 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
587 | IPHONEOS_DEPLOYMENT_TARGET = 15.0;
588 | LD_RUNPATH_SEARCH_PATHS = (
589 | "$(inherited)",
590 | "@executable_path/Frameworks",
591 | "@loader_path/Frameworks",
592 | );
593 | MACOSX_DEPLOYMENT_TARGET = 12.4;
594 | MARKETING_VERSION = 1.1.1;
595 | PRODUCT_BUNDLE_IDENTIFIER = com.rpcarson.MTGSDKSwift;
596 | PRODUCT_NAME = "$(TARGET_NAME)";
597 | REGISTER_APP_GROUPS = NO;
598 | SKIP_INSTALL = YES;
599 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
600 | SUPPORTS_MACCATALYST = YES;
601 | SWIFT_SWIFT3_OBJC_INFERENCE = Off;
602 | SWIFT_VERSION = 4.0;
603 | TARGETED_DEVICE_FAMILY = "1,2";
604 | };
605 | name = Debug;
606 | };
607 | 5BD04DBF1E64943C00E5ED27 /* Release */ = {
608 | isa = XCBuildConfiguration;
609 | buildSettings = {
610 | CODE_SIGN_IDENTITY = "iPhone Developer";
611 | DEFINES_MODULE = YES;
612 | DEVELOPMENT_TEAM = "";
613 | DYLIB_COMPATIBILITY_VERSION = 1;
614 | DYLIB_CURRENT_VERSION = 1;
615 | DYLIB_INSTALL_NAME_BASE = "@rpath";
616 | INFOPLIST_FILE = MTGSDKSwift/Info.plist;
617 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
618 | IPHONEOS_DEPLOYMENT_TARGET = 15.0;
619 | LD_RUNPATH_SEARCH_PATHS = (
620 | "$(inherited)",
621 | "@executable_path/Frameworks",
622 | "@loader_path/Frameworks",
623 | );
624 | MACOSX_DEPLOYMENT_TARGET = 12.4;
625 | MARKETING_VERSION = 1.1.1;
626 | PRODUCT_BUNDLE_IDENTIFIER = com.rpcarson.MTGSDKSwift;
627 | PRODUCT_NAME = "$(TARGET_NAME)";
628 | REGISTER_APP_GROUPS = NO;
629 | SKIP_INSTALL = YES;
630 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
631 | SUPPORTS_MACCATALYST = YES;
632 | SWIFT_SWIFT3_OBJC_INFERENCE = Off;
633 | SWIFT_VERSION = 4.0;
634 | TARGETED_DEVICE_FAMILY = "1,2";
635 | };
636 | name = Release;
637 | };
638 | 5BD04DC11E64943C00E5ED27 /* Debug */ = {
639 | isa = XCBuildConfiguration;
640 | buildSettings = {
641 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
642 | DEVELOPMENT_TEAM = X68KF89T7U;
643 | INFOPLIST_FILE = MTGSDKSwiftTests/Info.plist;
644 | IPHONEOS_DEPLOYMENT_TARGET = 15.0;
645 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
646 | PRODUCT_BUNDLE_IDENTIFIER = com.rpcarson.MTGSDKSwiftTests;
647 | PRODUCT_NAME = "$(TARGET_NAME)";
648 | REGISTER_APP_GROUPS = NO;
649 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
650 | SUPPORTS_MACCATALYST = YES;
651 | SWIFT_SWIFT3_OBJC_INFERENCE = Off;
652 | SWIFT_VERSION = 4.0;
653 | TARGETED_DEVICE_FAMILY = "1,2";
654 | };
655 | name = Debug;
656 | };
657 | 5BD04DC21E64943C00E5ED27 /* Release */ = {
658 | isa = XCBuildConfiguration;
659 | buildSettings = {
660 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
661 | DEVELOPMENT_TEAM = X68KF89T7U;
662 | INFOPLIST_FILE = MTGSDKSwiftTests/Info.plist;
663 | IPHONEOS_DEPLOYMENT_TARGET = 15.0;
664 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
665 | PRODUCT_BUNDLE_IDENTIFIER = com.rpcarson.MTGSDKSwiftTests;
666 | PRODUCT_NAME = "$(TARGET_NAME)";
667 | REGISTER_APP_GROUPS = NO;
668 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
669 | SUPPORTS_MACCATALYST = YES;
670 | SWIFT_SWIFT3_OBJC_INFERENCE = Off;
671 | SWIFT_VERSION = 4.0;
672 | TARGETED_DEVICE_FAMILY = "1,2";
673 | };
674 | name = Release;
675 | };
676 | /* End XCBuildConfiguration section */
677 |
678 | /* Begin XCConfigurationList section */
679 | 5B87D69320596D6B0098553C /* Build configuration list for PBXNativeTarget "TestApplication" */ = {
680 | isa = XCConfigurationList;
681 | buildConfigurations = (
682 | 5B87D69420596D6B0098553C /* Debug */,
683 | 5B87D69520596D6B0098553C /* Release */,
684 | );
685 | defaultConfigurationIsVisible = 0;
686 | defaultConfigurationName = Release;
687 | };
688 | 5BD04DA31E64943C00E5ED27 /* Build configuration list for PBXProject "MTGSDKSwift" */ = {
689 | isa = XCConfigurationList;
690 | buildConfigurations = (
691 | 5BD04DBB1E64943C00E5ED27 /* Debug */,
692 | 5BD04DBC1E64943C00E5ED27 /* Release */,
693 | );
694 | defaultConfigurationIsVisible = 0;
695 | defaultConfigurationName = Release;
696 | };
697 | 5BD04DBD1E64943C00E5ED27 /* Build configuration list for PBXNativeTarget "MTGSDKSwift" */ = {
698 | isa = XCConfigurationList;
699 | buildConfigurations = (
700 | 5BD04DBE1E64943C00E5ED27 /* Debug */,
701 | 5BD04DBF1E64943C00E5ED27 /* Release */,
702 | );
703 | defaultConfigurationIsVisible = 0;
704 | defaultConfigurationName = Release;
705 | };
706 | 5BD04DC01E64943C00E5ED27 /* Build configuration list for PBXNativeTarget "MTGSDKSwiftTests" */ = {
707 | isa = XCConfigurationList;
708 | buildConfigurations = (
709 | 5BD04DC11E64943C00E5ED27 /* Debug */,
710 | 5BD04DC21E64943C00E5ED27 /* Release */,
711 | );
712 | defaultConfigurationIsVisible = 0;
713 | defaultConfigurationName = Release;
714 | };
715 | /* End XCConfigurationList section */
716 | };
717 | rootObject = 5BD04DA01E64943C00E5ED27 /* Project object */;
718 | }
719 |
--------------------------------------------------------------------------------