├── .github ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .ruby-version ├── .swiftlint.yml ├── Cartfile ├── Gemfile ├── LICENSE ├── PyConJP.xcodeproj ├── project.pbxproj └── xcshareddata │ └── xcschemes │ └── PyConJP.xcscheme ├── PyConJP ├── Application │ ├── AppDelegate.swift │ ├── PCJConfig.swift │ └── PCJNotificationConfig.swift ├── Assets.xcassets │ ├── App │ │ ├── Contents.json │ │ ├── Icon │ │ │ ├── BarItem │ │ │ │ ├── BookmarkCollections.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ ├── bookmark_collections@1x.png │ │ │ │ │ ├── bookmark_collections@2x.png │ │ │ │ │ └── bookmark_collections@3x.png │ │ │ │ ├── Conference.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ ├── record_voice_over@1x.png │ │ │ │ │ ├── record_voice_over@2x.png │ │ │ │ │ └── record_voice_over@3x.png │ │ │ │ ├── Contents.json │ │ │ │ ├── Events.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ ├── view_list@1x.png │ │ │ │ │ ├── view_list@2x.png │ │ │ │ │ └── view_list@3x.png │ │ │ │ └── More.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ ├── more_horiz@1x.png │ │ │ │ │ ├── more_horiz@2x.png │ │ │ │ │ └── more_horiz@3x.png │ │ │ ├── Contents.json │ │ │ ├── Talk │ │ │ │ ├── BookmarkOff.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ ├── bookmark_off@1x.png │ │ │ │ │ ├── bookmark_off@2x.png │ │ │ │ │ └── bookmark_off@3x.png │ │ │ │ ├── BookmarkOn.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ ├── bookmark_on@1x.png │ │ │ │ │ ├── bookmark_on@2x.png │ │ │ │ │ └── bookmark_on@3x.png │ │ │ │ ├── Clock.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ ├── clock@1x.png │ │ │ │ │ ├── clock@2x.png │ │ │ │ │ └── clock@3x.png │ │ │ │ ├── Contents.json │ │ │ │ ├── Pin.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ ├── place@1x.png │ │ │ │ │ ├── place@2x.png │ │ │ │ │ └── place@3x.png │ │ │ │ └── Speaker.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ ├── person@1x.png │ │ │ │ │ ├── person@2x.png │ │ │ │ │ └── person@3x.png │ │ │ └── Utility │ │ │ │ ├── Close.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── close@1x.png │ │ │ │ ├── close@2x.png │ │ │ │ └── close@3x.png │ │ │ │ ├── Contents.json │ │ │ │ └── Logo.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── icon@2x.png │ │ │ │ └── icon@3x.png │ │ └── Image │ │ │ ├── Contents.json │ │ │ └── Map │ │ │ ├── Contents.json │ │ │ ├── Floor │ │ │ ├── Contents.json │ │ │ ├── FirstFloorMap.imageset │ │ │ │ ├── 1st-floor@1x.png │ │ │ │ ├── 1st-floor@2x.png │ │ │ │ ├── 1st-floor@3x.png │ │ │ │ └── Contents.json │ │ │ ├── SecondFloorMap.imageset │ │ │ │ ├── 2nd-floor@1x.png │ │ │ │ ├── 2nd-floor@2x.png │ │ │ │ ├── 2nd-floor@3x.png │ │ │ │ └── Contents.json │ │ │ └── ThirdFloorMap.imageset │ │ │ │ ├── 3rd-floor@1x.png │ │ │ │ ├── 3rd-floor@2x.png │ │ │ │ ├── 3rd-floor@3x.png │ │ │ │ └── Contents.json │ │ │ └── Room │ │ │ ├── Contents.json │ │ │ ├── Room201Map.imageset │ │ │ ├── Contents.json │ │ │ ├── room_201.png │ │ │ ├── room_201@2x.png │ │ │ └── room_201@3x.png │ │ │ ├── Room202Map.imageset │ │ │ ├── Contents.json │ │ │ ├── room_202.png │ │ │ ├── room_202@2x.png │ │ │ └── room_202@3x.png │ │ │ ├── Room203Map.imageset │ │ │ ├── Contents.json │ │ │ ├── room_203.png │ │ │ ├── room_203@2x.png │ │ │ └── room_203@3x.png │ │ │ ├── Room204Map.imageset │ │ │ ├── Contents.json │ │ │ ├── room_204.png │ │ │ ├── room_204@2x.png │ │ │ └── room_204@3x.png │ │ │ └── Room205Map.imageset │ │ │ ├── Contents.json │ │ │ ├── room_205.png │ │ │ ├── room_205@2x.png │ │ │ └── room_205@3x.png │ ├── AppIcon.appiconset │ │ ├── 1024x1024.jpg │ │ ├── 20.0x20.0@1x.png │ │ ├── 20.0x20.0@2x-1.png │ │ ├── 20.0x20.0@2x.png │ │ ├── 20.0x20.0@3x.png │ │ ├── 29.0x29.0@1x.png │ │ ├── 29.0x29.0@2x-1.png │ │ ├── 29.0x29.0@2x.png │ │ ├── 29.0x29.0@3x.png │ │ ├── 40.0x40.0@1x.png │ │ ├── 40.0x40.0@2x-1.png │ │ ├── 40.0x40.0@2x.png │ │ ├── 40.0x40.0@3x.png │ │ ├── 60.0x60.0@2x.png │ │ ├── 60.0x60.0@3x.png │ │ ├── 76.0x76.0@1x.png │ │ ├── 76.0x76.0@2x.png │ │ ├── 83.5x83.5@2x.png │ │ └── Contents.json │ ├── Colors │ │ ├── Contents.json │ │ ├── Custom │ │ │ ├── Contents.json │ │ │ ├── crimson.colorset │ │ │ │ └── Contents.json │ │ │ ├── davyGray.colorset │ │ │ │ └── Contents.json │ │ │ ├── goldenrod.colorset │ │ │ │ └── Contents.json │ │ │ ├── lightYellow.colorset │ │ │ │ └── Contents.json │ │ │ ├── navy.colorset │ │ │ │ └── Contents.json │ │ │ └── silver.colorset │ │ │ │ └── Contents.json │ │ └── External │ │ │ ├── Contents.json │ │ │ ├── facebook.colorset │ │ │ └── Contents.json │ │ │ └── twitter.colorset │ │ │ └── Contents.json │ ├── Contents.json │ └── LaunchImage.launchimage │ │ ├── Contents.json │ │ ├── Landscape 5.png │ │ ├── LaunchImageX.png │ │ ├── Portrait 3.5.png │ │ ├── Portrait 4.7.png │ │ ├── Portrait 4.png │ │ └── Portrait 5.5.png ├── DataStore │ ├── Conference │ │ └── ConferenceTimetableDataStore.swift │ ├── DataSource │ │ ├── More │ │ │ └── StaffListDataSource.swift │ │ ├── TalkDetail │ │ │ └── SpeakersCollectionViewDataSource.swift │ │ └── Timeline │ │ │ ├── Bookmark │ │ │ └── BookmarkListDataSource.swift │ │ │ ├── Conference │ │ │ └── ConferenceListDataSource.swift │ │ │ └── TimelineDataSource.swift │ └── More │ │ └── MoreListDataStore.swift ├── Extension │ ├── AppDelegateExtension.swift │ ├── ArrayExtension.swift │ ├── DateExtension.swift │ ├── StringExtension.swift │ ├── UIColorExtension.swift │ ├── UIDeviceExtension.swift │ ├── UIImageViewExtension.swift │ ├── UIStoryboardExtension.swift │ └── UIViewExtension.swift ├── Model │ ├── APIRequest │ │ ├── GitHub │ │ │ ├── StaffListAPIRequest.swift │ │ │ └── SurveyURLAPIRequest.swift │ │ └── PyConJP │ │ │ ├── TalkDetailAPIRequest.swift │ │ │ └── TalksAPIRequest.swift │ ├── Class │ │ └── TalkObject.swift │ ├── Enum │ │ ├── Error │ │ │ └── RealmError.swift │ │ ├── Language.swift │ │ ├── NotificationType.swift │ │ ├── PyConJPDate.swift │ │ └── Room.swift │ ├── Realm │ │ ├── LoadFavoriteTalksRequest.swift │ │ ├── LoadTalksRequest.swift │ │ └── SaveTalksRequest.swift │ └── Struct │ │ ├── Category.swift │ │ ├── Level.swift │ │ ├── Place.swift │ │ ├── Speaker.swift │ │ ├── Staff.swift │ │ ├── Talk.swift │ │ ├── TalkDetail.swift │ │ ├── Team.swift │ │ ├── Timeline.swift │ │ ├── Timetable.swift │ │ └── Track.swift ├── Protocol │ ├── DummyJSON │ │ ├── DummyTalkDetailProtocol.swift │ │ └── DummyTalksProtocol.swift │ ├── ErrorAlertProtocol.swift │ ├── GestureProtocol.swift │ ├── Realm │ │ ├── RealmLoadTalksProtocol.swift │ │ └── RealmSaveTalksProtocol.swift │ ├── UI │ │ ├── NibInstantitable.swift │ │ └── StoryboardIdentifiable.swift │ └── URLScheme │ │ ├── MailURLSchemeProtocol.swift │ │ └── TwitterURLSchemeProtocol.swift ├── Resource │ ├── DummyTalkDetail.json │ ├── DummyTalks.json │ ├── Localizable │ │ ├── Base.lproj │ │ │ ├── EventList.strings │ │ │ ├── Language.strings │ │ │ ├── Localizable.strings │ │ │ ├── Map.strings │ │ │ ├── MoreList.strings │ │ │ └── URLScheme.strings │ │ ├── en.lproj │ │ │ ├── EventList.strings │ │ │ ├── Language.strings │ │ │ ├── Localizable.strings │ │ │ ├── Map.strings │ │ │ ├── MoreList.strings │ │ │ └── URLScheme.strings │ │ └── ja.lproj │ │ │ ├── EventList.strings │ │ │ ├── Language.strings │ │ │ ├── Localizable.strings │ │ │ ├── Map.strings │ │ │ ├── MoreList.strings │ │ │ └── URLScheme.strings │ └── Settings.bundle │ │ ├── Root.plist │ │ ├── com.mono0926.LicensePlist.latest_result.txt │ │ ├── com.mono0926.LicensePlist.plist │ │ ├── com.mono0926.LicensePlist │ │ ├── APIKit.plist │ │ ├── Kingfisher.plist │ │ ├── Result.plist │ │ ├── SpreadsheetView.plist │ │ └── realm-cocoa.plist │ │ ├── en.lproj │ │ └── Root.strings │ │ └── ja.lproj │ │ └── Root.strings ├── Storyboard │ ├── Base.lproj │ │ ├── Bookmark.storyboard │ │ ├── Conference.storyboard │ │ ├── Events.storyboard │ │ ├── LaunchScreen.storyboard │ │ ├── Main.storyboard │ │ └── More.storyboard │ ├── en.lproj │ │ ├── Bookmark.strings │ │ ├── Conference.strings │ │ ├── Events.strings │ │ ├── LaunchScreen.strings │ │ ├── Main.strings │ │ └── More.strings │ └── ja.lproj │ │ ├── Bookmark.strings │ │ ├── Conference.strings │ │ ├── Events.strings │ │ ├── LaunchScreen.strings │ │ ├── Main.strings │ │ └── More.strings ├── Support Files │ └── Info.plist ├── View │ ├── CustomImageView.swift │ ├── SpreadsheetViewCell │ │ ├── TimetableCell.swift │ │ ├── TimetableCell.xib │ │ ├── TimetableRoomCell.swift │ │ ├── TimetableRoomCell.xib │ │ ├── TimetableTimeAxisCell.swift │ │ └── TimetableTimeAxisCell.xib │ ├── UICollectionViewCell │ │ ├── SpeakerCollectionViewCell.swift │ │ └── SpeakerCollectionViewCell.xib │ └── UITableViewCell │ │ ├── StaffTableViewCell.swift │ │ ├── StaffTableViewCell.xib │ │ ├── TalkTableViewCell.swift │ │ └── TalkTableViewCell.xib └── ViewController │ ├── Base │ ├── BaseTabBarController.swift │ ├── DetailImageViewController.swift │ ├── TalkDetailViewController.swift │ └── ZoomableImageViewController.swift │ ├── Bookmark │ └── BookmarkListViewController.swift │ ├── Conference │ ├── ConferenceBaseViewController.swift │ ├── ConferenceDateViewController.swift │ ├── ConferenceListViewController.swift │ ├── ConferenceModelController.swift │ ├── ConferencePageViewController.swift │ ├── ConferenceTimetableViewController.swift │ └── ConferenceViewController.swift │ ├── Events │ └── EventsListViewController.swift │ ├── More │ ├── FloorMapListViewController.swift │ ├── FloorMapZoomableImageViewController.swift │ ├── MapListViewController.swift │ ├── MapViewController.swift │ ├── MoreListViewController.swift │ └── StaffListViewController.swift │ └── WebView │ └── PCJWKWebViewController.swift ├── PyConJPTests ├── Info.plist └── PyConJPTests.swift ├── PyConJPUITests ├── Info.plist └── PyConJPUITests.swift ├── README.md ├── WebAPIFramework ├── APIKit │ ├── GitHubRequest.swift │ └── PyConJPRequest.swift ├── Error │ └── APIError.swift ├── Info.plist ├── LocaleExtension.swift ├── WebAPIFramework.h └── WebConfig.swift ├── WebAPIFrameworkTests ├── Info.plist └── WebAPIFrameworkTests.swift └── fastlane ├── Appfile ├── Deliverfile ├── Fastfile ├── README.md ├── metadata ├── app_icon.jpg ├── copyright.txt ├── en-US │ ├── description.txt │ ├── keywords.txt │ ├── marketing_url.txt │ ├── name.txt │ ├── privacy_url.txt │ ├── promotional_text.txt │ ├── release_notes.txt │ ├── subtitle.txt │ └── support_url.txt ├── ja │ ├── description.txt │ ├── keywords.txt │ ├── marketing_url.txt │ ├── name.txt │ ├── privacy_url.txt │ ├── promotional_text.txt │ ├── release_notes.txt │ ├── subtitle.txt │ └── support_url.txt ├── primary_category.txt ├── primary_first_sub_category.txt ├── primary_second_sub_category.txt ├── review_information │ ├── demo_password.txt │ ├── demo_user.txt │ ├── email_address.txt │ ├── first_name.txt │ ├── last_name.txt │ ├── notes.txt │ └── phone_number.txt ├── secondary_category.txt ├── secondary_first_sub_category.txt ├── secondary_second_sub_category.txt └── trade_representative_contact_information │ ├── address_line1.txt │ ├── address_line2.txt │ ├── city_name.txt │ ├── country.txt │ ├── is_displayed_on_app_store.txt │ ├── postal_code.txt │ ├── state.txt │ └── trade_name.txt └── screenshots ├── README.txt ├── en-US ├── 1_iphone58_1.1.png ├── 1_iphone6Plus_1.1.PNG ├── 2_iphone58_2.2.png ├── 2_iphone6Plus_2.2.PNG ├── 3_iphone58_3.3.png ├── 3_iphone6Plus_3.3.PNG ├── 4_iphone58_4.4.png └── 4_iphone6Plus_4.4.PNG └── ja ├── 1_iphone58_1.1.png ├── 1_iphone6Plus_1.1.PNG ├── 2_iphone58_2.2.png ├── 2_iphone6Plus_2.2.PNG ├── 3_iphone58_3.3.png ├── 3_iphone6Plus_3.3.PNG ├── 4_iphone58_4.4.png └── 4_iphone6Plus_4.4.PNG /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Issue Description 2 | 3 | ### Environment 4 | 5 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | refs: 2 | 3 | ### Motivation and Context 4 | 5 | ### Description 6 | 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | ## Build generated 3 | build/ 4 | DerivedData/ 5 | 6 | ## Various settings 7 | xcuserdata/ 8 | 9 | ## Private setting 10 | *.pbxuser 11 | *mode1v3 12 | *mode2v3 13 | *perspectivev3 14 | 15 | ## Default setting 16 | !default.pbxuser 17 | !default.mode1v3 18 | !default.mode2v3 19 | !default.perspectivev3 20 | 21 | ## Other 22 | *.moved-aside 23 | *.xccheckout 24 | *.xcscmblueprint 25 | 26 | ## CustomScheme 27 | *.xcodeproj/xcuserdata 28 | *.xcworkspace/xcuserdata 29 | 30 | # Bundler 31 | .bundle 32 | Gemfile.lock 33 | vendor 34 | 35 | # CocoaPods 36 | Pods/* 37 | Podfile.lock 38 | !default.xcworkspace 39 | *.xcworkspace 40 | 41 | # Carthage 42 | Carthage/* 43 | Cartfile.resolved 44 | 45 | # fastlane 46 | #fastlane/* 47 | !fastlane/Fastfile 48 | 49 | # AppCode 50 | ## User-specific stuff: 51 | .idea/workspace.xml 52 | .idea/tasks.xml 53 | 54 | ## Sensitive or high-churn files: 55 | .idea/dataSources.ids 56 | .idea/dataSources.xml 57 | .idea/dataSources.local.xml 58 | .idea/sqlDataSources.xml 59 | .idea/dynamic.xml 60 | .idea/uiDesigner.xml 61 | 62 | # macOS 63 | .DS_Store 64 | .AppleDouble 65 | .LSOverride 66 | 67 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 2.4.0 2 | -------------------------------------------------------------------------------- /.swiftlint.yml: -------------------------------------------------------------------------------- 1 | disabled_rules: 2 | # ForceCastを許可 3 | - force_cast 4 | # FourceTryを許可 5 | - force_try 6 | # ネストの許可 7 | #- nesting 8 | # コードの記載のない改行を許可 9 | - trailing_whitespace 10 | # パラメータ個数条件を解除 11 | - function_parameter_count 12 | # 変数名の条件を解除 13 | - variable_name 14 | 15 | # 追加したOSSライブラリを対象としない 16 | excluded: 17 | - Pods/ 18 | - Podfile 19 | - Podfile.lock 20 | - Carthage/ 21 | - Carfile 22 | - Cartfile.resolved 23 | - fastlane/ 24 | - vendor/ 25 | 26 | # 1行あたりの文字数制限を300に変更 27 | line_length: 300 28 | 29 | # 変数名の長さのMAXとMINを変更 30 | #variable_name: 31 | # max_length: 32 | # warning: 60 33 | # error: 80 34 | # min_length: 35 | # warning: 1 36 | # error: 0 37 | -------------------------------------------------------------------------------- /Cartfile: -------------------------------------------------------------------------------- 1 | # PyCon JP use Library 2 | github "ishkawa/APIKit" ~> 3.0 3 | github "antitypical/Result" ~> 3.0 4 | github "onevcat/Kingfisher" ~> 3.0 5 | github "realm/realm-cocoa" ~> 2.0 6 | github "kishikawakatsumi/SpreadsheetView" 7 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | source "https://rubygems.org" 3 | 4 | gem "fastlane" 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 PyCon JP 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 | -------------------------------------------------------------------------------- /PyConJP/Application/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2016/02/16. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import APIKit 11 | import RealmSwift 12 | 13 | @UIApplicationMain 14 | class AppDelegate: UIResponder, UIApplicationDelegate, ErrorAlertProtocol { 15 | 16 | var window: UIWindow? 17 | 18 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 19 | 20 | getTalksFromAPI() 21 | 22 | UINavigationBar.appearance().barTintColor = UIColor.navy 23 | UINavigationBar.appearance().tintColor = .white 24 | UINavigationBar.appearance().titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white] 25 | if #available(iOS 11.0, *) { 26 | UINavigationBar.appearance().largeTitleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white] 27 | } 28 | 29 | UITabBar.appearance().tintColor = UIColor.goldenrod 30 | UITabBarItem.appearance().setTitleTextAttributes([NSAttributedStringKey.font: UIFont.boldSystemFont(ofSize: 10), NSAttributedStringKey.foregroundColor: UIColor.goldenrod], for: .selected) 31 | 32 | let configuration = Realm.Configuration(schemaVersion: 1, deleteRealmIfMigrationNeeded: true) 33 | Realm.Configuration.defaultConfiguration = configuration 34 | 35 | return true 36 | } 37 | 38 | } 39 | 40 | extension AppDelegate { 41 | 42 | fileprivate func getTalksFromAPI() { 43 | let request = TalksAPIRequest() 44 | Session.send(request) { [weak self](result) in 45 | switch result { 46 | case .success(let talks): 47 | try? SaveTalksRequest().save(talks: talks) 48 | NotificationCenter.default.post(name: Notification.Name(rawValue: PCJNotificationConfig.completeFetchDataNotification), object: nil) 49 | case .failure(let error): 50 | self?.showErrorAlart(with: error) 51 | } 52 | } 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /PyConJP/Application/PCJConfig.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PCJConfig.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 8/30/2016. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | enum PCJConfig { 12 | 13 | static let mailAddress = "symposion@pycon.jp" 14 | 15 | } 16 | -------------------------------------------------------------------------------- /PyConJP/Application/PCJNotificationConfig.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PCJNotificationConfig.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2016/07/21. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | enum PCJNotificationConfig { 12 | 13 | static let completeFetchDataNotification = "CompleteFetchDateNotification" 14 | 15 | } 16 | -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/BarItem/BookmarkCollections.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "bookmark_collections@1x.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "bookmark_collections@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "bookmark_collections@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/BarItem/BookmarkCollections.imageset/bookmark_collections@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/BarItem/BookmarkCollections.imageset/bookmark_collections@1x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/BarItem/BookmarkCollections.imageset/bookmark_collections@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/BarItem/BookmarkCollections.imageset/bookmark_collections@2x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/BarItem/BookmarkCollections.imageset/bookmark_collections@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/BarItem/BookmarkCollections.imageset/bookmark_collections@3x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/BarItem/Conference.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "record_voice_over@1x.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "record_voice_over@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "record_voice_over@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/BarItem/Conference.imageset/record_voice_over@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/BarItem/Conference.imageset/record_voice_over@1x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/BarItem/Conference.imageset/record_voice_over@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/BarItem/Conference.imageset/record_voice_over@2x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/BarItem/Conference.imageset/record_voice_over@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/BarItem/Conference.imageset/record_voice_over@3x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/BarItem/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/BarItem/Events.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "view_list@1x.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "view_list@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "view_list@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/BarItem/Events.imageset/view_list@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/BarItem/Events.imageset/view_list@1x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/BarItem/Events.imageset/view_list@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/BarItem/Events.imageset/view_list@2x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/BarItem/Events.imageset/view_list@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/BarItem/Events.imageset/view_list@3x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/BarItem/More.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "more_horiz@1x.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "more_horiz@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "more_horiz@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/BarItem/More.imageset/more_horiz@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/BarItem/More.imageset/more_horiz@1x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/BarItem/More.imageset/more_horiz@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/BarItem/More.imageset/more_horiz@2x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/BarItem/More.imageset/more_horiz@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/BarItem/More.imageset/more_horiz@3x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/Talk/BookmarkOff.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "bookmark_off@1x.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "bookmark_off@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "bookmark_off@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/Talk/BookmarkOff.imageset/bookmark_off@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/Talk/BookmarkOff.imageset/bookmark_off@1x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/Talk/BookmarkOff.imageset/bookmark_off@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/Talk/BookmarkOff.imageset/bookmark_off@2x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/Talk/BookmarkOff.imageset/bookmark_off@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/Talk/BookmarkOff.imageset/bookmark_off@3x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/Talk/BookmarkOn.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "bookmark_on@1x.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "bookmark_on@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "bookmark_on@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/Talk/BookmarkOn.imageset/bookmark_on@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/Talk/BookmarkOn.imageset/bookmark_on@1x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/Talk/BookmarkOn.imageset/bookmark_on@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/Talk/BookmarkOn.imageset/bookmark_on@2x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/Talk/BookmarkOn.imageset/bookmark_on@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/Talk/BookmarkOn.imageset/bookmark_on@3x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/Talk/Clock.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "clock@1x.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "clock@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "clock@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/Talk/Clock.imageset/clock@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/Talk/Clock.imageset/clock@1x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/Talk/Clock.imageset/clock@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/Talk/Clock.imageset/clock@2x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/Talk/Clock.imageset/clock@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/Talk/Clock.imageset/clock@3x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/Talk/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/Talk/Pin.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "place@1x.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "place@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "place@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/Talk/Pin.imageset/place@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/Talk/Pin.imageset/place@1x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/Talk/Pin.imageset/place@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/Talk/Pin.imageset/place@2x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/Talk/Pin.imageset/place@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/Talk/Pin.imageset/place@3x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/Talk/Speaker.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "person@1x.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "person@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "person@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/Talk/Speaker.imageset/person@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/Talk/Speaker.imageset/person@1x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/Talk/Speaker.imageset/person@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/Talk/Speaker.imageset/person@2x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/Talk/Speaker.imageset/person@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/Talk/Speaker.imageset/person@3x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/Utility/Close.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "close@1x.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "close@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "close@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/Utility/Close.imageset/close@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/Utility/Close.imageset/close@1x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/Utility/Close.imageset/close@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/Utility/Close.imageset/close@2x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/Utility/Close.imageset/close@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/Utility/Close.imageset/close@3x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/Utility/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/Utility/Logo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "icon@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "icon@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/Utility/Logo.imageset/icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/Utility/Logo.imageset/icon@2x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Icon/Utility/Logo.imageset/icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Icon/Utility/Logo.imageset/icon@3x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Floor/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Floor/FirstFloorMap.imageset/1st-floor@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Image/Map/Floor/FirstFloorMap.imageset/1st-floor@1x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Floor/FirstFloorMap.imageset/1st-floor@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Image/Map/Floor/FirstFloorMap.imageset/1st-floor@2x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Floor/FirstFloorMap.imageset/1st-floor@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Image/Map/Floor/FirstFloorMap.imageset/1st-floor@3x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Floor/FirstFloorMap.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "1st-floor@1x.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "1st-floor@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "1st-floor@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Floor/SecondFloorMap.imageset/2nd-floor@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Image/Map/Floor/SecondFloorMap.imageset/2nd-floor@1x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Floor/SecondFloorMap.imageset/2nd-floor@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Image/Map/Floor/SecondFloorMap.imageset/2nd-floor@2x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Floor/SecondFloorMap.imageset/2nd-floor@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Image/Map/Floor/SecondFloorMap.imageset/2nd-floor@3x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Floor/SecondFloorMap.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "2nd-floor@1x.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "2nd-floor@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "2nd-floor@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Floor/ThirdFloorMap.imageset/3rd-floor@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Image/Map/Floor/ThirdFloorMap.imageset/3rd-floor@1x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Floor/ThirdFloorMap.imageset/3rd-floor@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Image/Map/Floor/ThirdFloorMap.imageset/3rd-floor@2x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Floor/ThirdFloorMap.imageset/3rd-floor@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Image/Map/Floor/ThirdFloorMap.imageset/3rd-floor@3x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Floor/ThirdFloorMap.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "3rd-floor@1x.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "3rd-floor@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "3rd-floor@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Room/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Room/Room201Map.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "room_201.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "room_201@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "room_201@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Room/Room201Map.imageset/room_201.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Image/Map/Room/Room201Map.imageset/room_201.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Room/Room201Map.imageset/room_201@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Image/Map/Room/Room201Map.imageset/room_201@2x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Room/Room201Map.imageset/room_201@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Image/Map/Room/Room201Map.imageset/room_201@3x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Room/Room202Map.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "room_202.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "room_202@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "room_202@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Room/Room202Map.imageset/room_202.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Image/Map/Room/Room202Map.imageset/room_202.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Room/Room202Map.imageset/room_202@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Image/Map/Room/Room202Map.imageset/room_202@2x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Room/Room202Map.imageset/room_202@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Image/Map/Room/Room202Map.imageset/room_202@3x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Room/Room203Map.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "room_203.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "room_203@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "room_203@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Room/Room203Map.imageset/room_203.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Image/Map/Room/Room203Map.imageset/room_203.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Room/Room203Map.imageset/room_203@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Image/Map/Room/Room203Map.imageset/room_203@2x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Room/Room203Map.imageset/room_203@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Image/Map/Room/Room203Map.imageset/room_203@3x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Room/Room204Map.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "room_204.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "room_204@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "room_204@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Room/Room204Map.imageset/room_204.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Image/Map/Room/Room204Map.imageset/room_204.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Room/Room204Map.imageset/room_204@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Image/Map/Room/Room204Map.imageset/room_204@2x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Room/Room204Map.imageset/room_204@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Image/Map/Room/Room204Map.imageset/room_204@3x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Room/Room205Map.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "room_205.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "room_205@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "room_205@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Room/Room205Map.imageset/room_205.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Image/Map/Room/Room205Map.imageset/room_205.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Room/Room205Map.imageset/room_205@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Image/Map/Room/Room205Map.imageset/room_205@2x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/App/Image/Map/Room/Room205Map.imageset/room_205@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/App/Image/Map/Room/Room205Map.imageset/room_205@3x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/AppIcon.appiconset/1024x1024.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/AppIcon.appiconset/1024x1024.jpg -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/AppIcon.appiconset/20.0x20.0@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/AppIcon.appiconset/20.0x20.0@1x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/AppIcon.appiconset/20.0x20.0@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/AppIcon.appiconset/20.0x20.0@2x-1.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/AppIcon.appiconset/20.0x20.0@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/AppIcon.appiconset/20.0x20.0@2x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/AppIcon.appiconset/20.0x20.0@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/AppIcon.appiconset/20.0x20.0@3x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/AppIcon.appiconset/29.0x29.0@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/AppIcon.appiconset/29.0x29.0@1x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/AppIcon.appiconset/29.0x29.0@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/AppIcon.appiconset/29.0x29.0@2x-1.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/AppIcon.appiconset/29.0x29.0@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/AppIcon.appiconset/29.0x29.0@2x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/AppIcon.appiconset/29.0x29.0@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/AppIcon.appiconset/29.0x29.0@3x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/AppIcon.appiconset/40.0x40.0@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/AppIcon.appiconset/40.0x40.0@1x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/AppIcon.appiconset/40.0x40.0@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/AppIcon.appiconset/40.0x40.0@2x-1.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/AppIcon.appiconset/40.0x40.0@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/AppIcon.appiconset/40.0x40.0@2x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/AppIcon.appiconset/40.0x40.0@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/AppIcon.appiconset/40.0x40.0@3x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/AppIcon.appiconset/60.0x60.0@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/AppIcon.appiconset/60.0x60.0@2x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/AppIcon.appiconset/60.0x60.0@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/AppIcon.appiconset/60.0x60.0@3x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/AppIcon.appiconset/76.0x76.0@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/AppIcon.appiconset/76.0x76.0@1x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/AppIcon.appiconset/76.0x76.0@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/AppIcon.appiconset/76.0x76.0@2x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/AppIcon.appiconset/83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/AppIcon.appiconset/83.5x83.5@2x.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "20.0x20.0@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "20.0x20.0@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "29.0x29.0@2x.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "29.0x29.0@3x.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "40x40", 29 | "idiom" : "iphone", 30 | "filename" : "40.0x40.0@2x.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "40.0x40.0@3x.png", 37 | "scale" : "3x" 38 | }, 39 | { 40 | "size" : "60x60", 41 | "idiom" : "iphone", 42 | "filename" : "60.0x60.0@2x.png", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "60.0x60.0@3x.png", 49 | "scale" : "3x" 50 | }, 51 | { 52 | "size" : "20x20", 53 | "idiom" : "ipad", 54 | "filename" : "20.0x20.0@1x.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "20.0x20.0@2x-1.png", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "size" : "29x29", 65 | "idiom" : "ipad", 66 | "filename" : "29.0x29.0@1x.png", 67 | "scale" : "1x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "29.0x29.0@2x-1.png", 73 | "scale" : "2x" 74 | }, 75 | { 76 | "size" : "40x40", 77 | "idiom" : "ipad", 78 | "filename" : "40.0x40.0@1x.png", 79 | "scale" : "1x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "40.0x40.0@2x-1.png", 85 | "scale" : "2x" 86 | }, 87 | { 88 | "size" : "76x76", 89 | "idiom" : "ipad", 90 | "filename" : "76.0x76.0@1x.png", 91 | "scale" : "1x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "76.0x76.0@2x.png", 97 | "scale" : "2x" 98 | }, 99 | { 100 | "size" : "83.5x83.5", 101 | "idiom" : "ipad", 102 | "filename" : "83.5x83.5@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "1024x1024", 107 | "idiom" : "ios-marketing", 108 | "filename" : "1024x1024.jpg", 109 | "scale" : "1x" 110 | } 111 | ], 112 | "info" : { 113 | "version" : 1, 114 | "author" : "xcode" 115 | } 116 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/Colors/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/Colors/Custom/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/Colors/Custom/crimson.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | }, 6 | "colors" : [ 7 | { 8 | "idiom" : "universal", 9 | "color" : { 10 | "color-space" : "srgb", 11 | "components" : { 12 | "red" : "0.839", 13 | "alpha" : "1.000", 14 | "blue" : "0.227", 15 | "green" : "0.000" 16 | } 17 | } 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/Colors/Custom/davyGray.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | }, 6 | "colors" : [ 7 | { 8 | "idiom" : "universal", 9 | "color" : { 10 | "color-space" : "srgb", 11 | "components" : { 12 | "red" : "0.333", 13 | "alpha" : "1.000", 14 | "blue" : "0.333", 15 | "green" : "0.333" 16 | } 17 | } 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/Colors/Custom/goldenrod.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | }, 6 | "colors" : [ 7 | { 8 | "idiom" : "universal", 9 | "color" : { 10 | "color-space" : "srgb", 11 | "components" : { 12 | "red" : "0.886", 13 | "alpha" : "1.000", 14 | "blue" : "0.078", 15 | "green" : "0.667" 16 | } 17 | } 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/Colors/Custom/lightYellow.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | }, 6 | "colors" : [ 7 | { 8 | "idiom" : "universal", 9 | "color" : { 10 | "color-space" : "srgb", 11 | "components" : { 12 | "red" : "1.000", 13 | "alpha" : "1.000", 14 | "blue" : "0.600", 15 | "green" : "1.000" 16 | } 17 | } 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/Colors/Custom/navy.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | }, 6 | "colors" : [ 7 | { 8 | "idiom" : "universal", 9 | "color" : { 10 | "color-space" : "srgb", 11 | "components" : { 12 | "red" : "0.110", 13 | "alpha" : "1.000", 14 | "blue" : "0.624", 15 | "green" : "0.427" 16 | } 17 | } 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/Colors/Custom/silver.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | }, 6 | "colors" : [ 7 | { 8 | "idiom" : "universal", 9 | "color" : { 10 | "color-space" : "srgb", 11 | "components" : { 12 | "red" : "0.784", 13 | "alpha" : "1.000", 14 | "blue" : "0.784", 15 | "green" : "0.784" 16 | } 17 | } 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/Colors/External/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/Colors/External/facebook.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | }, 6 | "colors" : [ 7 | { 8 | "idiom" : "universal", 9 | "color" : { 10 | "color-space" : "srgb", 11 | "components" : { 12 | "red" : "0.192", 13 | "alpha" : "1.000", 14 | "blue" : "0.588", 15 | "green" : "0.314" 16 | } 17 | } 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/Colors/External/twitter.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | }, 6 | "colors" : [ 7 | { 8 | "idiom" : "universal", 9 | "color" : { 10 | "color-space" : "srgb", 11 | "components" : { 12 | "red" : "0.333", 13 | "alpha" : "1.000", 14 | "blue" : "0.933", 15 | "green" : "0.675" 16 | } 17 | } 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "extent" : "full-screen", 5 | "idiom" : "iphone", 6 | "subtype" : "2436h", 7 | "filename" : "LaunchImageX.png", 8 | "minimum-system-version" : "11.0", 9 | "orientation" : "portrait", 10 | "scale" : "3x" 11 | }, 12 | { 13 | "extent" : "full-screen", 14 | "idiom" : "iphone", 15 | "subtype" : "736h", 16 | "filename" : "Portrait 5.5.png", 17 | "minimum-system-version" : "8.0", 18 | "orientation" : "portrait", 19 | "scale" : "3x" 20 | }, 21 | { 22 | "extent" : "full-screen", 23 | "idiom" : "iphone", 24 | "subtype" : "736h", 25 | "filename" : "Landscape 5.png", 26 | "minimum-system-version" : "8.0", 27 | "orientation" : "landscape", 28 | "scale" : "3x" 29 | }, 30 | { 31 | "extent" : "full-screen", 32 | "idiom" : "iphone", 33 | "subtype" : "667h", 34 | "filename" : "Portrait 4.7.png", 35 | "minimum-system-version" : "8.0", 36 | "orientation" : "portrait", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "orientation" : "portrait", 41 | "idiom" : "iphone", 42 | "filename" : "Portrait 3.5.png", 43 | "extent" : "full-screen", 44 | "minimum-system-version" : "7.0", 45 | "scale" : "2x" 46 | }, 47 | { 48 | "extent" : "full-screen", 49 | "idiom" : "iphone", 50 | "subtype" : "retina4", 51 | "filename" : "Portrait 4.png", 52 | "minimum-system-version" : "7.0", 53 | "orientation" : "portrait", 54 | "scale" : "2x" 55 | } 56 | ], 57 | "info" : { 58 | "version" : 1, 59 | "author" : "xcode" 60 | } 61 | } -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/LaunchImage.launchimage/Landscape 5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/LaunchImage.launchimage/Landscape 5.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/LaunchImage.launchimage/LaunchImageX.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/LaunchImage.launchimage/LaunchImageX.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/LaunchImage.launchimage/Portrait 3.5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/LaunchImage.launchimage/Portrait 3.5.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/LaunchImage.launchimage/Portrait 4.7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/LaunchImage.launchimage/Portrait 4.7.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/LaunchImage.launchimage/Portrait 4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/LaunchImage.launchimage/Portrait 4.png -------------------------------------------------------------------------------- /PyConJP/Assets.xcassets/LaunchImage.launchimage/Portrait 5.5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Assets.xcassets/LaunchImage.launchimage/Portrait 5.5.png -------------------------------------------------------------------------------- /PyConJP/DataStore/DataSource/More/StaffListDataSource.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StaffListDataSource.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 9/10/16. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import APIKit 11 | import Result 12 | 13 | class StaffListDataSource: NSObject { 14 | 15 | let reuseIdentifier = "StaffTableViewCell" 16 | 17 | var teams: [Team] = [] 18 | 19 | let facebookAction: ((_ url: String) -> (() -> Void)) 20 | let twitterAction: ((_ url: String) -> (() -> Void)) 21 | 22 | init(facebookAction: @escaping ((_ url: String) -> (() -> Void)), twitterAction: @escaping ((_ url: String) -> (() -> Void))) { 23 | self.facebookAction = facebookAction 24 | self.twitterAction = twitterAction 25 | } 26 | 27 | func refreshData(completionHandler: @escaping ((Result) -> Void)) { 28 | let request = StaffListAPIRequest() 29 | Session.send(request) { [weak self](result) in 30 | switch result { 31 | case .success(let staffs): 32 | self?.teams.removeAll() 33 | let teamNames = staffs.map({ $0.team }).unique() 34 | for tuple in teamNames.enumerated() { 35 | self?.teams.append(Team(name: teamNames[tuple.offset], staffs: staffs.filter({ $0.team == teamNames[tuple.offset] }))) 36 | } 37 | completionHandler(.success(())) 38 | case .failure(let error): 39 | completionHandler(.failure(error)) 40 | } 41 | } 42 | } 43 | 44 | } 45 | // MARK: - Table View Controller Data Source 46 | 47 | extension StaffListDataSource: UITableViewDataSource { 48 | 49 | func numberOfSections(in tableView: UITableView) -> Int { 50 | return teams.count 51 | } 52 | 53 | func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { 54 | return teams[section].name 55 | } 56 | 57 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 58 | return teams[section].staffs.count 59 | } 60 | 61 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 62 | guard let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath) as? StaffTableViewCell else { 63 | fatalError("Could not create StaffTableViewCell") 64 | } 65 | cell.fill(staff: teams[indexPath.section].staffs[indexPath.row], 66 | onFacebookButton: facebookAction(teams[indexPath.section].staffs[indexPath.row].facebook), 67 | onTwitterButton: twitterAction(teams[indexPath.section].staffs[indexPath.row].twitter)) 68 | return cell 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /PyConJP/DataStore/DataSource/TalkDetail/SpeakersCollectionViewDataSource.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SpeakersCollectionViewDataSource.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 9/8/16. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SpeakersCollectionViewDataSource: NSObject, UICollectionViewDataSource { 12 | 13 | let reuseIdentifier = "SpeakerCollectionViewCell" 14 | 15 | var speakers: [Speaker] = [] 16 | 17 | // MARK: - Collection View DataSource 18 | 19 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 20 | return speakers.count 21 | } 22 | 23 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 24 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! SpeakerCollectionViewCell 25 | cell.fill(speaker: speakers[indexPath.row]) 26 | return cell 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /PyConJP/DataStore/DataSource/Timeline/Bookmark/BookmarkListDataSource.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BookmarkListDataSource.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2016/08/18. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Result 11 | 12 | class BookmarkListDataSource: TimelineDataSource { 13 | 14 | private let loadTalksRequest = LoadFavoriteTalksRequest() 15 | 16 | func refreshData(completionHandler: @escaping ((Result) -> Void)) { 17 | do { 18 | let talks = try loadTalksRequest.load() 19 | timelines.removeAll() 20 | let keys = talks.map { $0.day }.unique() 21 | for tuple in keys.enumerated() { 22 | timelines.append(Timeline(key: keys[tuple.offset], talks: talks.filter { $0.day == keys[tuple.offset]})) 23 | } 24 | completionHandler(.success(())) 25 | } catch let error as NSError { 26 | completionHandler(.failure(error)) 27 | } 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /PyConJP/DataStore/DataSource/Timeline/Conference/ConferenceListDataSource.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ConferenceListDataSource.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2016/06/13. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import APIKit 11 | import Result 12 | 13 | class ConferenceListDataSource: TimelineDataSource { 14 | 15 | private let loadTalksRequest: LoadTalksRequest 16 | 17 | init(day: String?) { 18 | self.loadTalksRequest = LoadTalksRequest(day: day) 19 | super.init() 20 | } 21 | 22 | func getTalksFromAPI(completionHandler: @escaping ((Result) -> Void)) { 23 | let request = TalksAPIRequest() 24 | Session.send(request) { result in 25 | switch result { 26 | case .success(let talks): 27 | try? SaveTalksRequest().save(talks: talks) 28 | completionHandler(.success(())) 29 | case .failure(let error): 30 | completionHandler(.failure(error)) 31 | } 32 | } 33 | } 34 | 35 | func refreshData(completionHandler: @escaping ((Result) -> Void)) { 36 | do { 37 | let talks = try loadTalksRequest.load() 38 | timelines.removeAll() 39 | let keys = talks.map { $0.startTime }.unique() 40 | for tuple in keys.enumerated() { 41 | timelines.append(Timeline(time: keys[tuple.offset], talks: talks.filter { $0.startTime == keys[tuple.offset]})) 42 | } 43 | completionHandler(.success(())) 44 | } catch let error as NSError { 45 | completionHandler(.failure(error)) 46 | } 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /PyConJP/DataStore/DataSource/Timeline/TimelineDataSource.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TimelineDataSource.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 8/19/16. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class TimelineDataSource: NSObject, UITableViewDataSource { 12 | 13 | let reuseIdentifier = "TalkTableViewCell" 14 | 15 | var timelines: [Timeline] = [] 16 | 17 | // MARK: - Table View Data Source 18 | 19 | func numberOfSections(in tableView: UITableView) -> Int { 20 | return timelines.count 21 | } 22 | 23 | func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { 24 | return timelines[section].key 25 | } 26 | 27 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 28 | return timelines[section].talks.count 29 | } 30 | 31 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 32 | guard let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath) as? TalkTableViewCell else { 33 | fatalError("Could not create TalkTableViewCell") 34 | } 35 | cell.fill(talkObject: timelines[indexPath.section].talks[indexPath.row]) 36 | return cell 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /PyConJP/Extension/AppDelegateExtension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegateExtension.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2016/03/15. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension AppDelegate { 12 | 13 | func showAlert(alertController: UIAlertController) { 14 | self.window?.rootViewController?.presentingViewController?.present(alertController, animated: true, completion: nil) 15 | } 16 | 17 | func openTalkDetailViewController(id: Int) { 18 | let talkDetailViewController = TalkDetailViewController.build(id: id) 19 | self.window?.rootViewController?.presentedViewController?.navigationController?.pushViewController(talkDetailViewController, animated: true) 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /PyConJP/Extension/ArrayExtension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ArrayExtension.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2016/07/22. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension Array where Element: Hashable { 12 | 13 | func unique() -> [Element] { 14 | var r = [Element]() 15 | for i in self { 16 | r += !r.contains(i) ? [i] : [] 17 | } 18 | return r 19 | } 20 | 21 | mutating func uniqueInPlace() { 22 | self = self.unique() 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /PyConJP/Extension/DateExtension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DateExtension.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 7/18/16. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension Date { 12 | 13 | static func date(from string: String) -> Date? { 14 | let dateFormatter = DateFormatter() 15 | dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" 16 | return dateFormatter.date(from: string) 17 | } 18 | 19 | var components: DateComponents { 20 | let calendar = Calendar(identifier: Calendar.Identifier.gregorian) 21 | return calendar.dateComponents([.year, .month, .day, .weekday, .hour, .minute], from: self) 22 | } 23 | 24 | var hourClock: String? { 25 | let dateFormatter = DateFormatter() 26 | dateFormatter.dateFormat = "h\na" 27 | return dateFormatter.string(from: self) 28 | } 29 | 30 | func convertToTime() -> String { 31 | let components = self.components 32 | return String(format: "%02d", components.hour!) + ":" + String(format: "%02d", components.minute!) 33 | } 34 | 35 | func calculate(year: Int = 0, month: Int = 0, day: Int = 0, hour: Int = 0, minute: Int = 0, second: Int = 0) -> Date? { 36 | 37 | var components = self.components 38 | components.year = (components.year ?? 0) + year 39 | components.month = (components.month ?? 0) + month 40 | components.day = (components.day ?? 0) + day 41 | components.hour = (components.hour ?? 0) + hour 42 | components.minute = (components.minute ?? 0) + minute 43 | components.second = (components.second ?? 0) + second 44 | 45 | let calendar = Calendar(identifier: Calendar.Identifier.gregorian) 46 | return calendar.date(from: components) 47 | 48 | } 49 | 50 | func update(year: Int? = nil, month: Int? = nil, day: Int? = nil, hour: Int? = nil, minute: Int? = nil, second: Int? = nil) -> Date? { 51 | 52 | var components = self.components 53 | components.year = year ?? components.year 54 | components.month = month ?? components.month 55 | components.day = day ?? components.day 56 | components.hour = hour ?? components.hour 57 | components.minute = minute ?? components.minute 58 | components.second = second ?? components.second 59 | 60 | let calendar = Calendar(identifier: Calendar.Identifier.gregorian) 61 | return calendar.date(from: components) 62 | 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /PyConJP/Extension/StringExtension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StringExtension.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2016/07/22. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension String { 12 | 13 | static private let dateFormatterInstance: DateFormatter = { 14 | let dateFormatter = DateFormatter() 15 | dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" 16 | return dateFormatter 17 | }() 18 | 19 | func convertToDate() -> Date? { 20 | return String.dateFormatterInstance.date(from: self) 21 | } 22 | 23 | func timeStringByTrimmingSecond() -> String { 24 | let dateString = "2000-01-01 " + self 25 | guard let date = Date.date(from: dateString) else { return self } 26 | return date.convertToTime() 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /PyConJP/Extension/UIColorExtension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIColorExtension.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 4/23/16. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UIColor { 12 | 13 | static func hex(string: NSString, alpha: CGFloat) -> UIColor { 14 | let hex = string.replacingOccurrences(of: "#", with: "") 15 | let scanner = Scanner(string: hex) 16 | var color: UInt32 = 0 17 | if scanner.scanHexInt32(&color) { 18 | let r = CGFloat((color & 0xFF0000) >> 16) / 255.0 19 | let g = CGFloat((color & 0x00FF00) >> 8) / 255.0 20 | let b = CGFloat(color & 0x0000FF) / 255.0 21 | return UIColor(red: r, green: g, blue: b, alpha: alpha) 22 | } else { 23 | print("invalid hex string") 24 | return UIColor.white 25 | } 26 | } 27 | 28 | } 29 | 30 | extension UIColor { 31 | 32 | static let navy: UIColor = UIColor(named: "navy")! 33 | 34 | static let goldenrod: UIColor = UIColor(named: "goldenrod")! 35 | 36 | static let crimson: UIColor = UIColor(named: "crimson")! 37 | 38 | static let lightYellow: UIColor = UIColor(named: "lightYellow")! 39 | 40 | static let silver: UIColor = UIColor(named: "silver")! 41 | 42 | static let davyGray: UIColor = UIColor(named: "davyGray")! 43 | 44 | static let twitter: UIColor = UIColor(named: "twitter")! 45 | 46 | static let facebook: UIColor = UIColor(named: "facebook")! 47 | 48 | } 49 | -------------------------------------------------------------------------------- /PyConJP/Extension/UIDeviceExtension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIDeviceExtension.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 9/20/16. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UIDevice { 12 | 13 | var modelType: String { 14 | var systemInfo = utsname() 15 | uname(&systemInfo) 16 | let machineMirror = Mirror(reflecting: systemInfo.machine) 17 | 18 | return machineMirror.children.reduce("") { identifier, element in 19 | guard let value = element.value as? Int8, value != 0 else { return identifier } 20 | return identifier + String(UnicodeScalar(UInt8(value))) 21 | } 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /PyConJP/Extension/UIStoryboardExtension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIStoryboardExtension.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2017/06/01. 6 | // Copyright © 2017 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UIStoryboard { 12 | 13 | convenience init(storyboard: Storyboard, bundle: Bundle? = nil) { 14 | self.init(name: storyboard.description, bundle: bundle) 15 | } 16 | 17 | func instantiateViewController() -> T where T: StoryboardIdentifiable { 18 | return self.instantiateViewController(withIdentifier: T.storyboardIdentifier) as! T 19 | } 20 | 21 | enum Storyboard: CustomStringConvertible { 22 | case main 23 | case launch 24 | case events 25 | case conference 26 | case bookmark 27 | case more 28 | 29 | var description: String { 30 | switch self { 31 | case .main: return "Main" 32 | case .launch: return "Launch" 33 | case .events: return "Events" 34 | case .conference: return "Conference" 35 | case .bookmark: return "Bookmark" 36 | case .more: return "More" 37 | } 38 | } 39 | 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /PyConJP/Extension/UIViewExtension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewExtension.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2016/08/02. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UIViewController { 12 | 13 | @objc func topMostViewController() -> UIViewController { 14 | if let presentedViewController = self.presentedViewController { 15 | return presentedViewController.topMostViewController() 16 | } else { 17 | for view in self.view.subviews { 18 | if let subViewController = view.next { 19 | if subViewController is UIViewController { 20 | let viewController = subViewController as! UIViewController 21 | return viewController.topMostViewController() 22 | } 23 | } 24 | } 25 | return self 26 | } 27 | } 28 | 29 | } 30 | 31 | extension UITabBarController { 32 | 33 | override func topMostViewController() -> UIViewController { 34 | return self.selectedViewController!.topMostViewController() 35 | } 36 | 37 | } 38 | 39 | extension UINavigationController { 40 | 41 | override func topMostViewController() -> UIViewController { 42 | return self.visibleViewController!.topMostViewController() 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /PyConJP/Model/APIRequest/GitHub/StaffListAPIRequest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StaffListAPIRequest.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2017/06/12. 6 | // Copyright © 2017 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import APIKit 11 | import WebAPIFramework 12 | 13 | struct StaffListAPIRequest: GitHubRequest { 14 | 15 | var method: HTTPMethod { 16 | return .get 17 | } 18 | 19 | var path: String { 20 | return "stafflist.json" 21 | } 22 | 23 | func response(from object: Any, urlResponse: HTTPURLResponse) throws -> [Staff] { 24 | guard let dictionary = object as? [String: Any], 25 | let staffList = dictionary["staffList"] as? [Any] else { 26 | throw ResponseError.unexpectedObject(object) 27 | } 28 | return staffList.flatMap({ Staff(object: $0) }) 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /PyConJP/Model/APIRequest/GitHub/SurveyURLAPIRequest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SurveyURLAPIRequest.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2017/09/05. 6 | // Copyright © 2017 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import APIKit 11 | import WebAPIFramework 12 | 13 | struct SurveyURLAPIRequest: GitHubRequest { 14 | 15 | var method: HTTPMethod { 16 | return .get 17 | } 18 | 19 | var path: String { 20 | return "surveyURL.json" 21 | } 22 | 23 | func response(from object: Any, urlResponse: HTTPURLResponse) throws -> URL { 24 | guard let dictionary = object as? [String: Any], 25 | let urlString = dictionary["url"] as? String, 26 | let url = URL(string: urlString) else { 27 | throw ResponseError.unexpectedObject(object) 28 | } 29 | return url 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /PyConJP/Model/APIRequest/PyConJP/TalkDetailAPIRequest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TalkDetailAPIRequest.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2017/06/12. 6 | // Copyright © 2017 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import APIKit 11 | import WebAPIFramework 12 | 13 | struct TalkDetailAPIRequest: PyConJPRequest { 14 | 15 | let id: Int 16 | 17 | var method: HTTPMethod { 18 | return .get 19 | } 20 | 21 | var path: String { 22 | return "presentation/\(id)/" 23 | } 24 | 25 | init(id: Int) { 26 | self.id = id 27 | } 28 | 29 | func response(from object: Any, urlResponse: HTTPURLResponse) throws -> TalkDetail { 30 | guard let talkDetail = TalkDetail(object: object) else { 31 | throw ResponseError.unexpectedObject(object) 32 | } 33 | return talkDetail 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /PyConJP/Model/APIRequest/PyConJP/TalksAPIRequest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TalksAPIRequest.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2017/06/12. 6 | // Copyright © 2017 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import APIKit 11 | import Result 12 | import RealmSwift 13 | import WebAPIFramework 14 | 15 | struct TalksAPIRequest: PyConJPRequest { 16 | 17 | var method: HTTPMethod { 18 | return .get 19 | } 20 | 21 | var path: String { 22 | return "talks/list/" 23 | } 24 | 25 | func response(from object: Any, urlResponse: HTTPURLResponse) throws -> [TalkObject] { 26 | guard let dictionary = object as? [String: Any], 27 | let presentations = dictionary["presentations"] as? [Any] else { 28 | throw ResponseError.unexpectedObject(object) 29 | } 30 | return presentations.flatMap({ TalkObject(object: $0) }) 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /PyConJP/Model/Enum/Error/RealmError.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RealmError.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2017/06/01. 6 | // Copyright © 2017 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | enum RealmError: Error { 12 | case failureLoad 13 | case failureSave 14 | } 15 | -------------------------------------------------------------------------------- /PyConJP/Model/Enum/Language.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Language.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 7/11/16. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | enum Language: CustomStringConvertible { 12 | case en 13 | case ja 14 | 15 | var description: String { 16 | switch self { 17 | case .en: 18 | return "en" 19 | case .ja: 20 | return "ja" 21 | } 22 | } 23 | 24 | var localized: String { 25 | switch self { 26 | case .en: 27 | return NSLocalizedString("english", tableName: "Language", comment: "") 28 | case .ja: 29 | return NSLocalizedString("japanese", tableName: "Language", comment: "") 30 | 31 | } 32 | } 33 | 34 | init?(_ string: String) { 35 | switch string { 36 | case Language.en.description: 37 | self = .en 38 | case Language.ja.description: 39 | self = .ja 40 | default: 41 | return nil 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /PyConJP/Model/Enum/NotificationType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NotificationType.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2017/06/15. 6 | // Copyright © 2017 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | enum NotificationType: CustomStringConvertible { 12 | case information 13 | case talk 14 | 15 | var description: String { 16 | switch self { 17 | case .information: 18 | return "information" 19 | case .talk: 20 | return "talk" 21 | } 22 | } 23 | 24 | init?(_ stting: String) { 25 | switch stting { 26 | case NotificationType.information.description: 27 | self = .information 28 | case NotificationType.talk.description: 29 | self = .talk 30 | default: 31 | return nil 32 | } 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /PyConJP/Model/Enum/PyConJPDate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PyConJPDate.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2016/08/04. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | enum PyConJPDate: CustomStringConvertible { 12 | case tutorials 13 | case confarence1 14 | case confarence2 15 | case sprints 16 | 17 | var description: String { 18 | switch self { 19 | case .tutorials: return "2017-09-07" 20 | case .confarence1: return "2017-09-08" 21 | case .confarence2: return "2017-09-09" 22 | case .sprints: return "2017-09-10" 23 | } 24 | } 25 | 26 | static func confarenceDate() -> [PyConJPDate] { 27 | return [confarence1, confarence2] 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /PyConJP/Model/Enum/Room.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Room.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 8/7/16. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | enum Room: CustomStringConvertible { 12 | case room201 13 | case room202 14 | case room203 15 | 16 | static var rooms: [Room] { 17 | return [.room201, .room202, .room203] 18 | } 19 | 20 | var description: String { 21 | switch self { 22 | case .room201: return "Room 201" 23 | case .room202: return "Room 202" 24 | case .room203: return "Room 203" 25 | } 26 | } 27 | 28 | var number: Int { 29 | switch self { 30 | case .room201: return 201 31 | case .room202: return 202 32 | case .room203: return 203 33 | } 34 | } 35 | 36 | var color: UIColor { 37 | switch self { 38 | case .room201: return UIColor.navy 39 | case .room202: return UIColor.goldenrod 40 | case .room203: return UIColor.crimson 41 | } 42 | } 43 | 44 | var hashTag: String { 45 | switch self { 46 | case .room201: return "#pyconjp_201" 47 | case .room202: return "#pyconjp_202" 48 | case .room203: return "#pyconjp_203" 49 | } 50 | } 51 | 52 | init?(_ string: String) { 53 | switch string { 54 | case Room.room201.description: self = .room201 55 | case Room.room202.description: self = .room202 56 | case Room.room203.description: self = .room203 57 | default: return nil 58 | } 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /PyConJP/Model/Realm/LoadFavoriteTalksRequest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LoadFavoriteTalksRequest.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2017/06/16. 6 | // Copyright © 2017 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import RealmSwift 11 | 12 | struct LoadFavoriteTalksRequest: RealmLoadTalksProtocol { 13 | 14 | let filterPredicate = NSPredicate(format: "isFavorite == %@", true as CVarArg) 15 | let sortProperties = [SortDescriptor(keyPath: "startDate", ascending: true), 16 | SortDescriptor(keyPath: "roomString", ascending: true)] 17 | 18 | } 19 | -------------------------------------------------------------------------------- /PyConJP/Model/Realm/LoadTalksRequest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LoadTalksRequest.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2017/06/16. 6 | // Copyright © 2017 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import RealmSwift 11 | 12 | struct LoadTalksRequest: RealmLoadTalksProtocol { 13 | 14 | let filterPredicate: NSPredicate 15 | let sortProperties = [SortDescriptor(keyPath: "startDate", ascending: true), 16 | SortDescriptor(keyPath: "roomString", ascending: true)] 17 | 18 | init(day: String?) { 19 | self.filterPredicate = NSPredicate(format: "day == %@", day ?? "") 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /PyConJP/Model/Realm/SaveTalksRequest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SaveTalksRequest.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2017/06/16. 6 | // Copyright © 2017 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Result 11 | import RealmSwift 12 | 13 | struct SaveTalksRequest: RealmSaveTalksProtocol {} 14 | -------------------------------------------------------------------------------- /PyConJP/Model/Struct/Category.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Category.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2016/04/27. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Category { 12 | 13 | let id: Int 14 | let name: String 15 | 16 | } 17 | 18 | extension Category { 19 | 20 | init(dictionary: [String: Any]) { 21 | id = dictionary["id"] as? Int ?? 0 22 | name = dictionary["name"] as? String ?? "" 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /PyConJP/Model/Struct/Level.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Level.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2016/02/22. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Level { 12 | 13 | let id: Int 14 | let name: String 15 | 16 | } 17 | 18 | extension Level { 19 | 20 | init(dictionary: [String: Any]) { 21 | id = dictionary["id"] as? Int ?? 0 22 | name = dictionary["name"] as? String ?? "" 23 | } 24 | 25 | init?(dictionary: [String: Any]?) { 26 | guard let dictionary = dictionary else { return nil } 27 | id = dictionary["id"] as? Int ?? 0 28 | name = dictionary["name"] as? String ?? "" 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /PyConJP/Model/Struct/Place.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Place.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2016/02/22. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Place { 12 | 13 | let id: Int 14 | let name: String 15 | 16 | } 17 | 18 | extension Place { 19 | 20 | init(dictionary: [String: Any]) { 21 | id = dictionary["id"] as? Int ?? 0 22 | name = dictionary["name"] as? String ?? "" 23 | } 24 | 25 | init?(dictionary: [String: Any]?) { 26 | guard let dictionary = dictionary else { return nil } 27 | id = dictionary["id"] as? Int ?? 0 28 | name = dictionary["name"] as? String ?? "" 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /PyConJP/Model/Struct/Speaker.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Speaker.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2016/02/22. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Speaker { 12 | 13 | let name: String 14 | let imageURL: String? 15 | let twitterAccount: String? 16 | 17 | } 18 | 19 | extension Speaker { 20 | 21 | init(dictionary: [String: Any]) { 22 | name = dictionary["name"] as? String ?? "" 23 | imageURL = dictionary["image_uri"] as? String 24 | twitterAccount = dictionary["twitter"] as? String 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /PyConJP/Model/Struct/Staff.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Staff.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 9/10/16. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Staff { 12 | 13 | let team: String 14 | let name: String 15 | let role: String 16 | let twitter: String 17 | let facebook: String 18 | 19 | } 20 | 21 | extension Staff { 22 | 23 | init?(dictionary: [String: Any]) { 24 | guard let team = dictionary["team"] as? String, 25 | let name = dictionary["name"] as? String, 26 | let role = dictionary["title"] as? String else { 27 | return nil 28 | } 29 | self.init(team: team, 30 | name: name, 31 | role: role, 32 | twitter: dictionary["twitter"] as? String ?? "", 33 | facebook: dictionary["facebook"] as? String ?? "") 34 | } 35 | 36 | init?(object: Any) { 37 | guard let dictionary = object as? [String: Any] else { return nil } 38 | self.init(dictionary: dictionary) 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /PyConJP/Model/Struct/Talk.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Talk.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 7/11/16. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Talk { 12 | 13 | let id: Int 14 | let title: String 15 | let description: String 16 | let speakers: [String] 17 | let startDate: Date 18 | let endDate: Date 19 | let day: String 20 | let startTime: String 21 | let endTime: String 22 | let category: String 23 | let room: Room 24 | let language: Language 25 | 26 | } 27 | 28 | extension Talk { 29 | 30 | init?(dictionary: [String: Any]) { 31 | guard let id = dictionary["id"] as? Int, 32 | let title = dictionary["title"] as? String, 33 | let description = dictionary["description"] as? String, 34 | let speakers = dictionary["speakers"] as? [String], 35 | let day = dictionary["day"] as? String, 36 | let startTime = dictionary["start"] as? String, 37 | let startDate = Date.date(from: day + " " + startTime), 38 | let endTime = dictionary["end"] as? String, 39 | let endDate = Date.date(from: day + " " + endTime), 40 | let category = dictionary["category"] as? String, 41 | let room = Room(dictionary["rooms"] as? String ?? ""), 42 | let language = Language(dictionary["language"] as? String ?? "") else { return nil } 43 | 44 | self.init(id: id, 45 | title: title, 46 | description: description, 47 | speakers: speakers, 48 | startDate: startDate, 49 | endDate: endDate, 50 | day: day, 51 | startTime: startTime, 52 | endTime: endTime, 53 | category: category, 54 | room: room, 55 | language: language) 56 | } 57 | 58 | init?(_ talkObject: TalkObject) { 59 | guard let room = talkObject.room, 60 | let language = talkObject.language else { return nil } 61 | self.init(id: talkObject.id, 62 | title: talkObject.title, 63 | description: talkObject.descriptionText, 64 | speakers: talkObject.speakers.components(separatedBy: ", "), 65 | startDate: talkObject.startDate, 66 | endDate: talkObject.endDate, 67 | day: talkObject.day, 68 | startTime: talkObject.startTime, 69 | endTime: talkObject.endTime, 70 | category: talkObject.category, 71 | room: room, 72 | language: language) 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /PyConJP/Model/Struct/TalkDetail.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TalkDetail.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2016/02/22. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct TalkDetail { 12 | 13 | var talkObject: TalkObject 14 | let speakers: [Speaker] 15 | let abstract: String 16 | let level: String 17 | 18 | } 19 | 20 | extension TalkDetail { 21 | 22 | init?(dictionary: [String: Any]) { 23 | guard let talkObject = TalkObject(dictionary: dictionary), 24 | let abstract = dictionary["abstract"] as? String, 25 | let level = dictionary["level"] as? String else { return nil } 26 | self.init(talkObject: talkObject, 27 | speakers: (dictionary["speaker_infomations"] as? [[String: Any]] ?? []).map({ Speaker(dictionary: $0) }), 28 | abstract: abstract, 29 | level: level) 30 | } 31 | 32 | init?(object: Any) { 33 | guard let dictionary = object as? [String: Any] else { return nil} 34 | self.init(dictionary: dictionary) 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /PyConJP/Model/Struct/Team.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Team.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 9/10/16. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Team { 12 | 13 | let name: String 14 | var staffs: [Staff] 15 | 16 | } 17 | 18 | extension Team { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /PyConJP/Model/Struct/Timeline.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Timeline.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2016/07/21. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Timeline { 12 | 13 | let key: String 14 | var talks: [TalkObject] 15 | 16 | } 17 | 18 | extension Timeline { 19 | 20 | init(time: String, talks: [TalkObject]) { 21 | self.key = time.timeStringByTrimmingSecond() 22 | self.talks = talks 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /PyConJP/Model/Struct/Timetable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Timetable.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2017/06/01. 6 | // Copyright © 2017 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Timetable { 12 | 13 | let tracks: [Track] 14 | 15 | var rooms: [Room] { 16 | return tracks.map({ $0.room }) 17 | } 18 | 19 | var start: Date? { 20 | return tracks.flatMap({ $0.start }).min() 21 | } 22 | 23 | var end: Date? { 24 | return tracks.flatMap({ $0.end }).max() 25 | } 26 | 27 | var duration: Double? { 28 | guard let start = start, 29 | let end = end else { return nil } 30 | return end.timeIntervalSince(start) 31 | } 32 | 33 | var minutesDuration: Int { 34 | return Int((duration ?? 0) / 60) 35 | } 36 | 37 | var hours: Int { 38 | return minutesDuration / 60 39 | } 40 | 41 | var hourDuration: [Int] { 42 | guard let startHourClock = start?.components.hour, 43 | let endHourClock = end?.components.hour else { return [] } 44 | return Array(startHourClock...endHourClock) 45 | } 46 | 47 | init(talks: [TalkObject]) { 48 | self.tracks = Room.rooms.map { room -> Track in 49 | Track(room: room, talks: talks.filter({ $0.room == room })) 50 | } 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /PyConJP/Model/Struct/Track.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Track.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2017/06/01. 6 | // Copyright © 2017 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Track { 12 | 13 | let room: Room 14 | let talks: [TalkObject] 15 | 16 | var start: Date? { 17 | return talks.flatMap({ $0.startDate }).min() 18 | } 19 | 20 | var end: Date? { 21 | return talks.flatMap({ $0.endDate }).max() 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /PyConJP/Protocol/DummyJSON/DummyTalkDetailProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DummyTalkDetailProtocol.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2016/12/18. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Result 11 | 12 | protocol DummyTalkDetailProtocol { 13 | 14 | func getTalksFromLocalDummyJSON(completionHandler: ((Result) -> Void)) 15 | 16 | } 17 | 18 | extension DummyTalkDetailProtocol { 19 | 20 | func getTalkDetailFromLocalDummyJSON(completionHandler: ((Result) -> Void)) { 21 | let path = Bundle.main.path(forResource: "DummyTalkDetail", ofType: "json") 22 | let fileHandle = FileHandle(forReadingAtPath: path!) 23 | let data = fileHandle?.readDataToEndOfFile() 24 | 25 | do { 26 | let dictionary = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! [String: Any] 27 | 28 | let talkDetail = TalkDetail(dictionary: dictionary)! 29 | completionHandler(.success(talkDetail)) 30 | } catch let error as NSError { 31 | completionHandler(.failure(error)) 32 | } 33 | 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /PyConJP/Protocol/DummyJSON/DummyTalksProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DummyTalksProtocol.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2017/06/14. 6 | // Copyright © 2017 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Result 11 | 12 | protocol DummyTalksProtocol { 13 | 14 | func getTalksFromLocalDummyJSON(completionHandler: ((Result<[TalkObject], NSError>) -> Void)) 15 | 16 | } 17 | 18 | extension DummyTalksProtocol { 19 | 20 | func getTalksFromLocalDummyJSON(completionHandler: ((Result<[TalkObject], NSError>) -> Void)) { 21 | let path = Bundle.main.path(forResource: "DummyTalks", ofType: "json") 22 | let fileHandle = FileHandle(forReadingAtPath: path!) 23 | let data = fileHandle?.readDataToEndOfFile() 24 | let dictionary = try! JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! [String: Any] 25 | let presentations = dictionary["presentations"] as? [[String: Any]] ?? [[String: Any]]() 26 | 27 | completionHandler(.success(presentations.flatMap({ TalkObject(object: $0) }))) 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /PyConJP/Protocol/ErrorAlertProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ErrorAlertProtocol.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 4/23/16. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | protocol ErrorAlertProtocol { 12 | func showErrorAlart(with error: Error, parent viewController: UIViewController?) 13 | } 14 | 15 | extension ErrorAlertProtocol { 16 | 17 | func showErrorAlart(with error: Error, parent viewController: UIViewController? = nil) { 18 | 19 | let rootViewController = viewController != nil ? viewController! : UIApplication.shared.keyWindow!.rootViewController! 20 | 21 | let alert = UIAlertController(title: "", message: error.localizedDescription, preferredStyle: .alert) 22 | alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil)) 23 | rootViewController.present(alert, animated: true, completion: nil) 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /PyConJP/Protocol/GestureProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GestureProtocol.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 9/13/16. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | protocol GestureProtocol { 12 | func handle(gesture: UIGestureRecognizer) 13 | func singleTap(gesture: UITapGestureRecognizer) 14 | func doubleTap(gesture: UITapGestureRecognizer) 15 | func pinch(gesture: UIPinchGestureRecognizer) 16 | func pan(gesture: UIPanGestureRecognizer) 17 | func longPress(gesture: UILongPressGestureRecognizer) 18 | } 19 | 20 | extension GestureProtocol { 21 | 22 | func handle(gesture: UIGestureRecognizer) { 23 | if let singleTapGesture = gesture as? UITapGestureRecognizer, singleTapGesture.numberOfTapsRequired == 1 { 24 | singleTap(gesture: singleTapGesture) 25 | } else if let doubleTapGesture = gesture as? UITapGestureRecognizer, doubleTapGesture.numberOfTapsRequired == 2 { 26 | doubleTap(gesture: doubleTapGesture) 27 | } else if let pinchGesture = gesture as? UIPinchGestureRecognizer { 28 | pinch(gesture: pinchGesture) 29 | } else if let panGesture = gesture as? UIPanGestureRecognizer { 30 | pan(gesture: panGesture) 31 | } else if let longPressGesture = gesture as? UILongPressGestureRecognizer { 32 | longPress(gesture: longPressGesture) 33 | } 34 | } 35 | 36 | func singleTap(gesture: UITapGestureRecognizer) {} 37 | 38 | func doubleTap(gesture: UITapGestureRecognizer) {} 39 | 40 | func pinch(gesture: UIPinchGestureRecognizer) {} 41 | 42 | func pan(gesture: UIPanGestureRecognizer) {} 43 | 44 | func longPress(gesture: UILongPressGestureRecognizer) {} 45 | 46 | } 47 | -------------------------------------------------------------------------------- /PyConJP/Protocol/Realm/RealmLoadTalksProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RealmLoadTalksProtocol.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2016/08/18. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import RealmSwift 11 | 12 | protocol RealmLoadTalksProtocol { 13 | var filterPredicate: NSPredicate { get } 14 | var sortProperties: [SortDescriptor] { get } 15 | 16 | func load() throws -> [TalkObject] 17 | } 18 | 19 | extension RealmLoadTalksProtocol { 20 | 21 | func load() throws -> [TalkObject] { 22 | do { 23 | let realm = try Realm() 24 | return Array(realm.objects(TalkObject.self).filter(filterPredicate).sorted(by: sortProperties)) 25 | } catch { 26 | throw error 27 | } 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /PyConJP/Protocol/Realm/RealmSaveTalksProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RealmSaveTalksProtocol.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2017/06/13. 6 | // Copyright © 2017 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import RealmSwift 11 | 12 | protocol RealmSaveTalksProtocol { 13 | 14 | func save(talks: [TalkObject]) throws 15 | 16 | } 17 | 18 | extension RealmSaveTalksProtocol { 19 | 20 | func save(talks: [TalkObject]) throws { 21 | do { 22 | let realm = try Realm() 23 | let rejectedTalks = realm.objects(TalkObject.self).filter("NOT(id IN %@)", talks.map({ $0.id })) 24 | try realm.write({ 25 | realm.delete(rejectedTalks) 26 | realm.add(talks, update: true) 27 | }) 28 | } catch { 29 | throw error 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /PyConJP/Protocol/UI/NibInstantitable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NibInstantitable.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2017/06/01. 6 | // Copyright © 2017 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | protocol NibInstantitable {} 12 | 13 | extension NibInstantitable { 14 | 15 | static var nibName: String { 16 | return String(describing: Self.self) 17 | } 18 | 19 | static var nib: UINib { 20 | return UINib(nibName: Self.nibName, bundle: nil) 21 | } 22 | 23 | static func instantiateFromNib() -> Self { 24 | return nib.instantiate(withOwner: self, options: nil)[0] as! Self 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /PyConJP/Protocol/UI/StoryboardIdentifiable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StoryboardIdentifiable.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2017/06/01. 6 | // Copyright © 2017 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol StoryboardIdentifiable {} 12 | 13 | extension StoryboardIdentifiable { 14 | 15 | static var storyboardIdentifier: String { 16 | return String(describing: Self.self) 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /PyConJP/Protocol/URLScheme/MailURLSchemeProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MailURLSchemeProtocol.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 9/17/16. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | protocol MailURLSchemeProtocol { 12 | 13 | func mailURLScheme(to address: String, subject: String, body: String) -> URL? 14 | func openMail(to address: String, subject: String, body: String) 15 | 16 | } 17 | 18 | extension MailURLSchemeProtocol { 19 | 20 | private var urlScheme: URL { 21 | return URL(string: "mailto://")! 22 | } 23 | 24 | func mailURLScheme(to address: String, subject: String, body: String) -> URL? { 25 | guard UIApplication.shared.canOpenURL(urlScheme) else { return nil } 26 | return URL(string: String(format: "mailto:%@?subject=%@&body=%@", arguments: [address, subject.addingPercentEncoding(withAllowedCharacters: CharacterSet.alphanumerics)!, body.addingPercentEncoding(withAllowedCharacters: CharacterSet.alphanumerics)!])) 27 | } 28 | 29 | func openMail(to address: String, subject: String, body: String) { 30 | guard let url = mailURLScheme(to: address, subject: subject, body: body) else { return } 31 | UIApplication.shared.open(url, options: [:], completionHandler: nil) 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /PyConJP/Resource/DummyTalkDetail.json: -------------------------------------------------------------------------------- 1 | { 2 | "category": "Documentation", 3 | "speakers": [ 4 | "hashimoto" 5 | ], 6 | "end": "10:30:00", 7 | "description": "description test 1", 8 | "language": "ja", 9 | "title": "test 1", 10 | "day": "2016-09-21", 11 | "start": "10:00:00", 12 | "rooms": "Tutorials 1", 13 | "id": 1, 14 | "level": "Level 1", 15 | "abstract": "\u307b\u3052\u307b\u3052" 16 | } -------------------------------------------------------------------------------- /PyConJP/Resource/Localizable/Base.lproj/EventList.strings: -------------------------------------------------------------------------------- 1 | /* 2 | EventList.strings 3 | PyConJP 4 | 5 | Created by Yutaro Muta on 2017/08/28. 6 | Copyright © 2017 PyCon JP. All rights reserved. 7 | */ 8 | 9 | /** 10 | EventsListViewController Section Row 11 | */ 12 | 13 | "tutorials" = "Tutorials"; 14 | "keynote" = "Keynote"; 15 | "posters" = "Posters"; 16 | "lightningTalks" = "Lightning Talks (LT)"; 17 | "youthCoderWorkshop" = "Youth Coder Workshop"; 18 | "committeeMeeting" = "Committee Meeting"; 19 | "communityBooth" = "Community Booth"; 20 | "jobFair" = "Job Fair"; 21 | "openSpace" = "Open Space"; 22 | "mediaMeeting" = "Media Meeting"; 23 | "sprints" = "Sprints"; 24 | -------------------------------------------------------------------------------- /PyConJP/Resource/Localizable/Base.lproj/Language.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Language.strings 3 | PyConJP 4 | 5 | Created by Yutaro Muta on 8/31/16. 6 | Copyright © 2016 PyCon JP. All rights reserved. 7 | */ 8 | 9 | "english" = "English"; 10 | 11 | "japanese" = "Japanese"; 12 | -------------------------------------------------------------------------------- /PyConJP/Resource/Localizable/Base.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localizable.strings 3 | PyConJP 4 | 5 | Created by Yutaro Muta on 9/17/16. 6 | Copyright © 2016 PyCon JP. All rights reserved. 7 | */ 8 | 9 | /** 10 | AlertController 11 | */ 12 | 13 | "cancel" = "Cancel"; 14 | 15 | "open" = "Open"; 16 | -------------------------------------------------------------------------------- /PyConJP/Resource/Localizable/Base.lproj/Map.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Map.strings 3 | PyConJP 4 | 5 | Created by Yutaro Muta on 8/30/2016. 6 | Copyright © 2016 PyCon JP. All rights reserved. 7 | */ 8 | 9 | /** 10 | MapViewController 11 | */ 12 | 13 | "nameWaseda" = "Waseda University, Nishi-Waseda Campus"; 14 | 15 | "addressWaseda" = "Waseda University, Nishi-Waseda Campus, Building 63\n3-4-1, Okubo, Shinjuku, Tokyo\n169-0072, Japan"; 16 | 17 | "nameMicrosoft" = "Microsoft Japan Co., Ltd."; 18 | 19 | "addressMicrosoft" = "Microsoft Japan Co., Ltd.\nShinagawa Grand Central Tower, 2-16-3 Konan, Minato, Tokyo\n108-0075, Japan"; 20 | -------------------------------------------------------------------------------- /PyConJP/Resource/Localizable/Base.lproj/MoreList.strings: -------------------------------------------------------------------------------- 1 | /* 2 | MoreList.strings 3 | PyConJP 4 | 5 | Created by Yutaro Muta on 2017/09/07. 6 | Copyright © 2017 PyCon JP. All rights reserved. 7 | */ 8 | 9 | /** 10 | MoreListViewController 11 | */ 12 | 13 | "participantsInformation" = "Participants Information"; 14 | "whatsPyConJP" = "What is PyCon JP?"; 15 | "codeOfConduct" = "Code of Conduct"; 16 | "summary" = "Summary"; 17 | "sponsor" = "Sponsor"; 18 | "staffList" = "Staff List"; 19 | "survey" = "Survey"; 20 | 21 | "venue" = "Venue Information"; 22 | "conferenceMap" = "Tutorials・Conference"; 23 | "sprintMap" = "Sprints"; 24 | 25 | "application" = "About Application"; 26 | "repository" = "Repository"; 27 | "license" = "The MIT License (MIT)"; 28 | "feedback" = "Feedback (Open Mail)"; 29 | -------------------------------------------------------------------------------- /PyConJP/Resource/Localizable/Base.lproj/URLScheme.strings: -------------------------------------------------------------------------------- 1 | /* 2 | URLScheme.strings 3 | PyConJP 4 | 5 | Created by Yutaro Muta on 9/17/16. 6 | Copyright © 2016 PyCon JP. All rights reserved. 7 | */ 8 | 9 | /** 10 | TwitterURLSchemeType 11 | */ 12 | 13 | "twitterAlertTitle" = "Launch Twitter App"; 14 | 15 | "twitterAlertMessage" = "Try to open %@"; 16 | -------------------------------------------------------------------------------- /PyConJP/Resource/Localizable/en.lproj/EventList.strings: -------------------------------------------------------------------------------- 1 | /* 2 | EventList.strings 3 | PyConJP 4 | 5 | Created by Yutaro Muta on 2017/08/28. 6 | Copyright © 2017 PyCon JP. All rights reserved. 7 | */ 8 | 9 | /** 10 | EventsListViewController Section Row 11 | */ 12 | 13 | "tutorials" = "Tutorials"; 14 | "keynote" = "Keynote"; 15 | "posters" = "Posters"; 16 | "lightningTalks" = "Lightning Talks (LT)"; 17 | "youthCoderWorkshop" = "Youth Coder Workshop"; 18 | "committeeMeeting" = "Committee Meeting"; 19 | "communityBooth" = "Community Booth"; 20 | "jobFair" = "Job Fair"; 21 | "openSpace" = "Open Space"; 22 | "mediaMeeting" = "Media Meeting"; 23 | "sprints" = "Sprints"; 24 | -------------------------------------------------------------------------------- /PyConJP/Resource/Localizable/en.lproj/Language.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Language.strings 3 | PyConJP 4 | 5 | Created by Yutaro Muta on 8/31/16. 6 | Copyright © 2016 PyCon JP. All rights reserved. 7 | */ 8 | 9 | "english" = "English"; 10 | 11 | "japanese" = "Japanese"; 12 | -------------------------------------------------------------------------------- /PyConJP/Resource/Localizable/en.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localizable.strings 3 | PyConJP 4 | 5 | Created by Yutaro Muta on 9/17/16. 6 | Copyright © 2016 PyCon JP. All rights reserved. 7 | */ 8 | 9 | /** 10 | AlertController 11 | */ 12 | 13 | "cancel" = "Cancel"; 14 | 15 | "open" = "Open"; 16 | -------------------------------------------------------------------------------- /PyConJP/Resource/Localizable/en.lproj/Map.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Map.strings 3 | PyConJP 4 | 5 | Created by Yutaro Muta on 8/30/2016. 6 | Copyright © 2016 PyCon JP. All rights reserved. 7 | */ 8 | 9 | /** 10 | MapViewController 11 | */ 12 | 13 | "nameWaseda" = "Waseda University, Nishi-Waseda Campus"; 14 | 15 | "addressWaseda" = "Waseda University, Nishi-Waseda Campus, Building 63\n3-4-1, Okubo, Shinjuku, Tokyo\n169-0072, Japan"; 16 | 17 | "nameMicrosoft" = "Microsoft Japan Co., Ltd."; 18 | 19 | "addressMicrosoft" = "Microsoft Japan Co., Ltd.\nShinagawa Grand Central Tower, 2-16-3 Konan, Minato, Tokyo\n108-0075, Japan"; 20 | -------------------------------------------------------------------------------- /PyConJP/Resource/Localizable/en.lproj/MoreList.strings: -------------------------------------------------------------------------------- 1 | /* 2 | MoreList.strings 3 | PyConJP 4 | 5 | Created by Yutaro Muta on 2017/09/07. 6 | Copyright © 2017 PyCon JP. All rights reserved. 7 | */ 8 | 9 | /** 10 | MoreListViewController 11 | */ 12 | 13 | "participantsInformation" = "Participants Information"; 14 | "whatsPyConJP" = "What is PyCon JP?"; 15 | "codeOfConduct" = "Code of Conduct"; 16 | "summary" = "Summary"; 17 | "sponsor" = "Sponsor"; 18 | "staffList" = "Staff List"; 19 | "survey" = "Survey"; 20 | 21 | "venue" = "Venue Information"; 22 | "conferenceMap" = "Tutorials・Conference"; 23 | "sprintMap" = "Sprints"; 24 | 25 | "application" = "About Application"; 26 | "repository" = "Repository"; 27 | "license" = "The MIT License (MIT)"; 28 | "feedback" = "Feedback (Open Mail)"; 29 | -------------------------------------------------------------------------------- /PyConJP/Resource/Localizable/en.lproj/URLScheme.strings: -------------------------------------------------------------------------------- 1 | /* 2 | URLScheme.strings 3 | PyConJP 4 | 5 | Created by Yutaro Muta on 9/17/16. 6 | Copyright © 2016 PyCon JP. All rights reserved. 7 | */ 8 | 9 | /** 10 | TwitterURLSchemeType 11 | */ 12 | 13 | "twitterAlertTitle" = "Launch Twitter App"; 14 | 15 | "twitterAlertMessage" = "Try to open %@"; 16 | -------------------------------------------------------------------------------- /PyConJP/Resource/Localizable/ja.lproj/EventList.strings: -------------------------------------------------------------------------------- 1 | /* 2 | EventList.strings 3 | PyConJP 4 | 5 | Created by Yutaro Muta on 2017/08/28. 6 | Copyright © 2017 PyCon JP. All rights reserved. 7 | */ 8 | 9 | /** 10 | EventsListViewController Section Row 11 | */ 12 | 13 | "tutorials" = "チュートリアル"; 14 | "keynote" = "基調講演"; 15 | "posters" = "ポスター"; 16 | "lightningTalks" = "ライトニングトーク (LT)"; 17 | "youthCoderWorkshop" = "Youth Coder Workshop"; 18 | "committeeMeeting" = "Committee Meeting"; 19 | "communityBooth" = "Community Booth"; 20 | "jobFair" = "ジョブフェア"; 21 | "openSpace" = "オープンスペース"; 22 | "mediaMeeting" = "メディア会議"; 23 | "sprints" = "スプリント"; 24 | -------------------------------------------------------------------------------- /PyConJP/Resource/Localizable/ja.lproj/Language.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Language.strings 3 | PyConJP 4 | 5 | Created by Yutaro Muta on 8/31/16. 6 | Copyright © 2016 PyCon JP. All rights reserved. 7 | */ 8 | 9 | "english" = "英語"; 10 | 11 | "japanese" = "日本語"; 12 | -------------------------------------------------------------------------------- /PyConJP/Resource/Localizable/ja.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localizable.strings 3 | PyConJP 4 | 5 | Created by Yutaro Muta on 9/17/16. 6 | Copyright © 2016 PyCon JP. All rights reserved. 7 | */ 8 | 9 | /** 10 | AlertController 11 | */ 12 | 13 | "cancel" = "キャンセル"; 14 | 15 | "open" = "開く"; 16 | -------------------------------------------------------------------------------- /PyConJP/Resource/Localizable/ja.lproj/Map.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Map.strings 3 | PyConJP 4 | 5 | Created by Yutaro Muta on 8/30/2016. 6 | Copyright © 2016 PyCon JP. All rights reserved. 7 | */ 8 | 9 | /** 10 | MapViewController 11 | */ 12 | 13 | "nameWaseda" = "早稲田大学西早稲田キャンパス"; 14 | 15 | "addressWaseda" = "〒169-0072\n東京都新宿区大久保 3-4-1\n早稲田大学西早稲田キャンパス 63号館"; 16 | 17 | "nameMicrosoft" = "日本マイクロソフト株式会社"; 18 | 19 | "addressMicrosoft" = "〒108-0075\n東京都港区港南 2-16-3 品川グランドセントラルタワー\n日本マイクロソフト株式会社"; 20 | -------------------------------------------------------------------------------- /PyConJP/Resource/Localizable/ja.lproj/MoreList.strings: -------------------------------------------------------------------------------- 1 | /* 2 | MoreList.strings 3 | PyConJP 4 | 5 | Created by Yutaro Muta on 2017/09/07. 6 | Copyright © 2017 PyCon JP. All rights reserved. 7 | */ 8 | 9 | /** 10 | MoreListViewController 11 | */ 12 | 13 | "participantsInformation" = "参加の手引き"; 14 | "whatsPyConJP" = "PyCon JPってなに?"; 15 | "codeOfConduct" = "行動規範"; 16 | "summary" = "開催概要"; 17 | "sponsor" = "スポンサー"; 18 | "staffList" = "スタッフ一覧"; 19 | "survey" = "アンケート"; 20 | 21 | "venue" = "会場情報"; 22 | "conferenceMap" = "チュートリアル・カンファレンス"; 23 | "sprintMap" = "スプリント"; 24 | 25 | "application" = "このアプリについて"; 26 | "repository" = "リポジトリ"; 27 | "license" = "The MIT License (MIT)"; 28 | "feedback" = "フィードバック (Mailを起動)"; 29 | -------------------------------------------------------------------------------- /PyConJP/Resource/Localizable/ja.lproj/URLScheme.strings: -------------------------------------------------------------------------------- 1 | /* 2 | URLScheme.strings 3 | PyConJP 4 | 5 | Created by Yutaro Muta on 9/17/16. 6 | Copyright © 2016 PyCon JP. All rights reserved. 7 | */ 8 | 9 | /** 10 | TwitterURLSchemeType 11 | */ 12 | 13 | "twitterAlertTitle" = "Twiiterアプリを起動"; 14 | 15 | "twitterAlertMessage" = "%@ を開きます"; 16 | -------------------------------------------------------------------------------- /PyConJP/Resource/Settings.bundle/Root.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | StringsTable 6 | Root 7 | PreferenceSpecifiers 8 | 9 | 10 | Type 11 | PSChildPaneSpecifier 12 | Title 13 | Acknowledgments 14 | File 15 | com.mono0926.LicensePlist 16 | 17 | 18 | Type 19 | PSGroupSpecifier 20 | Title 21 | Copyright 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /PyConJP/Resource/Settings.bundle/com.mono0926.LicensePlist.latest_result.txt: -------------------------------------------------------------------------------- 1 | name: Result, nameSpecified: , owner: antitypical, version: 3.2.4 2 | 3 | name: APIKit, nameSpecified: , owner: ishkawa, version: 3.2.0 4 | 5 | name: SpreadsheetView, nameSpecified: , owner: kishikawakatsumi, version: v0.8.4 6 | 7 | name: Kingfisher, nameSpecified: , owner: onevcat, version: 3.13.1 8 | 9 | name: realm-cocoa, nameSpecified: , owner: realm, version: v2.10.2 10 | 11 | add-version-numbers: false 12 | 13 | LicensePlist Version: 1.8.2 -------------------------------------------------------------------------------- /PyConJP/Resource/Settings.bundle/com.mono0926.LicensePlist.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | File 9 | com.mono0926.LicensePlist/APIKit 10 | Title 11 | APIKit 12 | Type 13 | PSChildPaneSpecifier 14 | 15 | 16 | File 17 | com.mono0926.LicensePlist/Kingfisher 18 | Title 19 | Kingfisher 20 | Type 21 | PSChildPaneSpecifier 22 | 23 | 24 | File 25 | com.mono0926.LicensePlist/realm-cocoa 26 | Title 27 | realm-cocoa 28 | Type 29 | PSChildPaneSpecifier 30 | 31 | 32 | File 33 | com.mono0926.LicensePlist/Result 34 | Title 35 | Result 36 | Type 37 | PSChildPaneSpecifier 38 | 39 | 40 | File 41 | com.mono0926.LicensePlist/SpreadsheetView 42 | Title 43 | SpreadsheetView 44 | Type 45 | PSChildPaneSpecifier 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /PyConJP/Resource/Settings.bundle/com.mono0926.LicensePlist/APIKit.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | **Copyright (c) 2015 - 2016 Yosuke Ishikawa** 10 | 11 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | 17 | 18 | Type 19 | PSGroupSpecifier 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /PyConJP/Resource/Settings.bundle/com.mono0926.LicensePlist/Kingfisher.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | The MIT License (MIT) 10 | 11 | Copyright (c) 2018 Wei Wang 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 29 | SOFTWARE. 30 | 31 | 32 | Type 33 | PSGroupSpecifier 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /PyConJP/Resource/Settings.bundle/com.mono0926.LicensePlist/Result.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | The MIT License (MIT) 10 | 11 | Copyright (c) 2014 Rob Rix 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 29 | SOFTWARE. 30 | Type 31 | PSGroupSpecifier 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /PyConJP/Resource/Settings.bundle/com.mono0926.LicensePlist/SpreadsheetView.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | MIT License 10 | 11 | Copyright (c) 2017 Kishikawa Katsumi 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 29 | SOFTWARE. 30 | 31 | Type 32 | PSGroupSpecifier 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /PyConJP/Resource/Settings.bundle/en.lproj/Root.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Resource/Settings.bundle/en.lproj/Root.strings -------------------------------------------------------------------------------- /PyConJP/Resource/Settings.bundle/ja.lproj/Root.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/PyConJP/Resource/Settings.bundle/ja.lproj/Root.strings -------------------------------------------------------------------------------- /PyConJP/Storyboard/en.lproj/Bookmark.strings: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | BookmarkNavigationController 4 | */ 5 | 6 | /* Class = "UITabBarItem"; title = "Bookmark"; ObjectID = "G4f-OO-Xar"; */ 7 | "G4f-OO-Xar.title" = "Bookmark"; 8 | 9 | 10 | /** 11 | BookmarkViewController 12 | */ 13 | 14 | /* Class = "UINavigationItem"; title = "Bookmark"; ObjectID = "gT9-SV-IIF"; */ 15 | "gT9-SV-IIF.title" = "Bookmark"; 16 | 17 | /* Class = "UIBarButtonItem"; title = " "; ObjectID = "mln-vy-6xh"; */ 18 | "mln-vy-6xh.title" = " "; 19 | 20 | 21 | /** 22 | BookmarkListViewController 23 | */ 24 | 25 | /* Class = "UINavigationItem"; title = "Bookmark"; ObjectID = "dBi-0j-5q3"; */ 26 | "dBi-0j-5q3.title" = "Bookmark"; 27 | 28 | /* Class = "UIBarButtonItem"; title = " "; ObjectID = "dK4-lC-Czn"; */ 29 | "dK4-lC-Czn.title" = " "; 30 | -------------------------------------------------------------------------------- /PyConJP/Storyboard/en.lproj/Conference.strings: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | ConferenceNavigationController 4 | */ 5 | 6 | /* Class = "UITabBarItem"; title = "Conference"; ObjectID = "ZuP-30-Iu1"; */ 7 | "ZuP-30-Iu1.title" = "Conference"; 8 | 9 | 10 | /** 11 | ConferenceViewController 12 | */ 13 | 14 | /* Class = "UINavigationItem"; title = "Conference"; ObjectID = "Q68-Bc-SB0"; */ 15 | "Q68-Bc-SB0.title" = "Conference"; 16 | 17 | /* Class = "UIBarButtonItem"; title = " "; ObjectID = "cef-TD-d2s"; */ 18 | "cef-TD-d2s.title" = " "; 19 | 20 | 21 | /** 22 | ConferenceBaseViewController 23 | */ 24 | 25 | /* Class = "UINavigationItem"; title = "Conference"; ObjectID = "zN7-B8-vNJ"; */ 26 | "zN7-B8-vNJ.title" = "Conference"; 27 | 28 | /* Class = "UIBarButtonItem"; title = " "; ObjectID = "ARZ-4x-RxF"; */ 29 | "ARZ-4x-RxF.title" = " "; 30 | 31 | 32 | /** 33 | ConferenceDateViewController 34 | */ 35 | 36 | /* Class = "UIButton"; normalTitle = "Day1"; ObjectID = "xEC-K7-3BF"; */ 37 | "xEC-K7-3BF.normalTitle" = "Day1"; 38 | 39 | /* Class = "UIButton"; normalTitle = "Day2"; ObjectID = "fNF-R4-aQr"; */ 40 | "fNF-R4-aQr.normalTitle" = "Day2"; 41 | -------------------------------------------------------------------------------- /PyConJP/Storyboard/en.lproj/Events.strings: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | EventsNavigationController 4 | */ 5 | 6 | /* Class = "UITabBarItem"; title = "Events"; ObjectID = "ubk-Ga-9mF"; */ 7 | "ubk-Ga-9mF.title" = "Events"; 8 | 9 | 10 | /** 11 | EventsViewController 12 | */ 13 | 14 | /* Class = "UINavigationItem"; title = "Events"; ObjectID = "sqm-sS-mcY"; */ 15 | "sqm-sS-mcY.title" = "Events"; 16 | 17 | /* Class = "UIBarButtonItem"; title = " "; ObjectID = "I00-9O-hIK"; */ 18 | "I00-9O-hIK.title" = " "; 19 | 20 | 21 | /** 22 | EventsListViewController 23 | */ 24 | 25 | /* Class = "UINavigationItem"; title = "Events"; ObjectID = "7aG-LV-Eni"; */ 26 | "7aG-LV-Eni.title" = "Events"; 27 | 28 | /* Class = "UIBarButtonItem"; title = " "; ObjectID = "Kkv-wF-ctk"; */ 29 | "Kkv-wF-ctk.title" = " "; 30 | -------------------------------------------------------------------------------- /PyConJP/Storyboard/en.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | LaunchScreenViewController 4 | */ 5 | -------------------------------------------------------------------------------- /PyConJP/Storyboard/en.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | TalkDetailViewController 4 | */ 5 | 6 | /* Class = "UIBarButtonItem"; title = " "; ObjectID = "agf-dK-8uB"; */ 7 | "agf-dK-8uB.title" = " "; 8 | 9 | /* Class = "UILabel"; text = "Title"; ObjectID = "1cC-hE-Hba"; */ 10 | "1cC-hE-Hba.text" = "Title"; 11 | 12 | /* Class = "UILabel"; text = "day"; ObjectID = "nqD-Zb-1cG"; */ 13 | "nqD-Zb-1cG.text" = "day"; 14 | 15 | /* Class = "UILabel"; text = "time"; ObjectID = "9Hk-se-873"; */ 16 | "9Hk-se-873.text" = "time"; 17 | 18 | /* Class = "UILabel"; text = "place"; ObjectID = "Rcf-qG-0nK"; */ 19 | "Rcf-qG-0nK.text" = "place"; 20 | 21 | /* Class = "UILabel"; text = "Speaker"; ObjectID = "kzM-Hy-Nxe"; */ 22 | "kzM-Hy-Nxe.text" = "Speaker"; 23 | 24 | /* Class = "UILabel"; text = "Language: "; ObjectID = "bua-7j-fWI"; */ 25 | "bua-7j-fWI.text" = "Language: "; 26 | 27 | /* Class = "UILabel"; text = "Audience Level: "; ObjectID = "aHk-Dp-GNG"; */ 28 | "aHk-Dp-GNG.text" = "Audience Level: "; 29 | 30 | /* Class = "UILabel"; text = "Category: "; ObjectID = "Pbg-wa-R1a"; */ 31 | "Pbg-wa-R1a.text" = "Category: "; 32 | 33 | /* Class = "UILabel"; text = "Description"; ObjectID = "cOD-c6-zk2"; */ 34 | "cOD-c6-zk2.text" = "Description"; 35 | 36 | /* Class = "UILabel"; text = "Abstract"; ObjectID = "wgw-0x-wge"; */ 37 | "wgw-0x-wge.text" = "Abstract"; 38 | 39 | 40 | /** 41 | WebViewController 42 | */ 43 | 44 | /* Class = "UIBarButtonItem"; title = " "; ObjectID = "uSt-BB-mtx"; */ 45 | "uSt-BB-mtx.title" = " "; 46 | -------------------------------------------------------------------------------- /PyConJP/Storyboard/ja.lproj/Bookmark.strings: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | BookmarkNavigationController 4 | */ 5 | 6 | /* Class = "UITabBarItem"; title = "Bookmark"; ObjectID = "G4f-OO-Xar"; */ 7 | "G4f-OO-Xar.title" = "ブックマーク"; 8 | 9 | 10 | /** 11 | BookmarkViewController 12 | */ 13 | 14 | /* Class = "UINavigationItem"; title = "Bookmark"; ObjectID = "gT9-SV-IIF"; */ 15 | "gT9-SV-IIF.title" = "ブックマーク"; 16 | 17 | /* Class = "UIBarButtonItem"; title = " "; ObjectID = "mln-vy-6xh"; */ 18 | "mln-vy-6xh.title" = " "; 19 | 20 | 21 | /** 22 | BookmarkListViewController 23 | */ 24 | 25 | /* Class = "UINavigationItem"; title = "Bookmark"; ObjectID = "dBi-0j-5q3"; */ 26 | "dBi-0j-5q3.title" = "ブックマーク"; 27 | 28 | /* Class = "UIBarButtonItem"; title = " "; ObjectID = "dK4-lC-Czn"; */ 29 | "dK4-lC-Czn.title" = " "; 30 | -------------------------------------------------------------------------------- /PyConJP/Storyboard/ja.lproj/Conference.strings: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | ConferenceNavigationController 4 | */ 5 | 6 | /* Class = "UITabBarItem"; title = "Conference"; ObjectID = "ZuP-30-Iu1"; */ 7 | "ZuP-30-Iu1.title" = "カンファレンス"; 8 | 9 | 10 | /** 11 | ConferenceViewController 12 | */ 13 | 14 | /* Class = "UINavigationItem"; title = "Conference"; ObjectID = "Q68-Bc-SB0"; */ 15 | "Q68-Bc-SB0.title" = "カンファレンス"; 16 | 17 | /* Class = "UIBarButtonItem"; title = " "; ObjectID = "cef-TD-d2s"; */ 18 | "cef-TD-d2s.title" = " "; 19 | 20 | 21 | /** 22 | ConferenceBaseViewController 23 | */ 24 | 25 | /* Class = "UINavigationItem"; title = "Conference"; ObjectID = "zN7-B8-vNJ"; */ 26 | "zN7-B8-vNJ.title" = "カンファレンス"; 27 | 28 | /* Class = "UIBarButtonItem"; title = " "; ObjectID = "ARZ-4x-RxF"; */ 29 | "ARZ-4x-RxF.title" = " "; 30 | 31 | 32 | /** 33 | ConferenceDateViewController 34 | */ 35 | 36 | /* Class = "UIButton"; normalTitle = "Day1"; ObjectID = "xEC-K7-3BF"; */ 37 | "xEC-K7-3BF.normalTitle" = "Day1"; 38 | 39 | /* Class = "UIButton"; normalTitle = "Day2"; ObjectID = "fNF-R4-aQr"; */ 40 | "fNF-R4-aQr.normalTitle" = "Day2"; 41 | -------------------------------------------------------------------------------- /PyConJP/Storyboard/ja.lproj/Events.strings: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | EventsNavigationController 4 | */ 5 | 6 | /* Class = "UITabBarItem"; title = "Events"; ObjectID = "ubk-Ga-9mF"; */ 7 | "ubk-Ga-9mF.title" = "イベント"; 8 | 9 | 10 | /** 11 | EventsViewController 12 | */ 13 | 14 | /* Class = "UINavigationItem"; title = "Events"; ObjectID = "sqm-sS-mcY"; */ 15 | "sqm-sS-mcY.title" = "イベント"; 16 | 17 | /* Class = "UIBarButtonItem"; title = " "; ObjectID = "I00-9O-hIK"; */ 18 | "I00-9O-hIK.title" = " "; 19 | 20 | 21 | /** 22 | EventsListViewController 23 | */ 24 | 25 | /* Class = "UINavigationItem"; title = "Events"; ObjectID = "7aG-LV-Eni"; */ 26 | "7aG-LV-Eni.title" = "イベント"; 27 | 28 | /* Class = "UIBarButtonItem"; title = " "; ObjectID = "Kkv-wF-ctk"; */ 29 | "Kkv-wF-ctk.title" = " "; 30 | -------------------------------------------------------------------------------- /PyConJP/Storyboard/ja.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | LaunchScreenViewController 4 | */ 5 | -------------------------------------------------------------------------------- /PyConJP/Storyboard/ja.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | TalkDetailViewController 4 | */ 5 | 6 | /* Class = "UIBarButtonItem"; title = " "; ObjectID = "agf-dK-8uB"; */ 7 | "agf-dK-8uB.title" = " "; 8 | 9 | /* Class = "UILabel"; text = "Title"; ObjectID = "1cC-hE-Hba"; */ 10 | "1cC-hE-Hba.text" = "Title"; 11 | 12 | /* Class = "UILabel"; text = "day"; ObjectID = "nqD-Zb-1cG"; */ 13 | "nqD-Zb-1cG.text" = "day"; 14 | 15 | /* Class = "UILabel"; text = "time"; ObjectID = "9Hk-se-873"; */ 16 | "9Hk-se-873.text" = "time"; 17 | 18 | /* Class = "UILabel"; text = "place"; ObjectID = "Rcf-qG-0nK"; */ 19 | "Rcf-qG-0nK.text" = "place"; 20 | 21 | /* Class = "UILabel"; text = "Speaker"; ObjectID = "kzM-Hy-Nxe"; */ 22 | "kzM-Hy-Nxe.text" = "Speaker"; 23 | 24 | /* Class = "UILabel"; text = "Language: "; ObjectID = "bua-7j-fWI"; */ 25 | "bua-7j-fWI.text" = "言語: "; 26 | 27 | /* Class = "UILabel"; text = "Audience Level: "; ObjectID = "aHk-Dp-GNG"; */ 28 | "aHk-Dp-GNG.text" = "対象レベル: "; 29 | 30 | /* Class = "UILabel"; text = "Category: "; ObjectID = "Pbg-wa-R1a"; */ 31 | "Pbg-wa-R1a.text" = "カテゴリ: "; 32 | 33 | /* Class = "UILabel"; text = "Description"; ObjectID = "cOD-c6-zk2"; */ 34 | "cOD-c6-zk2.text" = "説明"; 35 | 36 | /* Class = "UILabel"; text = "Abstract"; ObjectID = "wgw-0x-wge"; */ 37 | "wgw-0x-wge.text" = "概要"; 38 | 39 | 40 | /** 41 | WebViewController 42 | */ 43 | 44 | /* Class = "UIBarButtonItem"; title = " "; ObjectID = "uSt-BB-mtx"; */ 45 | "uSt-BB-mtx.title" = " "; 46 | -------------------------------------------------------------------------------- /PyConJP/Support Files/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 | APPL 17 | CFBundleShortVersionString 18 | 2.0.2 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 3 23 | LSApplicationQueriesSchemes 24 | 25 | twitter 26 | mailto 27 | 28 | LSRequiresIPhoneOS 29 | 30 | UIMainStoryboardFile 31 | Main 32 | UIRequiredDeviceCapabilities 33 | 34 | armv64 35 | 36 | UIStatusBarStyle 37 | UIStatusBarStyleDefault 38 | UISupportedInterfaceOrientations 39 | 40 | UIInterfaceOrientationPortrait 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | UISupportedInterfaceOrientations~ipad 45 | 46 | UIInterfaceOrientationPortrait 47 | UIInterfaceOrientationPortraitUpsideDown 48 | UIInterfaceOrientationLandscapeLeft 49 | UIInterfaceOrientationLandscapeRight 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /PyConJP/View/SpreadsheetViewCell/TimetableCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TimetableCell.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2017/06/17. 6 | // Copyright © 2017 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SpreadsheetView 11 | 12 | final class TimetableCell: Cell, NibInstantitable { 13 | 14 | @IBOutlet weak var titleLabel: UILabel! 15 | @IBOutlet weak var timeLabel: UILabel! 16 | @IBOutlet weak var speakerLabel: UILabel! 17 | 18 | static let width: CGFloat = 200.0 19 | static let height: CGFloat = 2.0 20 | 21 | override func awakeFromNib() { 22 | super.awakeFromNib() 23 | gridlines = Gridlines.all(.solid(width: 1.0, color: .gray)) 24 | } 25 | 26 | override func prepareForReuse() { 27 | super.prepareForReuse() 28 | titleLabel.text = nil 29 | timeLabel.text = nil 30 | speakerLabel.text = nil 31 | self.backgroundColor = nil 32 | } 33 | 34 | func fill(_ talkObject: TalkObject) { 35 | titleLabel.text = talkObject.title 36 | timeLabel.text = talkObject.periodTime 37 | speakerLabel.text = talkObject.speakers 38 | self.backgroundColor = talkObject.isFavorite ? UIColor.lightYellow : nil 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /PyConJP/View/SpreadsheetViewCell/TimetableRoomCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TimetableRoomCell.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2017/06/18. 6 | // Copyright © 2017 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SpreadsheetView 11 | 12 | final class TimetableRoomCell: Cell, NibInstantitable { 13 | 14 | @IBOutlet weak var roomLabel: UILabel! 15 | 16 | static let width: CGFloat = 200.0 17 | static let height: CGFloat = 44.0 18 | 19 | override func awakeFromNib() { 20 | super.awakeFromNib() 21 | gridlines = Gridlines.all(.solid(width: 1.0, color: .gray)) 22 | } 23 | 24 | override func prepareForReuse() { 25 | roomLabel.text = nil 26 | backgroundColor = nil 27 | } 28 | 29 | func fill(_ room: Room) { 30 | roomLabel.text = room.description 31 | backgroundColor = room.color 32 | } 33 | 34 | } 35 | 36 | extension TimetableCellProtocol where Self: Cell { 37 | 38 | } 39 | 40 | protocol TimetableCellProtocol {} 41 | 42 | extension TimetableRoomCell: TimetableCellProtocol { 43 | 44 | } 45 | -------------------------------------------------------------------------------- /PyConJP/View/SpreadsheetViewCell/TimetableRoomCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /PyConJP/View/SpreadsheetViewCell/TimetableTimeAxisCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TimetableTimeAxisCell.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2017/06/18. 6 | // Copyright © 2017 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SpreadsheetView 11 | 12 | final class TimetableTimeAxisCell: Cell, NibInstantitable { 13 | 14 | @IBOutlet weak var timeLabel: UILabel! 15 | 16 | static let width: CGFloat = 44.0 17 | static let height: CGFloat = 3.0 18 | 19 | override func awakeFromNib() { 20 | super.awakeFromNib() 21 | gridlines = Gridlines.all(.solid(width: 1.0, color: .gray)) 22 | } 23 | 24 | override func prepareForReuse() { 25 | super.prepareForReuse() 26 | timeLabel.text = nil 27 | } 28 | 29 | func fill(_ hour: String) { 30 | timeLabel.text = hour 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /PyConJP/View/SpreadsheetViewCell/TimetableTimeAxisCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /PyConJP/View/UICollectionViewCell/SpeakerCollectionViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SpeakerCollectionViewCell.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 9/8/16. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import WebAPIFramework 11 | 12 | class SpeakerCollectionViewCell: UICollectionViewCell { 13 | 14 | @IBOutlet weak var iconImageView: UIImageView! 15 | @IBOutlet weak var nameLabel: UILabel! 16 | @IBOutlet weak var twitterLabel: UILabel! 17 | 18 | override func prepareForReuse() { 19 | iconImageView.image = #imageLiteral(resourceName: "Speaker") 20 | nameLabel.text = nil 21 | twitterLabel.text = nil 22 | } 23 | 24 | func fill(speaker: Speaker) { 25 | iconImageView.setImage(withURL: URL(string: WebConfig.hostURL + (speaker.imageURL ?? "")), 26 | imageTrainsition: UIImageView.ImageTransition.crossDissolve(0.3)) 27 | nameLabel.text = speaker.name 28 | twitterLabel.text = (speaker.twitterAccount != nil ? "@\(speaker.twitterAccount!)" : nil) 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /PyConJP/View/UITableViewCell/StaffTableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StaffTableViewCell.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 9/10/16. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class StaffTableViewCell: UITableViewCell { 12 | 13 | @IBOutlet weak var nameLabel: UILabel! 14 | @IBOutlet weak var roleLabel: UILabel! 15 | @IBOutlet weak var facebookButton: UIButton! 16 | @IBOutlet weak var twitterButton: UIButton! 17 | 18 | static let estimatedRowHeight: CGFloat = 100 19 | 20 | private var facebookAction: (() -> Void)? 21 | private var twitterAction: (() -> Void)? 22 | 23 | override func prepareForReuse() { 24 | nameLabel.text = nil 25 | roleLabel.text = nil 26 | toggleFacebookButton(enabled: false) 27 | toggleTwitterButton(enabled: false) 28 | } 29 | 30 | func fill(staff: Staff, onFacebookButton: @escaping (() -> Void), onTwitterButton: @escaping (() -> Void)) { 31 | nameLabel.text = staff.name 32 | roleLabel.text = staff.role 33 | toggleFacebookButton(enabled: !staff.facebook.isEmpty) 34 | toggleTwitterButton(enabled: !staff.twitter.isEmpty) 35 | facebookAction = onFacebookButton 36 | twitterAction = onTwitterButton 37 | } 38 | 39 | private func toggleFacebookButton(enabled: Bool) { 40 | facebookButton.isEnabled = enabled 41 | facebookButton.backgroundColor = enabled ? UIColor.facebook : UIColor.silver 42 | } 43 | 44 | private func toggleTwitterButton(enabled: Bool) { 45 | twitterButton.isEnabled = enabled 46 | twitterButton.backgroundColor = enabled ? UIColor.twitter : UIColor.silver 47 | } 48 | 49 | @IBAction func onFacebookButton(_ sender: UIButton) { 50 | guard let facebookAction = facebookAction else { return } 51 | facebookAction() 52 | } 53 | 54 | @IBAction func onTwitterButton(_ sender: UIButton) { 55 | guard let twitterAction = twitterAction else { return } 56 | twitterAction() 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /PyConJP/View/UITableViewCell/TalkTableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TalkTableViewCell.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2016/03/07. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class TalkTableViewCell: UITableViewCell { 12 | 13 | @IBOutlet weak var titleLabel: UILabel! 14 | @IBOutlet weak var timeLabel: UILabel! 15 | @IBOutlet weak var placeLabel: UILabel! 16 | @IBOutlet weak var placeView: UIView! 17 | @IBOutlet weak var speakerLabel: UILabel! 18 | 19 | static let estimatedRowHeight: CGFloat = 134 20 | 21 | override func prepareForReuse() { 22 | titleLabel.text = nil 23 | timeLabel.text = nil 24 | placeLabel.text = nil 25 | speakerLabel.text = nil 26 | placeView.backgroundColor = UIColor.darkGray 27 | } 28 | 29 | func fill(talkObject: TalkObject) { 30 | titleLabel.text = talkObject.title 31 | timeLabel.text = talkObject.periodTime 32 | placeLabel.text = talkObject.room?.description 33 | speakerLabel.text = talkObject.speakers 34 | if let room = talkObject.room { 35 | placeView.backgroundColor = room.color 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /PyConJP/ViewController/Base/BaseTabBarController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BaseTabBarController.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2016/02/19. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class BaseTabBarController: UITabBarController { 12 | 13 | private var eventsTabNavigationController: UINavigationController? 14 | private var conferenceTabNavigationController: UINavigationController? 15 | private var moreTabNavigationController: UINavigationController? 16 | 17 | override func viewDidLoad() { 18 | super.viewDidLoad() 19 | 20 | // EventsceTab 21 | let eventsStoryboard = UIStoryboard(storyboard: .events) 22 | eventsTabNavigationController = eventsStoryboard.instantiateViewController(withIdentifier: "EventsNavigationController") as? UINavigationController 23 | 24 | // ConferenceTab 25 | let conferenceStoryboard = UIStoryboard(storyboard: .conference) 26 | conferenceTabNavigationController = conferenceStoryboard.instantiateViewController(withIdentifier: "ConferenceNavigationController") as? UINavigationController 27 | 28 | // MoreTab 29 | let moreStoryboard = UIStoryboard(storyboard: .more) 30 | moreTabNavigationController = moreStoryboard.instantiateViewController(withIdentifier: "MoreNavigationController") as? UINavigationController 31 | 32 | let viewControllers = [eventsTabNavigationController!, conferenceTabNavigationController!, moreTabNavigationController!] as [UIViewController] 33 | self.setViewControllers(viewControllers, animated: false) 34 | self.selectedIndex = 1 35 | 36 | } 37 | 38 | override func didReceiveMemoryWarning() { 39 | super.didReceiveMemoryWarning() 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /PyConJP/ViewController/Base/DetailImageViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DetailImageViewController.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2016/08/05. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class DetailImageViewController: UIViewController { 12 | 13 | @IBOutlet weak var customImageView: CustomImageView? 14 | 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | 18 | let doubleTapGesture = UITapGestureRecognizer(target: customImageView, action: #selector(CustomImageView.handleGesture(_:))) 19 | doubleTapGesture.numberOfTapsRequired = 2 20 | view.addGestureRecognizer(doubleTapGesture) 21 | 22 | let pinchGesture = UIPinchGestureRecognizer(target: customImageView, action: #selector(CustomImageView.handleGesture(_:))) 23 | view.addGestureRecognizer(pinchGesture) 24 | 25 | let longPressGesture = UILongPressGestureRecognizer(target: customImageView, action: #selector(CustomImageView.handleGesture(_:))) 26 | view.addGestureRecognizer(longPressGesture) 27 | 28 | let panGesture = UIPanGestureRecognizer(target: customImageView, action: #selector(CustomImageView.handleGesture(_:))) 29 | view.addGestureRecognizer(panGesture) 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /PyConJP/ViewController/Conference/ConferenceBaseViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ConferenceBaseViewController.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2016/03/07. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ConferenceBaseViewController: UIViewController, UIPageViewControllerDelegate { 12 | 13 | @IBOutlet weak var barContainerView: UIView! 14 | @IBOutlet weak var pageContainerView: UIView! 15 | 16 | var conferenceDateViewProtocol: ConferenceDateViewProtocol? 17 | var conferencePageViewProtocol: ConferencePageViewProtocol? 18 | 19 | private var displayIndex: Int = 0 { 20 | didSet { 21 | if let conferenceDateViewProtocol = conferenceDateViewProtocol { 22 | conferenceDateViewProtocol.changeActive(index: displayIndex) 23 | } 24 | } 25 | } 26 | 27 | override func viewDidLoad() { 28 | super.viewDidLoad() 29 | 30 | let conferencePageViewController = ConferencePageViewController.build() 31 | conferencePageViewController.view.frame = pageContainerView.bounds 32 | self.addChildViewController(conferencePageViewController) 33 | pageContainerView.addSubview(conferencePageViewController.view) 34 | conferencePageViewController.didMove(toParentViewController: self) 35 | 36 | let conferenceDateViewController = ConferenceDateViewController.build() 37 | conferenceDateViewController.view.frame = barContainerView.bounds 38 | self.addChildViewController(conferenceDateViewController) 39 | barContainerView.addSubview(conferenceDateViewController.view) 40 | conferenceDateViewController.didMove(toParentViewController: self) 41 | 42 | } 43 | 44 | } 45 | 46 | protocol ConferencePageViewProtocol { 47 | func fowardPage(index: Int) 48 | func reversePage(index: Int) 49 | } 50 | 51 | protocol ConferenceDateViewProtocol { 52 | func changeActive(index: Int) 53 | } 54 | -------------------------------------------------------------------------------- /PyConJP/ViewController/Conference/ConferenceModelController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ConferenceModelController.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2016/03/07. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ConferenceModelController: NSObject, UIPageViewControllerDataSource { 12 | 13 | private let days: [PyConJPDate] = PyConJPDate.confarenceDate() 14 | 15 | override init() { 16 | super.init() 17 | } 18 | 19 | func viewController(index: Int) -> ConferenceTimetableViewController? { 20 | 21 | if self.days.isEmpty || index >= days.count { 22 | return nil 23 | } 24 | 25 | let conferenceTimetableViewController = ConferenceTimetableViewController.build(days[index]) 26 | return conferenceTimetableViewController 27 | } 28 | 29 | func indexOfViewController(viewController: UIViewController) -> Int { 30 | guard let viewController = viewController as? ConferenceTimetableViewController, 31 | let pyconJPDate = viewController.dataStore?.pyconJPDate else { return NSNotFound } 32 | return days.index(of: pyconJPDate) ?? NSNotFound 33 | } 34 | 35 | // MARK: - Page View Controller Data Source 36 | 37 | func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { 38 | var index = self.indexOfViewController(viewController: viewController) 39 | if (index == 0) || (index == NSNotFound) { 40 | return nil 41 | } 42 | 43 | index -= 1 44 | return self.viewController(index: index) 45 | } 46 | 47 | func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? { 48 | var index = self.indexOfViewController(viewController: viewController) 49 | if index == NSNotFound { 50 | return nil 51 | } 52 | 53 | index += 1 54 | if index == days.count { 55 | return nil 56 | } 57 | 58 | return self.viewController(index: index) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /PyConJP/ViewController/Conference/ConferencePageViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ConferencePageViewController.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2016/03/07. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ConferencePageViewController: UIPageViewController, StoryboardIdentifiable, ErrorAlertProtocol { 12 | 13 | private var conferenceModelViewProtocol: ConferenceModelViewProtocol? 14 | 15 | static func build() -> ConferencePageViewController { 16 | let conferencePageViewController: ConferencePageViewController = UIStoryboard(storyboard: .conference).instantiateViewController() 17 | return conferencePageViewController 18 | } 19 | 20 | override func viewDidLoad() { 21 | super.viewDidLoad() 22 | 23 | guard let startingViewController = conferenceModelController.viewController(index: 0) else { return } 24 | let viewControllers = [startingViewController] 25 | self.setViewControllers(viewControllers, direction: .forward, animated: false) 26 | 27 | // self.dataSource = self.conferenceModelController 28 | 29 | } 30 | 31 | private var _conferenceModelController: ConferenceModelController? 32 | 33 | fileprivate var conferenceModelController: ConferenceModelController { 34 | if _conferenceModelController == nil { 35 | _conferenceModelController = ConferenceModelController() 36 | } 37 | return _conferenceModelController! 38 | } 39 | 40 | override func didReceiveMemoryWarning() { 41 | super.didReceiveMemoryWarning() 42 | } 43 | 44 | override func didMove(toParentViewController parent: UIViewController?) { 45 | guard let conferenceBaseViewController = parent as? ConferenceBaseViewController else { return } 46 | // self.delegate = conferenceBaseViewController 47 | conferenceBaseViewController.conferencePageViewProtocol = self 48 | 49 | // self.view.subviews.forEach { 50 | // if let scrollView = $0 as? UIScrollView { 51 | // scrollView.delegate = conferenceBaseViewController 52 | // } 53 | // } 54 | } 55 | 56 | } 57 | 58 | extension ConferencePageViewController: ConferencePageViewProtocol { 59 | 60 | func fowardPage(index: Int) { 61 | movePage(index: index, direction: .forward) 62 | } 63 | 64 | func reversePage(index: Int) { 65 | movePage(index: index, direction: .reverse) 66 | } 67 | 68 | private func movePage(index: Int, direction: UIPageViewControllerNavigationDirection) { 69 | guard let viewController = conferenceModelController.viewController(index: index) else { return } 70 | let viewControllers = [viewController] 71 | setViewControllers(viewControllers, direction: direction, animated: true) 72 | } 73 | 74 | } 75 | 76 | protocol ConferenceModelViewProtocol { 77 | func loadData() 78 | } 79 | -------------------------------------------------------------------------------- /PyConJP/ViewController/Conference/ConferenceViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ConferenceViewController.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 8/27/16. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ConferenceViewController: UIViewController { 12 | 13 | @IBAction func onBookmark(_ sender: UIBarButtonItem) { 14 | let bookmarkListViewController = BookmarkListViewController.build() 15 | self.navigationController?.pushViewController(bookmarkListViewController, animated: true) 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /PyConJP/ViewController/More/FloorMapListViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FloorMapListViewController.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2016/08/05. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class FloorMapListViewController: UITableViewController, StoryboardIdentifiable { 12 | 13 | private let sections: [Section] = Section.sections 14 | 15 | static func build() -> FloorMapListViewController { 16 | let floorMapListViewController: FloorMapListViewController = UIStoryboard(storyboard: .more).instantiateViewController() 17 | return floorMapListViewController 18 | } 19 | 20 | // MARK: - Table View Controller Delegate 21 | 22 | override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 23 | 24 | let floorMapZoomableImageViewController = FloorMapZoomableImageViewController.build(assetCatalog: sections[indexPath.section].rows[indexPath.row]) 25 | self.present(floorMapZoomableImageViewController, animated: true, completion: nil) 26 | } 27 | 28 | private enum Section: Int { 29 | case firstFloor 30 | case secondFloor 31 | case thirdFloor 32 | 33 | static let sections: [Section] = [.firstFloor, .secondFloor, .thirdFloor] 34 | 35 | var rows: [FloorMapZoomableImageViewController.AssetCatalog] { 36 | switch self { 37 | case .firstFloor: 38 | return [.firstFloorView] 39 | case .secondFloor: 40 | return [.secondFloorView, .room201, .room202, .room203] 41 | case .thirdFloor: 42 | return [.thirdFloorView] 43 | } 44 | } 45 | 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /PyConJP/ViewController/More/FloorMapZoomableImageViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FloorMapZoomableImageViewController.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2016/08/05. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class FloorMapZoomableImageViewController: ZoomableImageViewController { 12 | 13 | private var assetCatalog: AssetCatalog? { 14 | didSet { 15 | DispatchQueue.main.async { 16 | self.imageView?.image = self.assetCatalog?.image 17 | } 18 | } 19 | } 20 | 21 | static func build(assetCatalog: AssetCatalog) -> FloorMapZoomableImageViewController { 22 | let floorMapImageViewController: FloorMapZoomableImageViewController = UIStoryboard(storyboard: .more).instantiateViewController() 23 | floorMapImageViewController.assetCatalog = assetCatalog 24 | return floorMapImageViewController 25 | } 26 | 27 | enum AssetCatalog { 28 | case firstFloorView 29 | case secondFloorView 30 | case thirdFloorView 31 | case room201 32 | case room202 33 | case room203 34 | 35 | var title: String { 36 | switch self { 37 | case .firstFloorView: return "1F" 38 | case .secondFloorView: return "2F" 39 | case .thirdFloorView: return "3F" 40 | case .room201: return "Room 201" 41 | case .room202: return "Room 202" 42 | case .room203: return "Room 203" 43 | } 44 | } 45 | 46 | var image: UIImage { 47 | switch self { 48 | case .firstFloorView: return #imageLiteral(resourceName: "FirstFloorMap") 49 | case .secondFloorView: return #imageLiteral(resourceName: "SecondFloorMap") 50 | case .thirdFloorView: return #imageLiteral(resourceName: "ThirdFloorMap") 51 | case .room201: return #imageLiteral(resourceName: "Room201Map") 52 | case .room202: return #imageLiteral(resourceName: "Room202Map") 53 | case .room203: return #imageLiteral(resourceName: "Room203Map") 54 | } 55 | } 56 | 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /PyConJP/ViewController/More/MapListViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MapListViewController.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 8/5/16. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class MapListViewController: UITableViewController, StoryboardIdentifiable { 12 | 13 | static func build() -> MapListViewController { 14 | let mapListViewController: MapListViewController = UIStoryboard(storyboard: .more).instantiateViewController() 15 | return mapListViewController 16 | } 17 | 18 | // MARK: - Table View Controller Delegate 19 | 20 | override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 21 | switch TableViewCell(rawValue: indexPath.row) ?? .access { 22 | case .access: 23 | let mapViewController = MapViewController.build(venue: MapViewController.Venue.waseda) 24 | self.navigationController?.pushViewController(mapViewController, animated: true) 25 | case .floor: 26 | let floorListViewController: FloorMapListViewController = UIStoryboard(storyboard: .more).instantiateViewController() 27 | self.navigationController?.pushViewController(floorListViewController, animated: true) 28 | } 29 | } 30 | 31 | private enum TableViewCell: Int { 32 | case access = 0 33 | case floor = 1 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /PyConJP/ViewController/More/MapViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MapViewController.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2016/03/10. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import MapKit 11 | 12 | class MapViewController: UIViewController, MKMapViewDelegate, StoryboardIdentifiable { 13 | 14 | @IBOutlet weak var textView: UITextView! 15 | @IBOutlet weak var mapView: MKMapView! 16 | 17 | private var venue: Venue? 18 | 19 | static func build(venue: Venue) -> MapViewController { 20 | let mapViewController: MapViewController = UIStoryboard(storyboard: .more).instantiateViewController() 21 | mapViewController.venue = venue 22 | return mapViewController 23 | } 24 | 25 | override func viewDidLoad() { 26 | super.viewDidLoad() 27 | 28 | guard let venue = venue else { return } 29 | 30 | textView.text = venue.address 31 | 32 | mapView.setCenter(venue.location, animated: true) 33 | 34 | var region: MKCoordinateRegion = mapView.region 35 | region.center = venue.location 36 | region.span.latitudeDelta = 0.01 37 | region.span.longitudeDelta = 0.01 38 | mapView.setRegion(region, animated: true) 39 | 40 | let annotation = MKPointAnnotation() 41 | annotation.coordinate = venue.location 42 | annotation.title = venue.name 43 | mapView.addAnnotation(annotation) 44 | 45 | } 46 | 47 | override func viewDidLayoutSubviews() { 48 | super.viewDidLayoutSubviews() 49 | textView.setContentOffset(.zero, animated: false) 50 | } 51 | 52 | enum Venue { 53 | case waseda 54 | case microsoft 55 | 56 | var name: String { 57 | switch self { 58 | case .waseda: return NSLocalizedString("nameWaseda", tableName: "Map", comment: "") 59 | case .microsoft: return NSLocalizedString("nameMicrosoft", tableName: "Map", comment: "") 60 | } 61 | } 62 | 63 | var location: CLLocationCoordinate2D { 64 | switch self { 65 | case .waseda: return CLLocationCoordinate2D(latitude: 35.706069, longitude: 139.706809) 66 | case .microsoft: return CLLocationCoordinate2D(latitude: 35.626670, longitude: 139.740375) 67 | } 68 | } 69 | 70 | var address: String { 71 | switch self { 72 | case .waseda: return NSLocalizedString("addressWaseda", tableName: "Map", comment: "") 73 | case .microsoft: return NSLocalizedString("addressMicrosoft", tableName: "Map", comment: "") 74 | } 75 | } 76 | 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /PyConJP/ViewController/More/MoreListViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MoreListViewController.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 3/7/16. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SafariServices 11 | 12 | class MoreListViewController: UITableViewController { 13 | 14 | private lazy var dataStore: MoreListDataStore = MoreListDataStore { [weak self] in 15 | DispatchQueue.main.async { 16 | self?.tableView.reloadData() 17 | } 18 | } 19 | 20 | // MARK: - Table View Controller DataSource 21 | 22 | override func numberOfSections(in tableView: UITableView) -> Int { 23 | return dataStore.sections.count 24 | } 25 | 26 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 27 | return dataStore.sections[section].rows.count 28 | } 29 | 30 | override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { 31 | return dataStore.sections[section].title 32 | } 33 | 34 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 35 | let cell = tableView.dequeueReusableCell(withIdentifier: "MoreCell", for: indexPath) 36 | cell.textLabel?.text = dataStore.sections[indexPath.section].rows[indexPath.row].title 37 | return cell 38 | } 39 | 40 | // MARK: - Table View Controller Delegate 41 | 42 | override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 43 | let row = dataStore.sections[indexPath.section].rows[indexPath.row] 44 | switch row { 45 | case .whatsPyConJP, .codeOfConduct, .summary, .license, .staffList: 46 | guard let identifier = row.identifier, let viewController = self.storyboard?.instantiateViewController(withIdentifier: identifier) else { return } 47 | self.navigationController?.pushViewController(viewController, animated: true) 48 | case .participantsInformation, .sponsor, .repository: 49 | guard let url = row.url else { return } 50 | let safariViewController = SFSafariViewController(url: url) 51 | self.present(safariViewController, animated: true, completion: nil) 52 | case .survey(let url): 53 | let safariViewController = SFSafariViewController(url: url) 54 | self.present(safariViewController, animated: true, completion: nil) 55 | case .conferenceMap: 56 | let mapListViewController = MapListViewController.build() 57 | self.navigationController?.pushViewController(mapListViewController, animated: true) 58 | case .sprintMap: 59 | let mapViewController = MapViewController.build(venue: MapViewController.Venue.microsoft) 60 | self.navigationController?.pushViewController(mapViewController, animated: true) 61 | case .feedback: 62 | guard let urlSheme = row.urlSheme else { return } 63 | UIApplication.shared.open(urlSheme, options: [:], completionHandler: nil) 64 | tableView.deselectRow(at: indexPath, animated: true) 65 | } 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /PyConJP/ViewController/WebView/PCJWKWebViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PCJWKWebViewController.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2016/02/26. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import WebKit 11 | 12 | class PCJWKWebViewController: UIViewController, WKNavigationDelegate, WKUIDelegate, StoryboardIdentifiable { 13 | 14 | @IBOutlet weak var webContentView: UIView! 15 | 16 | private var url: String = "" 17 | 18 | static func build(url: String) -> PCJWKWebViewController { 19 | let pcjWKWebViewController: PCJWKWebViewController = UIStoryboard(storyboard: .main).instantiateViewController() 20 | pcjWKWebViewController.url = url 21 | return pcjWKWebViewController 22 | } 23 | 24 | override func viewDidLoad() { 25 | super.viewDidLoad() 26 | 27 | let webView = WKWebView(frame: .zero, configuration: WKWebViewConfiguration()) 28 | webView.translatesAutoresizingMaskIntoConstraints = false 29 | webView.navigationDelegate = self 30 | webView.allowsBackForwardNavigationGestures = true 31 | webContentView.addSubview(webView) 32 | 33 | let noLayoutFormatOptions = NSLayoutFormatOptions(rawValue: 0) 34 | webContentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[webView]|", options: noLayoutFormatOptions, metrics: nil, views: ["webView": webView])) 35 | 36 | webContentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[webView]|", options: noLayoutFormatOptions, metrics: nil, views: ["webView": webView])) 37 | 38 | let request = URLRequest(url: URL(string: url)!) 39 | webView.load(request) 40 | 41 | } 42 | 43 | override func didReceiveMemoryWarning() { 44 | super.didReceiveMemoryWarning() 45 | // Dispose of any resources that can be recreated. 46 | } 47 | 48 | func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { 49 | } 50 | 51 | func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? { 52 | guard let url = navigationAction.request.url else { 53 | return nil 54 | } 55 | guard let targetFrame = navigationAction.targetFrame, targetFrame.isMainFrame else { 56 | webView.load(URLRequest.init(url: url)) 57 | return nil 58 | } 59 | 60 | return nil 61 | } 62 | 63 | @IBAction func onCleseButton(_ sender: UIBarButtonItem) { 64 | self.dismiss(animated: true, completion: nil) 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /PyConJPTests/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 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /PyConJPTests/PyConJPTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PyConJPTests.swift 3 | // PyConJPTests 4 | // 5 | // Created by Yutaro Muta on 2016/02/16. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import PyConJP 11 | 12 | class PyConJPTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | // Use XCTAssert and related functions to verify your tests produce the correct results. 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measure { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /PyConJPUITests/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 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /PyConJPUITests/PyConJPUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PyConJPUITests.swift 3 | // PyConJPUITests 4 | // 5 | // Created by Yutaro Muta on 2016/02/16. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class PyConJPUITests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | 18 | // In UI tests it is usually best to stop immediately when a failure occurs. 19 | continueAfterFailure = false 20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 21 | XCUIApplication().launch() 22 | 23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 24 | } 25 | 26 | override func tearDown() { 27 | // Put teardown code here. This method is called after the invocation of each test method in the class. 28 | super.tearDown() 29 | } 30 | 31 | func testExample() { 32 | // Use recording to get started writing UI tests. 33 | // Use XCTAssert and related functions to verify your tests produce the correct results. 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](PyConJP/Assets.xcassets/AppIcon.appiconset/1024x1024.jpg) 2 | 3 | # PyCon JP Official Guile App [![GitHub license](https://img.shields.io/badge/license-MIT-lightgrey.svg)](https://raw.githubusercontent.com/pyconjp/pyconjp-ios/develop/LICENSE) 4 | 5 | * Swift 4.x 6 | * Xcode 9.x 7 | * iOS 9.0~ 8 | 9 | ## Required 10 | 11 | ### fastlane 12 | https://docs.fastlane.tools 13 | 14 | ```sh 15 | $gem install bundler 16 | $bundle install --path vendor/bundle 17 | $bundle exec fastlane init 18 | ``` 19 | 20 | ### Libraries are managed by Carthage 21 | https://github.com/Carthage/Carthage 22 | 23 | ```sh 24 | $brew install carthage 25 | $carthage update --platform iOS 26 | ``` 27 | 28 | #### Acknowledgements 🎉 29 | * [APIKit](https://github.com/ishkawa/APIKit) 30 | * [Result](https://github.com/antitypical/Result) 31 | * [Kingfisher](https://github.com/onevcat/Kingfisher) 32 | * [RealmSwift](https://realm.io/docs/swift/latest/) 33 | * [SpreadsheetView](https://github.com/kishikawakatsumi/SpreadsheetView) 34 | 35 | ## Optional 36 | 37 | ### Using the SwiftLint recommended 38 | https://github.com/realm/SwiftLint 39 | 40 | ```sh 41 | $brew install swiftlint 42 | ``` 43 | 44 | ### The URL and Basic authentication on Staging server 45 | **Staging credentials are secret in PyCon JP staff** 46 | The URL, the user name of the basic authentication, and the password refer to the environment variable of Scheme 47 | For connection to staging, make the following settings 48 | (You can connect to the production environment without setting it) 49 | 50 | 1. Create `New Scheme` (Non sharing, Do not include in git) 51 | 2. Add the folloeing items to `Edit Scheme` > `Run` > `Arguments` > `Enviroment Variables` 52 | * APIBaseURL 53 | * APIAuthUser 54 | * APIAuthPassword 55 | 56 | ## License 57 | [pyconjp-ios](https://github.com/pyconjp/pyconjp-ios) is released under the [MIT License](LICENSE.md). 58 | 59 | 60 | -------------------------------------------------------------------------------- /WebAPIFramework/APIKit/GitHubRequest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GitHubRequest.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2017/09/02. 6 | // Copyright © 2017 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import APIKit 11 | 12 | public protocol GitHubRequest: Request {} 13 | 14 | public extension GitHubRequest { 15 | 16 | public var baseURL: URL { 17 | return URL(string: "https://pyconjp.github.io/app-static-api/2017/" + Locale.currentLanguageLocaleIdentifier + "/")! 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /WebAPIFramework/APIKit/PyConJPRequest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PyConJPRequest.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2017/06/12. 6 | // Copyright © 2017 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import APIKit 11 | 12 | public protocol PyConJPRequest: Request {} 13 | 14 | public extension PyConJPRequest { 15 | 16 | public var baseURL: URL { 17 | return URL(string: WebConfig.apiURL)! 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /WebAPIFramework/Error/APIError.swift: -------------------------------------------------------------------------------- 1 | // 2 | // APIError.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 2017/06/01. 6 | // Copyright © 2017 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public enum APIError: Error { 12 | case failureParse 13 | case nullData 14 | } 15 | -------------------------------------------------------------------------------- /WebAPIFramework/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 | 0.1 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /WebAPIFramework/LocaleExtension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LocaleExtension.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 8/16/2016. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension Locale { 12 | 13 | static var currentLanguageLocaleIdentifier: String { 14 | return Bundle.main.preferredLocalizations.first! 15 | } 16 | 17 | static var currentLanguageLocale: Locale { 18 | return Locale(identifier: Locale.currentLanguageLocaleIdentifier) 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /WebAPIFramework/WebAPIFramework.h: -------------------------------------------------------------------------------- 1 | // 2 | // WebAPIFramework.h 3 | // WebAPIFramework 4 | // 5 | // Created by Yutaro Muta on 2016/12/18. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for WebAPIFramework. 12 | FOUNDATION_EXPORT double WebAPIFrameworkVersionNumber; 13 | 14 | //! Project version string for WebAPIFramework. 15 | FOUNDATION_EXPORT const unsigned char WebAPIFrameworkVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /WebAPIFramework/WebConfig.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PCJConfig.swift 3 | // PyConJP 4 | // 5 | // Created by Yutaro Muta on 8/30/2016. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public enum WebConfig { 12 | 13 | public static let hostURL = ProcessInfo.processInfo.environment["APIBaseURL"] ?? "https://pycon.jp" 14 | 15 | public static let baseURL = WebConfig.hostURL + "/2017/" + Locale.currentLanguageLocaleIdentifier + "/" 16 | 17 | static let apiURL = WebConfig.baseURL + "api/" 18 | 19 | static let authUser = ProcessInfo.processInfo.environment["APIAuthUser"] ?? "" 20 | 21 | static let authPassword = ProcessInfo.processInfo.environment["APIAuthPassword"] ?? "" 22 | 23 | } 24 | -------------------------------------------------------------------------------- /WebAPIFrameworkTests/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 | -------------------------------------------------------------------------------- /WebAPIFrameworkTests/WebAPIFrameworkTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WebAPIFrameworkTests.swift 3 | // WebAPIFrameworkTests 4 | // 5 | // Created by Yutaro Muta on 2016/12/18. 6 | // Copyright © 2016 PyCon JP. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import WebAPIFramework 11 | 12 | class WebAPIFrameworkTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | // Use XCTAssert and related functions to verify your tests produce the correct results. 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measure { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /fastlane/Appfile: -------------------------------------------------------------------------------- 1 | app_identifier "jp.pycon.pyconjp" # The bundle identifier of your app 2 | apple_id "apple@pycon.jp" # Your Apple email address 3 | 4 | team_id "KP7AT73S3W" # Developer Portal Team ID 5 | 6 | # you can even provide different app identifiers, Apple IDs and team names per lane: 7 | # More information: https://docs.fastlane.tools/advanced/#appfile 8 | -------------------------------------------------------------------------------- /fastlane/Deliverfile: -------------------------------------------------------------------------------- 1 | ###################### More Options ###################### 2 | # If you want to have even more control, check out the documentation 3 | # https://docs.fastlane.tools/actions/deliver 4 | 5 | 6 | ###################### Automatically generated ###################### 7 | # Feel free to remove the following line if you use fastlane (which you should) 8 | 9 | app_identifier "jp.pycon.pyconjp" # The bundle identifier of your app 10 | username "apple@pycon.jp" # your Apple ID user 11 | -------------------------------------------------------------------------------- /fastlane/Fastfile: -------------------------------------------------------------------------------- 1 | # Customize this file, documentation can be found here: 2 | # https://docs.fastlane.tools/actions/ 3 | # All available actions: https://docs.fastlane.tools/actions 4 | # can also be listed using the `fastlane actions` command 5 | 6 | # Change the syntax highlighting to Ruby 7 | # All lines starting with a # are ignored when running `fastlane` 8 | 9 | # If you want to automatically update fastlane if a new version is available: 10 | # update_fastlane 11 | 12 | # This is the minimum version number required. 13 | # Update this, if you use features of a newer version 14 | min_fastlane_version("2.70.3") 15 | 16 | default_platform(:ios) 17 | 18 | platform :ios do 19 | before_all do 20 | # ENV["SLACK_URL"] = "https://hooks.slack.com/services/..." 21 | # cocoapods 22 | carthage 23 | end 24 | 25 | desc "Runs all the tests" 26 | lane :test do 27 | scan 28 | end 29 | 30 | desc "Submit a new Beta Build to Apple TestFlight" 31 | desc "This will also make sure the profile is up to date" 32 | lane :beta do 33 | # match(type: "appstore") # more information: https://codesigning.guide 34 | increment_build_number 35 | gym(scheme: "PyConJP") # more options available 36 | pilot 37 | 38 | # sh "your_script.sh" 39 | # You can also use other beta testing services here (run `fastlane actions`) 40 | end 41 | 42 | desc "Deploy a new version to the App Store" 43 | lane :release do 44 | # match(type: "appstore") 45 | snapshot 46 | increment_build_number 47 | gym(scheme: "PyConJP") # more options available 48 | deliver(force: true) 49 | # frameit 50 | end 51 | 52 | # You can define as many lanes as you want 53 | 54 | after_all do |lane| 55 | # This block is called, only if the executed lane was successful 56 | 57 | version_number = get_version_number 58 | build_number = get_build_number 59 | 60 | slack( 61 | message: "Successfully deployed new iOS App Update for " + lane.to_s, 62 | default_payloads: [], 63 | attachment_properties: { 64 | fields: [ 65 | { 66 | title: "Version", 67 | value: version_number, 68 | short: true 69 | },{ 70 | title: "Build Number", 71 | value: build_number, 72 | short: true 73 | } 74 | ] 75 | } 76 | ) 77 | end 78 | 79 | error do |lane, exception| 80 | slack( 81 | message: exception.message, 82 | success: false 83 | ) 84 | end 85 | end 86 | 87 | 88 | # More information about multiple platforms in fastlane: https://docs.fastlane.tools/advanced/#control-configuration-by-lane-and-by-platform 89 | # All available actions: https://docs.fastlane.tools/actions 90 | 91 | # fastlane reports which actions are used. No personal data is recorded. 92 | # Learn more at https://docs.fastlane.tools/#metrics 93 | -------------------------------------------------------------------------------- /fastlane/README.md: -------------------------------------------------------------------------------- 1 | fastlane documentation 2 | ================ 3 | # Installation 4 | 5 | Make sure you have the latest version of the Xcode command line tools installed: 6 | 7 | ``` 8 | xcode-select --install 9 | ``` 10 | 11 | ## Choose your installation method: 12 | 13 | | Method | OS support | Description | 14 | |----------------------------|-----------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------| 15 | | [Homebrew](http://brew.sh) | macOS | `brew cask install fastlane` | 16 | | Installer Script | macOS | [Download the zip file](https://download.fastlane.tools). Then double click on the `install` script (or run it in a terminal window). | 17 | | RubyGems | macOS or Linux with Ruby 2.0.0 or above | `sudo gem install fastlane -NV` | 18 | 19 | # Available Actions 20 | ## iOS 21 | ### ios test 22 | ``` 23 | fastlane ios test 24 | ``` 25 | Runs all the tests 26 | ### ios beta 27 | ``` 28 | fastlane ios beta 29 | ``` 30 | Submit a new Beta Build to Apple TestFlight 31 | 32 | This will also make sure the profile is up to date 33 | ### ios release 34 | ``` 35 | fastlane ios release 36 | ``` 37 | Deploy a new version to the App Store 38 | 39 | ---- 40 | 41 | This README.md is auto-generated and will be re-generated every time [fastlane](https://fastlane.tools) is run. 42 | More information about fastlane can be found on [fastlane.tools](https://fastlane.tools). 43 | The documentation of fastlane can be found on [docs.fastlane.tools](https://docs.fastlane.tools). 44 | -------------------------------------------------------------------------------- /fastlane/metadata/app_icon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/fastlane/metadata/app_icon.jpg -------------------------------------------------------------------------------- /fastlane/metadata/copyright.txt: -------------------------------------------------------------------------------- 1 | PyCon JP Committee 2 | -------------------------------------------------------------------------------- /fastlane/metadata/en-US/description.txt: -------------------------------------------------------------------------------- 1 | PyCon JP 2017 Guide Application. 2 | 3 | # Conference Talk List 4 | 5 | You can search for talks your interested in and add them to your bookmark list 6 | by tapping the button in the top right corner of the talk detail view. 7 | 8 | (Notification are not implemented yet.) 9 | 10 | 11 | # Event List 12 | 13 | You can view confirmed events that will be held at PyCon JP 2017. 14 | 15 | 16 | # Map 17 | 18 | Access maps to the conference venue as well as floor maps of the venue. 19 | 20 | 21 | # EvenT Summary 22 | 23 | Tutorial: 2017-9-7 (Thu) 2017, Waseda University, Nishi-Waseda Campus 24 | Conference: 2017-9-8 (Fri) - 9 (Sat) 2017, Waseda University, Nishi-Waseda Campus 25 | Development Sprints: 2017-9-10 (Sun) 2017, Microsoft Japan 26 | 27 | Please note that in order to join the tutorials and the conference, a ticket is required. 28 | -------------------------------------------------------------------------------- /fastlane/metadata/en-US/keywords.txt: -------------------------------------------------------------------------------- 1 | pycon, pycon jp, pycon japan, python, conference, community 2 | -------------------------------------------------------------------------------- /fastlane/metadata/en-US/marketing_url.txt: -------------------------------------------------------------------------------- 1 | https://pycon.jp/2017/en/ 2 | -------------------------------------------------------------------------------- /fastlane/metadata/en-US/name.txt: -------------------------------------------------------------------------------- 1 | PyCon JP 2017 2 | -------------------------------------------------------------------------------- /fastlane/metadata/en-US/privacy_url.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /fastlane/metadata/en-US/promotional_text.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /fastlane/metadata/en-US/release_notes.txt: -------------------------------------------------------------------------------- 1 | * Support for iOS 11 2 | * Support for iPhone X 3 | 4 | See you again next year PyCon JP 2018! 5 | -------------------------------------------------------------------------------- /fastlane/metadata/en-US/subtitle.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /fastlane/metadata/en-US/support_url.txt: -------------------------------------------------------------------------------- 1 | https://pycon.jp/2017/en/ 2 | -------------------------------------------------------------------------------- /fastlane/metadata/ja/description.txt: -------------------------------------------------------------------------------- 1 | PyCon JP 2017のガイドアプリ 2 | 3 | # カンファレンストーク一覧 4 | 一覧の中から気になるトークを探しましょう! 5 | 詳細画面 > 右上ボタンを押すと、ブックマークに追加することができます。(通知機能は未実装です。) 6 | 7 | # マップ 8 | 会場へのアクセスマップ、会場内のフロアマップを搭載! 9 | 10 | PyCon JP 2017は以下の日程で開催されます。 11 | チュートリアル: 2017年9月7(木) "早稲田大学西早稲田キャンパス" 12 | カンファレンス: 2017年9月8(金)、9(土) "早稲田大学西早稲田キャンパス" 13 | 開発スプリント: 2017年9月10(日) "日本マイクロソフト株式会社" 14 | 15 | ※チュートリアルやカンファレンスに参加するためには、チケットの購入が必要です。 16 | -------------------------------------------------------------------------------- /fastlane/metadata/ja/keywords.txt: -------------------------------------------------------------------------------- 1 | pycon, pycon jp, pycon japan, python, conference, community 2 | -------------------------------------------------------------------------------- /fastlane/metadata/ja/marketing_url.txt: -------------------------------------------------------------------------------- 1 | https://pycon.jp/2017/ja/ 2 | -------------------------------------------------------------------------------- /fastlane/metadata/ja/name.txt: -------------------------------------------------------------------------------- 1 | PyCon JP 2017 2 | -------------------------------------------------------------------------------- /fastlane/metadata/ja/privacy_url.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /fastlane/metadata/ja/promotional_text.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /fastlane/metadata/ja/release_notes.txt: -------------------------------------------------------------------------------- 1 | * iOS 11をサポートしました 2 | * iPhone Xをサポートしました 3 | 4 | 来年のPyCon JP 2018でまたお会いしましょう! 5 | -------------------------------------------------------------------------------- /fastlane/metadata/ja/subtitle.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /fastlane/metadata/ja/support_url.txt: -------------------------------------------------------------------------------- 1 | https://pycon.jp/2017/ja/ 2 | -------------------------------------------------------------------------------- /fastlane/metadata/primary_category.txt: -------------------------------------------------------------------------------- 1 | MZGenre.Navigation 2 | -------------------------------------------------------------------------------- /fastlane/metadata/primary_first_sub_category.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /fastlane/metadata/primary_second_sub_category.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /fastlane/metadata/review_information/demo_password.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /fastlane/metadata/review_information/demo_user.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /fastlane/metadata/review_information/email_address.txt: -------------------------------------------------------------------------------- 1 | muta.yutaro+pyconjp@gmail.com 2 | -------------------------------------------------------------------------------- /fastlane/metadata/review_information/first_name.txt: -------------------------------------------------------------------------------- 1 | Yutaro 2 | -------------------------------------------------------------------------------- /fastlane/metadata/review_information/last_name.txt: -------------------------------------------------------------------------------- 1 | Muta 2 | -------------------------------------------------------------------------------- /fastlane/metadata/review_information/notes.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /fastlane/metadata/review_information/phone_number.txt: -------------------------------------------------------------------------------- 1 | +81-80-1792-7998 2 | -------------------------------------------------------------------------------- /fastlane/metadata/secondary_category.txt: -------------------------------------------------------------------------------- 1 | MZGenre.SocialNetworking 2 | -------------------------------------------------------------------------------- /fastlane/metadata/secondary_first_sub_category.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /fastlane/metadata/secondary_second_sub_category.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /fastlane/metadata/trade_representative_contact_information/address_line1.txt: -------------------------------------------------------------------------------- 1 | 1-11-1, Higashiueno 2 | -------------------------------------------------------------------------------- /fastlane/metadata/trade_representative_contact_information/address_line2.txt: -------------------------------------------------------------------------------- 1 | Gosho Kasugadori Bldg. 9f. 2 | -------------------------------------------------------------------------------- /fastlane/metadata/trade_representative_contact_information/city_name.txt: -------------------------------------------------------------------------------- 1 | Taito-Ku 2 | -------------------------------------------------------------------------------- /fastlane/metadata/trade_representative_contact_information/country.txt: -------------------------------------------------------------------------------- 1 | Japan 2 | -------------------------------------------------------------------------------- /fastlane/metadata/trade_representative_contact_information/is_displayed_on_app_store.txt: -------------------------------------------------------------------------------- 1 | false 2 | -------------------------------------------------------------------------------- /fastlane/metadata/trade_representative_contact_information/postal_code.txt: -------------------------------------------------------------------------------- 1 | 110-0015 2 | -------------------------------------------------------------------------------- /fastlane/metadata/trade_representative_contact_information/state.txt: -------------------------------------------------------------------------------- 1 | Tokyo 2 | -------------------------------------------------------------------------------- /fastlane/metadata/trade_representative_contact_information/trade_name.txt: -------------------------------------------------------------------------------- 1 | PYCON JP COMMITTEE 2 | -------------------------------------------------------------------------------- /fastlane/screenshots/README.txt: -------------------------------------------------------------------------------- 1 | Put all screenshots you want to use inside the folder of its language (e.g. en-US). 2 | The device type will automatically be recognized using the image resolution. Apple TV screenshots 3 | should be stored in a subdirectory named appleTV with language folders inside of it. iMessage 4 | screenshots, like Apple TV screenshots, should also be stored in a subdirectory named iMessage 5 | with language folders inside of it. 6 | 7 | The screenshots can be named whatever you want, but keep in mind they are sorted alphabetically. 8 | -------------------------------------------------------------------------------- /fastlane/screenshots/en-US/1_iphone58_1.1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/fastlane/screenshots/en-US/1_iphone58_1.1.png -------------------------------------------------------------------------------- /fastlane/screenshots/en-US/1_iphone6Plus_1.1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/fastlane/screenshots/en-US/1_iphone6Plus_1.1.PNG -------------------------------------------------------------------------------- /fastlane/screenshots/en-US/2_iphone58_2.2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/fastlane/screenshots/en-US/2_iphone58_2.2.png -------------------------------------------------------------------------------- /fastlane/screenshots/en-US/2_iphone6Plus_2.2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/fastlane/screenshots/en-US/2_iphone6Plus_2.2.PNG -------------------------------------------------------------------------------- /fastlane/screenshots/en-US/3_iphone58_3.3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/fastlane/screenshots/en-US/3_iphone58_3.3.png -------------------------------------------------------------------------------- /fastlane/screenshots/en-US/3_iphone6Plus_3.3.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/fastlane/screenshots/en-US/3_iphone6Plus_3.3.PNG -------------------------------------------------------------------------------- /fastlane/screenshots/en-US/4_iphone58_4.4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/fastlane/screenshots/en-US/4_iphone58_4.4.png -------------------------------------------------------------------------------- /fastlane/screenshots/en-US/4_iphone6Plus_4.4.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/fastlane/screenshots/en-US/4_iphone6Plus_4.4.PNG -------------------------------------------------------------------------------- /fastlane/screenshots/ja/1_iphone58_1.1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/fastlane/screenshots/ja/1_iphone58_1.1.png -------------------------------------------------------------------------------- /fastlane/screenshots/ja/1_iphone6Plus_1.1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/fastlane/screenshots/ja/1_iphone6Plus_1.1.PNG -------------------------------------------------------------------------------- /fastlane/screenshots/ja/2_iphone58_2.2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/fastlane/screenshots/ja/2_iphone58_2.2.png -------------------------------------------------------------------------------- /fastlane/screenshots/ja/2_iphone6Plus_2.2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/fastlane/screenshots/ja/2_iphone6Plus_2.2.PNG -------------------------------------------------------------------------------- /fastlane/screenshots/ja/3_iphone58_3.3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/fastlane/screenshots/ja/3_iphone58_3.3.png -------------------------------------------------------------------------------- /fastlane/screenshots/ja/3_iphone6Plus_3.3.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/fastlane/screenshots/ja/3_iphone6Plus_3.3.PNG -------------------------------------------------------------------------------- /fastlane/screenshots/ja/4_iphone58_4.4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/fastlane/screenshots/ja/4_iphone58_4.4.png -------------------------------------------------------------------------------- /fastlane/screenshots/ja/4_iphone6Plus_4.4.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyconjp/pyconjp-ios/fa616d688bf98d6a4d4d1991970bd36a4ce22e84/fastlane/screenshots/ja/4_iphone6Plus_4.4.PNG --------------------------------------------------------------------------------