├── .gitignore
├── .gitmodules
├── .swift-version
├── .swiftlint.yml
├── .travis.yml
├── Cartfile
├── LICENSE
├── README.md
├── application
├── AccountListViewController.swift
├── AppDelegate.swift
├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Contents.json
│ ├── account.imageset
│ │ ├── Contents.json
│ │ ├── account.png
│ │ ├── account@2x.png
│ │ └── account@3x.png
│ ├── action.imageset
│ │ ├── Contents.json
│ │ ├── action.png
│ │ ├── action@2x.png
│ │ └── action@3x.png
│ ├── back.imageset
│ │ ├── Contents.json
│ │ ├── back.png
│ │ ├── back@2x.png
│ │ └── back@3x.png
│ ├── backOnBarButton.imageset
│ │ ├── Contents.json
│ │ ├── backOnBarButton.png
│ │ ├── backOnBarButton@2x.png
│ │ └── backOnBarButton@3x.png
│ ├── bookmark.imageset
│ │ ├── Contents.json
│ │ ├── bookmark.png
│ │ ├── bookmark@2x.png
│ │ └── bookmark@3x.png
│ ├── categoryList.imageset
│ │ ├── Contents.json
│ │ ├── categoryList.png
│ │ ├── categoryList@2x.png
│ │ └── categoryList@3x.png
│ ├── comments.imageset
│ │ ├── Contents.json
│ │ ├── comments.png
│ │ ├── comments@2x.png
│ │ └── comments@3x.png
│ ├── commentsFill.imageset
│ │ ├── Contents.json
│ │ ├── commentsFill.png
│ │ ├── commentsFill@2x.png
│ │ └── commentsFill@3x.png
│ ├── compose.imageset
│ │ ├── Contents.json
│ │ ├── compose.png
│ │ ├── compose@2x.png
│ │ └── compose@3x.png
│ ├── crown.imageset
│ │ ├── Contents.json
│ │ ├── crown.png
│ │ ├── crown@2x.png
│ │ └── crown@3x.png
│ ├── downVote.imageset
│ │ ├── Contents.json
│ │ ├── downVote.png
│ │ ├── downVote@2x.png
│ │ └── downVote@3x.png
│ ├── downVoteFill.imageset
│ │ ├── Contents.json
│ │ ├── downVoteFill.png
│ │ ├── downVoteFill@2x.png
│ │ └── downVoteFill@3x.png
│ ├── error.imageset
│ │ ├── Contents.json
│ │ ├── error.png
│ │ ├── error@2x.png
│ │ └── error@3x.png
│ ├── expand.imageset
│ │ ├── Contents.json
│ │ ├── expand.png
│ │ ├── expand@2x.png
│ │ └── expand@3x.png
│ ├── fold.imageset
│ │ ├── Contents.json
│ │ ├── fold.png
│ │ ├── fold@2x.png
│ │ └── fold@3x.png
│ ├── folder.imageset
│ │ ├── Contents.json
│ │ ├── folder.png
│ │ ├── folder@2x.png
│ │ └── folder@3x.png
│ ├── forward.imageset
│ │ ├── Contents.json
│ │ ├── forward.png
│ │ ├── forward@2x.png
│ │ └── forward@3x.png
│ ├── link.imageset
│ │ ├── Contents.json
│ │ ├── link.png
│ │ ├── link@2x.png
│ │ └── link@3x.png
│ ├── mailbox.imageset
│ │ ├── Contents.json
│ │ ├── mailbox.png
│ │ ├── mailbox@2x.png
│ │ └── mailbox@3x.png
│ ├── newsokurFolder.imageset
│ │ ├── Contents.json
│ │ ├── newsokurFolder.png
│ │ ├── newsokurFolder@2x.png
│ │ └── newsokurFolder@3x.png
│ ├── playButton.imageset
│ │ ├── Contents.json
│ │ ├── playButton.png
│ │ ├── playButton@2x.png
│ │ └── playButton@3x.png
│ ├── ranking.imageset
│ │ ├── Contents.json
│ │ ├── ranking.png
│ │ ├── ranking@2x.png
│ │ └── ranking@3x.png
│ ├── reply.imageset
│ │ ├── Contents.json
│ │ ├── reply.png
│ │ ├── reply@2x.png
│ │ └── reply@3x.png
│ ├── report.imageset
│ │ ├── Contents.json
│ │ ├── report.png
│ │ ├── report@2x.png
│ │ └── report@3x.png
│ ├── sample.imageset
│ │ ├── Contents.json
│ │ └── sample.jpg
│ ├── save.imageset
│ │ ├── Contents.json
│ │ ├── save.png
│ │ ├── save@2x.png
│ │ └── save@3x.png
│ ├── saveFill.imageset
│ │ ├── Contents.json
│ │ ├── saveFill.png
│ │ ├── saveFill@2x.png
│ │ └── saveFill@3x.png
│ ├── send.imageset
│ │ ├── Contents.json
│ │ ├── send.png
│ │ ├── send@2x.png
│ │ └── send@3x.png
│ ├── setting.imageset
│ │ ├── Contents.json
│ │ ├── setting.png
│ │ ├── setting@2x.png
│ │ └── setting@3x.png
│ ├── subredditList.imageset
│ │ ├── Contents.json
│ │ ├── subredditList.png
│ │ ├── subredditList@2x.png
│ │ └── subredditList@3x.png
│ ├── tab.imageset
│ │ ├── Contents.json
│ │ ├── tab.png
│ │ ├── tab@2x.png
│ │ └── tab@3x.png
│ ├── tabbarFolder.imageset
│ │ ├── Contents.json
│ │ ├── tabbarFolder.png
│ │ ├── tabbarFolder@2x.png
│ │ └── tabbarFolder@3x.png
│ ├── tabbarList.imageset
│ │ ├── Contents.json
│ │ ├── tabbarList.png
│ │ ├── tabbarList@2x.png
│ │ └── tabbarList@3x.png
│ ├── tabbarNewsokur.imageset
│ │ ├── Contents.json
│ │ ├── tabbarNewsokur.png
│ │ ├── tabbarNewsokur@2x.png
│ │ └── tabbarNewsokur@3x.png
│ ├── tabbarRanking.imageset
│ │ ├── Contents.json
│ │ ├── tabbarRanking.png
│ │ ├── tabbarRanking@2x.png
│ │ └── tabbarRanking@3x.png
│ ├── trend.imageset
│ │ ├── Contents.json
│ │ ├── trend.png
│ │ ├── trend@2x.png
│ │ └── trend@3x.png
│ ├── upVote.imageset
│ │ ├── Contents.json
│ │ ├── upVote.png
│ │ ├── upVote@2x.png
│ │ └── upVote@3x.png
│ ├── upVoteFill.imageset
│ │ ├── Contents.json
│ │ ├── upVoteFill.png
│ │ ├── upVoteFill@2x.png
│ │ └── upVoteFill@3x.png
│ ├── update.imageset
│ │ ├── Contents.json
│ │ ├── update.png
│ │ ├── update@2x.png
│ │ └── update@3x.png
│ └── vote.imageset
│ │ ├── Contents.json
│ │ ├── vote.png
│ │ ├── vote@2x.png
│ │ └── vote@3x.png
├── Base.lproj
│ ├── LaunchScreen.xib
│ └── Main.storyboard
├── BaseCommentCell.swift
├── CloseCommentCell.swift
├── CommentCell.swift
├── CommentContainable.swift
├── CommentContainer.swift
├── CommentContainerCellar.swift
├── CommentThumbnailView.swift
├── CommentViewController.swift
├── ContentInfoView.swift
├── ContentToolbar.swift
├── FromFieldView.swift
├── FrontViewController.swift
├── ImageDownloader.swift
├── ImageLinkThumbnailView.swift
├── ImageURLContainer.swift
├── ImageViewController.swift
├── ImageViewPageController.swift
├── ImageViewPageDismissAnimator.swift
├── ImageViewPageModalAnimator.swift
├── ImgurLinkContainer.swift
├── Info.plist
├── InvisibleCell.swift
├── LinkCell.swift
├── LinkContainable.swift
├── LinkContainer.swift
├── LinkContainerCellar.swift
├── LoadingCommentCell.swift
├── LoadingCommentCell.xib
├── MediaLinkCell.swift
├── MediaLinkContainer.swift
├── MoreCommentCell.swift
├── MoreCommentCell.xib
├── MoreContainer.swift
├── MoviePlayView.swift
├── MoviePlayerController.swift
├── MoviePlayerViewToolbar.swift
├── NewsokurCategoryViewController.swift
├── PostCommentViewController.swift
├── PostFieldView.swift
├── ReddiftAPPError.swift
├── ReddiftTextView.h
├── ReddiftTextView.m
├── SearchController.swift
├── SearchLinkCellar.swift
├── String+reddift.swift
├── SubredditCellar.swift
├── SubredditListCategoryTargetType.swift
├── SubredditListCategoryViewController.swift
├── SubredditListItem.swift
├── SubredditListRankingOrderType.swift
├── SubredditListRankingTargetType.swift
├── SubredditListRankingViewController.swift
├── SubredditListViewCell.swift
├── SubredditListViewController.swift
├── SubredditSelectTabBarController.swift
├── SubredditSelectViewController.storyboard
├── TabSelectViewController.swift
├── TabViewCell.swift
├── TabViewCell.xib
├── ThingContainable.swift
├── Thumbnail.swift
├── ThumbnailLinkCell.swift
├── ThumbnailLinkContainer.swift
├── TitleFieldView.swift
├── UIViewController+reddift.swift
├── URL+reddift.swift
├── URLFieldView.swift
├── UZTextViewCell.swift
├── UserViewController.swift
├── ViewController.swift
├── WebViewController.swift
├── application-Bridging-Header.h
├── application.entitlements
├── mona.ttf
├── reddift-Bridging-Header.h
├── reddift.entitlements
└── reddift_config.json.sample
├── framework
├── Extension
│ ├── Dictionary+reddift.swift
│ ├── HttpStatusWithBody.swift
│ ├── NSAttributedString+reddift.swift
│ ├── NSBundle+reddift.swift
│ ├── NSMutableURLRequest+reddift.swift
│ ├── NSURLComponents+reddift.swift
│ ├── NSURLRequest+reddift.swift
│ └── ReddiftError.swift
├── Info.plist
├── Model
│ ├── Account.swift
│ ├── CAPTCHA.swift
│ ├── Comment.swift
│ ├── Config.swift
│ ├── Created.swift
│ ├── Enum.swift
│ ├── Link.swift
│ ├── Listing.swift
│ ├── Media.swift
│ ├── MediaEmbed.swift
│ ├── Message.swift
│ ├── More.swift
│ ├── Multireddit.swift
│ ├── MultiredditDescription.swift
│ ├── Oembed.swift
│ ├── Paginator.swift
│ ├── Preference.swift
│ ├── Response.swift
│ ├── Subreddit.swift
│ ├── SubredditKarma.swift
│ ├── Thing.swift
│ ├── Trophy.swift
│ ├── User.swift
│ ├── Votable.swift
│ ├── generator.rb
│ └── source.html
├── Network
│ ├── BackgroundFetch.swift
│ ├── HttpStatus.swift
│ ├── Session+CAPTCHA.swift
│ ├── Session+Token.swift
│ ├── Session+account.swift
│ ├── Session+flair.swift
│ ├── Session+gold.swift
│ ├── Session+helper.swift
│ ├── Session+links.swift
│ ├── Session+listings.swift
│ ├── Session+liveThreads.swift
│ ├── Session+messages.swift
│ ├── Session+misc.swift
│ ├── Session+moderation.swift
│ ├── Session+multireddit.swift
│ ├── Session+search.swift
│ ├── Session+subreddits.swift
│ ├── Session+users.swift
│ ├── Session+wiki.swift
│ └── Session.swift
├── OAuth
│ ├── OAuth2AppOnlyToken.swift
│ ├── OAuth2Authorizer.swift
│ ├── OAuth2Token.swift
│ ├── OAuth2TokenRepository.swift
│ └── Token.swift
├── Utility
│ ├── Parser.swift
│ ├── Result.swift
│ └── helper.swift
└── reddift.h
├── playground
├── data.playground
│ ├── Contents.swift
│ ├── Resources
│ │ └── test_config.json.sample
│ ├── Sources
│ │ └── SupportCode.swift
│ └── contents.xcplayground
└── reddift.playground
│ ├── Contents.swift
│ ├── Resources
│ └── test_config.json.sample
│ ├── Sources
│ └── SupportCode.swift
│ └── contents.xcplayground
├── reddift.podspec
├── reddift.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── xcshareddata
│ └── xcschemes
│ ├── application.xcscheme
│ ├── reddift-iOS.xcscheme
│ ├── reddift-macOS.xcscheme
│ └── reddift-tvOS.xcscheme
└── test
├── AccountTest.swift
├── CAPTCHATest.swift
├── ExtendCommentsTest.swift
├── Info.plist
├── LinksTest.swift
├── ListingsTest.swift
├── MoreChildrenTest.swift
├── MultiredditTest.swift
├── ParseCommentMarkdownTest.swift
├── ParseResponseObjectTest.swift
├── ParseThingObjectTest.swift
├── ReddiftColorTest.swift
├── SearchTest.swift
├── SessionNoAuthTestSpec.swift
├── SessionTestSpec.swift
├── SubredditsTest.swift
├── UsersTest.swift
├── data
├── comment
│ └── comment_parse_data.json
├── other
│ ├── create_token.json
│ └── refresh_token.json
├── response
│ ├── TrophyList.json
│ ├── api_comment_response.json
│ ├── api_needs_captcha.json
│ ├── api_new_captcha.json
│ ├── comments.json
│ ├── comments_extend.json
│ ├── error.json
│ ├── links.json
│ ├── message.json
│ ├── moreChildren.json
│ ├── multi.json
│ ├── multidesc.json
│ └── subreddit.json
└── thing
│ ├── LabeledMulti.json
│ ├── LabeledMultiDescription.json
│ ├── UserList.json
│ ├── more.json
│ ├── t1.json
│ ├── t2.json
│ ├── t3.json
│ ├── t4.json
│ └── t5.json
├── objc-header.h
├── test_config.json.enc
└── test_config.json.sample
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | build/
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | xcuserdata
13 | *.xccheckout
14 | *.moved-aside
15 | DerivedData
16 | *.hmap
17 | *.ipa
18 | *.xcuserstate
19 | *.xcscmblueprint
20 |
21 | # CocoaPods
22 | #
23 | # We recommend against adding the Pods directory to your .gitignore. However
24 | # you should judge for yourself, the pros and cons are mentioned at:
25 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
26 | #
27 | Pods/
28 |
29 | # Carthage
30 | #
31 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
32 | # Carthage/Checkouts
33 |
34 | /Carthage
35 | /Cartfile.resolved
36 |
37 | # reddift
38 | \#*
39 | *~
40 | reddift_config.json
41 | test_config.json
42 | .DS_Store
43 |
44 | # jazzy
45 | /docs
46 |
47 | ## Playgrounds
48 | timeline.xctimeline
49 | playground.xcworkspace
50 |
51 | expired_token.json
52 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/.gitmodules
--------------------------------------------------------------------------------
/.swift-version:
--------------------------------------------------------------------------------
1 | 4.0
2 |
--------------------------------------------------------------------------------
/.swiftlint.yml:
--------------------------------------------------------------------------------
1 | disabled_rules:
2 | - trailing_whitespace
3 | - valid_docs
4 | - type_name
5 | - variable_name
6 |
7 | excluded:
8 | - reddift/vendor
9 | - playground
10 | - reddiftTests
11 | - reddiftSample
12 | - reddiftSampleTV
13 |
14 | file_length:
15 | warning: 2000
16 | error: 4000
17 |
18 | line_length:
19 | warning: 10000
20 | error: 20000
21 |
22 | type_body_length:
23 | warning: 1000
24 | error: 2000
25 |
26 | variable_name:
27 | max_length:
28 | warning: 50
29 | error: 40
30 | min_length:
31 | warning: 1
32 | error: 0
33 |
34 | function_parameter_count:
35 | warning: 10
36 | error: 20
37 |
38 | function_body_length:
39 | warning: 200
40 | error: 400
41 |
42 | cyclomatic_complexity:
43 | warning: 100
44 | error: 150
45 |
46 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: objective-c
2 | osx_image: xcode9.3
3 |
4 | before_install:
5 | - openssl aes-256-cbc -K $encrypted_7f426862c7c1_key -iv $encrypted_7f426862c7c1_iv -in ./test/test_config.json.enc -out ./test/test_config.json -d
6 |
7 | script:
8 | - carthage update HTMLSpecialCharacters MiniKeychain --platform ios --no-use-binaries
9 | - xcodebuild test -project reddift.xcodeproj -scheme reddift-iOS -configuration Debug -sdk iphonesimulator -destination "platform=iOS Simulator,name=iPhone 8" CODE_SIGNING_REQUIRED=NO
10 |
11 | branches:
12 | only:
13 | - master
--------------------------------------------------------------------------------
/Cartfile:
--------------------------------------------------------------------------------
1 | github "Flipboard/FLAnimatedImage"
2 | github "sonsongithub/UZTextView"
3 | github "sonsongithub/YouTubeGetVideoInfoAPIParser"
4 | github "sonsongithub/HTMLSpecialCharacters"
5 | github "sonsongithub/MiniKeychain"
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 sonson
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 |
23 |
--------------------------------------------------------------------------------
/application/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | }
43 | ],
44 | "info" : {
45 | "version" : 1,
46 | "author" : "xcode"
47 | }
48 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/account.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "account.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "account@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "account@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/account.imageset/account.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/account.imageset/account.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/account.imageset/account@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/account.imageset/account@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/account.imageset/account@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/account.imageset/account@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/action.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "action.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "action@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "action@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/action.imageset/action.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/action.imageset/action.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/action.imageset/action@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/action.imageset/action@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/action.imageset/action@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/action.imageset/action@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/back.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "back.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "back@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "back@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/back.imageset/back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/back.imageset/back.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/back.imageset/back@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/back.imageset/back@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/back.imageset/back@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/back.imageset/back@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/backOnBarButton.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "backOnBarButton.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "backOnBarButton@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "backOnBarButton@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/backOnBarButton.imageset/backOnBarButton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/backOnBarButton.imageset/backOnBarButton.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/backOnBarButton.imageset/backOnBarButton@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/backOnBarButton.imageset/backOnBarButton@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/backOnBarButton.imageset/backOnBarButton@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/backOnBarButton.imageset/backOnBarButton@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/bookmark.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "bookmark.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "bookmark@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "bookmark@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/bookmark.imageset/bookmark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/bookmark.imageset/bookmark.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/bookmark.imageset/bookmark@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/bookmark.imageset/bookmark@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/bookmark.imageset/bookmark@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/bookmark.imageset/bookmark@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/categoryList.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "categoryList.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "categoryList@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "categoryList@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/categoryList.imageset/categoryList.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/categoryList.imageset/categoryList.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/categoryList.imageset/categoryList@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/categoryList.imageset/categoryList@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/categoryList.imageset/categoryList@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/categoryList.imageset/categoryList@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/comments.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "comments.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "comments@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "comments@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/comments.imageset/comments.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/comments.imageset/comments.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/comments.imageset/comments@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/comments.imageset/comments@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/comments.imageset/comments@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/comments.imageset/comments@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/commentsFill.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "commentsFill.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "commentsFill@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "commentsFill@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/commentsFill.imageset/commentsFill.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/commentsFill.imageset/commentsFill.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/commentsFill.imageset/commentsFill@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/commentsFill.imageset/commentsFill@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/commentsFill.imageset/commentsFill@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/commentsFill.imageset/commentsFill@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/compose.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "compose.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "compose@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "compose@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/compose.imageset/compose.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/compose.imageset/compose.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/compose.imageset/compose@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/compose.imageset/compose@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/compose.imageset/compose@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/compose.imageset/compose@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/crown.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "crown.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "crown@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "crown@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/crown.imageset/crown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/crown.imageset/crown.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/crown.imageset/crown@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/crown.imageset/crown@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/crown.imageset/crown@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/crown.imageset/crown@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/downVote.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "downVote.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "downVote@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "downVote@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/downVote.imageset/downVote.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/downVote.imageset/downVote.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/downVote.imageset/downVote@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/downVote.imageset/downVote@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/downVote.imageset/downVote@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/downVote.imageset/downVote@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/downVoteFill.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "downVoteFill.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "downVoteFill@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "downVoteFill@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/downVoteFill.imageset/downVoteFill.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/downVoteFill.imageset/downVoteFill.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/downVoteFill.imageset/downVoteFill@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/downVoteFill.imageset/downVoteFill@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/downVoteFill.imageset/downVoteFill@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/downVoteFill.imageset/downVoteFill@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/error.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "error.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "error@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "error@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/error.imageset/error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/error.imageset/error.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/error.imageset/error@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/error.imageset/error@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/error.imageset/error@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/error.imageset/error@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/expand.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "expand.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "expand@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "expand@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/expand.imageset/expand.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/expand.imageset/expand.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/expand.imageset/expand@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/expand.imageset/expand@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/expand.imageset/expand@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/expand.imageset/expand@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/fold.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "fold.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "fold@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "fold@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/fold.imageset/fold.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/fold.imageset/fold.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/fold.imageset/fold@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/fold.imageset/fold@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/fold.imageset/fold@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/fold.imageset/fold@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/folder.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "folder.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "folder@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "folder@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/folder.imageset/folder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/folder.imageset/folder.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/folder.imageset/folder@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/folder.imageset/folder@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/folder.imageset/folder@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/folder.imageset/folder@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/forward.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "forward.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "forward@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "forward@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/forward.imageset/forward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/forward.imageset/forward.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/forward.imageset/forward@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/forward.imageset/forward@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/forward.imageset/forward@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/forward.imageset/forward@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/link.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "link.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "link@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "link@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/link.imageset/link.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/link.imageset/link.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/link.imageset/link@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/link.imageset/link@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/link.imageset/link@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/link.imageset/link@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/mailbox.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "mailbox.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "mailbox@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "mailbox@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/mailbox.imageset/mailbox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/mailbox.imageset/mailbox.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/mailbox.imageset/mailbox@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/mailbox.imageset/mailbox@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/mailbox.imageset/mailbox@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/mailbox.imageset/mailbox@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/newsokurFolder.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "newsokurFolder.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "newsokurFolder@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "newsokurFolder@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/newsokurFolder.imageset/newsokurFolder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/newsokurFolder.imageset/newsokurFolder.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/newsokurFolder.imageset/newsokurFolder@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/newsokurFolder.imageset/newsokurFolder@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/newsokurFolder.imageset/newsokurFolder@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/newsokurFolder.imageset/newsokurFolder@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/playButton.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "playButton.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "playButton@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "playButton@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/playButton.imageset/playButton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/playButton.imageset/playButton.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/playButton.imageset/playButton@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/playButton.imageset/playButton@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/playButton.imageset/playButton@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/playButton.imageset/playButton@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/ranking.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "ranking.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "ranking@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "ranking@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/ranking.imageset/ranking.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/ranking.imageset/ranking.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/ranking.imageset/ranking@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/ranking.imageset/ranking@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/ranking.imageset/ranking@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/ranking.imageset/ranking@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/reply.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "reply.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "reply@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "reply@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/reply.imageset/reply.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/reply.imageset/reply.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/reply.imageset/reply@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/reply.imageset/reply@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/reply.imageset/reply@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/reply.imageset/reply@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/report.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "report.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "report@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "report@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/report.imageset/report.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/report.imageset/report.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/report.imageset/report@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/report.imageset/report@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/report.imageset/report@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/report.imageset/report@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/sample.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "sample.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/sample.imageset/sample.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/sample.imageset/sample.jpg
--------------------------------------------------------------------------------
/application/Assets.xcassets/save.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "save.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "save@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "save@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/save.imageset/save.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/save.imageset/save.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/save.imageset/save@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/save.imageset/save@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/save.imageset/save@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/save.imageset/save@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/saveFill.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "saveFill.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "saveFill@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "saveFill@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/saveFill.imageset/saveFill.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/saveFill.imageset/saveFill.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/saveFill.imageset/saveFill@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/saveFill.imageset/saveFill@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/saveFill.imageset/saveFill@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/saveFill.imageset/saveFill@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/send.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "send.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "send@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "send@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/send.imageset/send.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/send.imageset/send.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/send.imageset/send@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/send.imageset/send@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/send.imageset/send@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/send.imageset/send@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/setting.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "setting.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "setting@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "setting@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/setting.imageset/setting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/setting.imageset/setting.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/setting.imageset/setting@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/setting.imageset/setting@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/setting.imageset/setting@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/setting.imageset/setting@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/subredditList.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "subredditList.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "subredditList@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "subredditList@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/subredditList.imageset/subredditList.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/subredditList.imageset/subredditList.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/subredditList.imageset/subredditList@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/subredditList.imageset/subredditList@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/subredditList.imageset/subredditList@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/subredditList.imageset/subredditList@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/tab.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "tab.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "tab@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "tab@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/tab.imageset/tab.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/tab.imageset/tab.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/tab.imageset/tab@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/tab.imageset/tab@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/tab.imageset/tab@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/tab.imageset/tab@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/tabbarFolder.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "tabbarFolder.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "tabbarFolder@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "tabbarFolder@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/tabbarFolder.imageset/tabbarFolder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/tabbarFolder.imageset/tabbarFolder.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/tabbarFolder.imageset/tabbarFolder@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/tabbarFolder.imageset/tabbarFolder@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/tabbarFolder.imageset/tabbarFolder@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/tabbarFolder.imageset/tabbarFolder@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/tabbarList.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "tabbarList.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "tabbarList@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "tabbarList@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/tabbarList.imageset/tabbarList.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/tabbarList.imageset/tabbarList.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/tabbarList.imageset/tabbarList@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/tabbarList.imageset/tabbarList@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/tabbarList.imageset/tabbarList@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/tabbarList.imageset/tabbarList@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/tabbarNewsokur.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "tabbarNewsokur.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "tabbarNewsokur@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "tabbarNewsokur@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/tabbarNewsokur.imageset/tabbarNewsokur.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/tabbarNewsokur.imageset/tabbarNewsokur.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/tabbarNewsokur.imageset/tabbarNewsokur@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/tabbarNewsokur.imageset/tabbarNewsokur@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/tabbarNewsokur.imageset/tabbarNewsokur@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/tabbarNewsokur.imageset/tabbarNewsokur@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/tabbarRanking.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "tabbarRanking.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "tabbarRanking@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "tabbarRanking@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/tabbarRanking.imageset/tabbarRanking.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/tabbarRanking.imageset/tabbarRanking.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/tabbarRanking.imageset/tabbarRanking@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/tabbarRanking.imageset/tabbarRanking@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/tabbarRanking.imageset/tabbarRanking@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/tabbarRanking.imageset/tabbarRanking@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/trend.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "trend.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "trend@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "trend@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/trend.imageset/trend.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/trend.imageset/trend.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/trend.imageset/trend@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/trend.imageset/trend@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/trend.imageset/trend@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/trend.imageset/trend@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/upVote.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "upVote.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "upVote@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "upVote@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/upVote.imageset/upVote.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/upVote.imageset/upVote.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/upVote.imageset/upVote@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/upVote.imageset/upVote@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/upVote.imageset/upVote@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/upVote.imageset/upVote@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/upVoteFill.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "upVoteFill.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "upVoteFill@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "upVoteFill@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/upVoteFill.imageset/upVoteFill.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/upVoteFill.imageset/upVoteFill.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/upVoteFill.imageset/upVoteFill@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/upVoteFill.imageset/upVoteFill@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/upVoteFill.imageset/upVoteFill@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/upVoteFill.imageset/upVoteFill@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/update.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "update.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "update@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "update@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/update.imageset/update.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/update.imageset/update.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/update.imageset/update@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/update.imageset/update@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/update.imageset/update@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/update.imageset/update@3x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/vote.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "vote.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "vote@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "vote@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/application/Assets.xcassets/vote.imageset/vote.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/vote.imageset/vote.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/vote.imageset/vote@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/vote.imageset/vote@2x.png
--------------------------------------------------------------------------------
/application/Assets.xcassets/vote.imageset/vote@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/Assets.xcassets/vote.imageset/vote@3x.png
--------------------------------------------------------------------------------
/application/Base.lproj/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
21 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/application/CommentContainable.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CommentContainable.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2016/09/29.
6 | // Copyright © 2016年 sonson. All rights reserved.
7 | //
8 |
9 | import reddift
10 | import Foundation
11 |
12 | class CommentContainable: ThingContainable, ImageDownloadable {
13 | var depth: Int
14 | var isCollapsed: Bool = false
15 | var isLoading: Bool = false
16 | var numberOfChildren: Int = 0
17 | var isTop = false
18 |
19 | init(with thing: Thing, depth: Int) {
20 | self.depth = depth
21 | super.init(with: thing)
22 | }
23 |
24 | /// Method to download attional contents or images when the cell is updated.
25 | func downloadImages() {
26 | }
27 |
28 | func layout(with width: CGFloat, fontSize: CGFloat) {
29 | }
30 |
31 | static func createContainer(with object: Thing, depth: Int, width: CGFloat, fontSize: CGFloat = 14) throws -> CommentContainable {
32 | if let comment = object as? Comment {
33 | return CommentContainer(with: comment, depth: depth, width: width)
34 | } else if let more = object as? More {
35 | return MoreContainer(with: more, depth: depth)
36 | } else {
37 | throw NSError(domain: "a", code: 0, userInfo: nil)
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/application/FromFieldView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FromFieldView.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2016/12/12.
6 | // Copyright © 2016年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | protocol FromFieldViewDelegate {
12 | func didTapFromFieldView(sender: FromFieldView)
13 | }
14 |
15 | class FromFieldView: PostFieldView {
16 | var delegate: FromFieldViewDelegate?
17 | let button = UIButton(type: .custom)
18 |
19 | override func setupSubviews() {
20 | super.setupSubviews()
21 | field.isEnabled = false
22 | let views = ["button": button]
23 | button.translatesAutoresizingMaskIntoConstraints = false
24 | self.addSubview(button)
25 | self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[button]-0-|", options: NSLayoutFormatOptions(), metrics: nil, views: views))
26 | self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[button]-0-|", options: NSLayoutFormatOptions(), metrics: nil, views: views))
27 | button.addTarget(self, action: #selector(FromFieldView.didTapButton(sender:)), for: .touchUpInside)
28 |
29 | if let name = UIApplication.appDelegate()?.session?.token?.name {
30 | field.text = name
31 | } else {
32 | field.text = "anonymous"
33 | }
34 |
35 | NotificationCenter.default.addObserver(self, selector: #selector(FromFieldView.didUpdateToken(notification:)), name: OAuth2TokenRepositoryDidUpdateTokenName, object: nil)
36 | }
37 |
38 | @objc func didUpdateToken(notification: NSNotification) {
39 | if let name = UIApplication.appDelegate()?.session?.token?.name {
40 | field.text = name
41 | } else {
42 | field.text = "anonymous"
43 | }
44 | }
45 |
46 | @objc func didTapButton(sender: Any) {
47 | if let delegate = delegate {
48 | delegate.didTapFromFieldView(sender: self)
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/application/ImageURLContainer.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ImageURLContainer.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2016/10/09.
6 | // Copyright © 2016年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | protocol ImageURLContainer {
12 | var sourceURL: URL { get set }
13 | var imageURL: [Thumbnail] { get set }
14 | }
15 |
16 | struct ImageURLInComment: ImageURLContainer {
17 | var sourceURL: URL
18 | var parentID: String
19 | var imageURL: [Thumbnail] = []
20 |
21 | init(sourceURL: URL, parentID: String) {
22 | self.sourceURL = sourceURL
23 | self.parentID = parentID
24 | imageURL = [Thumbnail.Image(imageURL: sourceURL, parentID: parentID)]
25 | }
26 | }
27 |
28 | struct ImgurURLInComment: ImageURLContainer {
29 | var sourceURL: URL
30 | var parentID: String
31 | var imageURL: [Thumbnail] = []
32 |
33 | init(sourceURL: URL, parentID: String) {
34 | let removed = sourceURL.deletingPathExtension()
35 | self.parentID = parentID
36 | self.sourceURL = removed
37 | }
38 | }
39 |
40 | struct MovieURLInComment: ImageURLContainer {
41 | var sourceURL: URL
42 | var parentID: String
43 | var imageURL: [Thumbnail] = []
44 |
45 | init(sourceURL: URL, thumbnailURL: URL, parentID: String) {
46 | self.parentID = parentID
47 | self.sourceURL = sourceURL
48 | self.imageURL = [Thumbnail.Movie(movieURL: sourceURL, thumbnailURL: thumbnailURL, parentID: parentID)]
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/application/ImgurLinkContainer.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ImgurLinkContainer.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2016/10/06.
6 | // Copyright © 2016年 sonson. All rights reserved.
7 | //
8 |
9 | import reddift
10 | import Foundation
11 |
12 | class ImgurLinkContainer: MediaLinkContainer {
13 |
14 | /// Shared session configuration
15 | var sessionConfiguration: URLSessionConfiguration {
16 | get {
17 | let configuration = URLSessionConfiguration.default
18 | configuration.timeoutIntervalForRequest = 30
19 | configuration.timeoutIntervalForResource = 30
20 | return configuration
21 | }
22 | }
23 |
24 | override init(link: Link, width: CGFloat, fontSize: CGFloat = 18, thumbnails: [Thumbnail]) {
25 | super.init(link: link, width: width, fontSize: fontSize, thumbnails: [])
26 | self.thumbnails = thumbnails
27 | let font = UIFont(name: UIFont.systemFont(ofSize: fontSize).fontName, size: fontSize) ?? UIFont.systemFont(ofSize: fontSize)
28 | attributedTitle = NSAttributedString(string: link.title).reconstruct(with: font, color: UIColor.black, linkColor: UIColor.blue)
29 | titleSize = ThumbnailLinkCell.estimateTitleSize(attributedString: attributedTitle, withBountWidth: width, margin: .zero)
30 | pageLoaded = false
31 | }
32 |
33 | override func prefetch(at: IndexPath) {
34 | if pageLoaded { return }
35 | guard let url = URL(string: link.url) else { return }
36 | let https_url = url.httpsSchemaURL
37 | var request = URLRequest(url: https_url)
38 | request.addValue("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/601.1.56 (KHTML, like Gecko) Version/9.0 Safari/601.1.56", forHTTPHeaderField: "User-Agent")
39 | let session: URLSession = URLSession(configuration: sessionConfiguration)
40 | let task = session.dataTask(with: request, completionHandler: { (data, _, error) -> Void in
41 | self.pageLoaded = true
42 | if let error = error {
43 | NotificationCenter.default.post(name: LinkContainerDidLoadImageName, object: nil, userInfo: ["error": error as NSError])
44 | }
45 | if let data = data, let decoded = String(data: data, encoding: .utf8) {
46 | if !decoded.is404OfImgurcom {
47 | self.thumbnails = decoded.extractImgurImageURL(parentID: self.link.id)
48 | DispatchQueue.main.async(execute: { () -> Void in
49 | NotificationCenter.default.post(name: LinkContainerDidLoadImageName, object: nil, userInfo: [MediaLinkContainerPrefetchAtIndexPathKey: at, MediaLinkContainerPrefetchContentKey: self])
50 | })
51 | }
52 | } else {
53 | NotificationCenter.default.post(name: LinkContainerDidLoadImageName, object: nil, userInfo: ["error": "can not decode html"])
54 | }
55 | })
56 | task.resume()
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/application/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | reddift
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleURLTypes
22 |
23 |
24 | CFBundleTypeRole
25 | Editor
26 | CFBundleURLName
27 | com.sonson.reddift
28 | CFBundleURLSchemes
29 |
30 | reddift
31 |
32 |
33 |
34 | CFBundleVersion
35 | 1
36 | LSRequiresIPhoneOS
37 |
38 | UILaunchStoryboardName
39 | LaunchScreen
40 | UIMainStoryboardFile
41 | Main
42 | UIRequiredDeviceCapabilities
43 |
44 | armv7
45 |
46 | UISupportedInterfaceOrientations
47 |
48 | UIInterfaceOrientationPortrait
49 | UIInterfaceOrientationLandscapeLeft
50 | UIInterfaceOrientationLandscapeRight
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/application/InvisibleCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // InvisibleCell.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2016/08/28.
6 | // Copyright © 2016年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | class InvisibleCell: UITableViewCell {
12 | }
13 |
--------------------------------------------------------------------------------
/application/LinkContainer.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LinkContainer.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2016/09/29.
6 | // Copyright © 2016年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | class LinkContainer: LinkContainable {
12 |
13 | /// Cell identifier for dequeueReusableCellWithIdentifier of FrontViewController class.
14 | override var cellIdentifier: String {
15 | get {
16 | if isHidden {
17 | return "InvisibleCell"
18 | } else {
19 | return "LinkCell"
20 | }
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/application/LinkContainerCellar.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LinkContainerCellar.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2016/10/05.
6 | // Copyright © 2016年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public let LinkContainerCellarDidLoadName = Notification.Name(rawValue: "LinkContainerCellarDidLoadName")
12 |
13 | class LinkContainerCellar {
14 | static let reloadIndicesKey = "ReloadIndices"
15 | static let insertIndicesKey = "InsertIndices"
16 | static let deleteIndicesKey = "DeleteIndices"
17 | static let errorKey = "Error"
18 | static let isAtTheBeginningKey = "atTheBeginning"
19 | static let providerKey = "Provider"
20 |
21 | var containers: [LinkContainable] = []
22 | var thumbnails: [Thumbnail] {
23 | get {
24 | return containers.flatMap({$0.thumbnails})
25 | }
26 | }
27 |
28 | func updateHidden() {
29 | for i in 0.. String { return "" }
46 | func loadingMessage() -> String { return "" }
47 | }
48 |
--------------------------------------------------------------------------------
/application/LoadingCommentCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LoadingCommentCell.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2016/03/14.
6 | // Copyright © 2016年 sonson. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class LoadingCommentCell: UITableViewCell {
12 | @IBOutlet var activityIndicator: UIActivityIndicatorView?
13 |
14 | override func awakeFromNib() {
15 | activityIndicator?.startAnimating()
16 | layoutMargins = UIEdgeInsets.zero
17 | separatorInset = UIEdgeInsets.zero
18 | selectionStyle = .none
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/application/LoadingCommentCell.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/application/MoreCommentCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MoreCommentCell.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2016/03/08.
6 | // Copyright © 2016年 sonson. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class MoreCommentCell: UITableViewCell {
12 | var moreContainer: MoreContainer? = nil {
13 | didSet {
14 | if let moreContainer = self.moreContainer {
15 | leftMarginVarticalBar?.constant = moreContainer.depth == 1 ? -CommentCell.verticalBarWidth : (CGFloat(moreContainer.depth) - 1) * CommentCell.verticalBarWidth
16 | }
17 | }
18 | }
19 |
20 | @IBOutlet var leftMarginVarticalBar: NSLayoutConstraint?
21 | @IBOutlet var widthOfVerticalBar: NSLayoutConstraint?
22 |
23 | override func awakeFromNib() {
24 | super.awakeFromNib()
25 | // Initialization code
26 | layoutMargins = UIEdgeInsets.zero
27 | separatorInset = UIEdgeInsets.zero
28 | widthOfVerticalBar?.constant = CommentCell.verticalBarWidth
29 | }
30 |
31 | override func setSelected(_ selected: Bool, animated: Bool) {
32 | super.setSelected(selected, animated: animated)
33 |
34 | // Configure the view for the selected state
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/application/MoreContainer.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MoreContainer.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2016/09/29.
6 | // Copyright © 2016年 sonson. All rights reserved.
7 | //
8 |
9 | import reddift
10 | import Foundation
11 |
12 | class MoreContainer: CommentContainable {
13 | internal var intrinsicMore: More
14 | var more: More {
15 | get {
16 | return intrinsicMore
17 | }
18 | }
19 |
20 | init(with more: More, depth: Int) {
21 | self.intrinsicMore = more
22 | super.init(with: more, depth: depth)
23 | }
24 |
25 | override var height: CGFloat {
26 | get {
27 | if isHidden {
28 | return 0
29 | }
30 | return 44
31 | }
32 | }
33 |
34 | override var intrinsicThing: Thing {
35 | didSet {
36 | DispatchQueue.main.async(execute: { () -> Void in
37 | if let more = self.intrinsicThing as? More {
38 | self.intrinsicMore = more
39 | NotificationCenter.default.post(name: ThingContainableDidUpdate, object: nil, userInfo: ["contents": self])
40 | }
41 | })
42 | }
43 | }
44 |
45 | override var cellIdentifier: String {
46 | get {
47 | if isHidden {
48 | return "InvisibleCell"
49 | }
50 | if isLoading {
51 | return "LoadingCell"
52 | }
53 | return "MoreCell"
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/application/MoviePlayerController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MoviePlayerController.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2016/10/22.
6 | // Copyright © 2016年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import AVKit
11 | import AVFoundation
12 |
13 | class MoviePlayerController: ImageViewController {
14 | let movieView: MoviePlayView
15 | let movieURL: URL
16 |
17 | @objc func didChangeStatus(notification: Notification) {
18 | var f = movieView.frame
19 | f.size = movieView.presentationSize
20 | movieView.frame = f
21 | updateImageCenter()
22 |
23 | let boundsSize = self.view.bounds
24 | var frameToCenter = movieView.frame
25 |
26 | let ratio = movieView.presentationSize.width / movieView.presentationSize.height
27 |
28 | var contentSize = CGSize.zero
29 |
30 | if ratio > 1 {
31 | contentSize = CGSize(width: boundsSize.width, height: boundsSize.height / ratio)
32 | } else {
33 | contentSize = CGSize(width: boundsSize.height * ratio, height: boundsSize.height)
34 | }
35 |
36 | frameToCenter.size = contentSize
37 | var f2 = mainImageView.bounds
38 | f2.origin = CGPoint.zero
39 | movieView.frame = f2
40 |
41 | if frameToCenter.size.width < boundsSize.width {
42 | frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width) / 2
43 | } else {
44 | frameToCenter.origin.x = 0
45 | }
46 | if frameToCenter.size.height < boundsSize.height {
47 | frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height) / 2
48 | } else {
49 | frameToCenter.origin.y = 0
50 | }
51 | movieView.playerLayer.player?.play()
52 | }
53 |
54 | override func viewDidLoad() {
55 | print("MovieViewController - viewDidLoad")
56 | super.viewDidLoad()
57 | mainImageView.addSubview(movieView)
58 | NotificationCenter.default.addObserver(self, selector: #selector(MoviePlayerController.didChangeStatus(notification:)), name: MoviePlayViewDidChangeStatus, object: nil)
59 | }
60 |
61 | required init?(coder aDecoder: NSCoder) {
62 | movieURL = URL(string: "")!
63 | movieView = MoviePlayView(url: movieURL)
64 | super.init(coder: aDecoder)
65 | }
66 |
67 | override init(index: Int, thumbnails: [Thumbnail], isOpenedBy3DTouch: Bool = false) {
68 | let thumbnail = thumbnails[index]
69 | switch thumbnail {
70 | case .Image:
71 | movieURL = URL(string: "")!
72 | case .Movie(let movieURL, _, _):
73 | self.movieURL = movieURL
74 | }
75 | movieView = MoviePlayView(url: movieURL)
76 | super.init(index: index, thumbnails: thumbnails, isOpenedBy3DTouch: isOpenedBy3DTouch)
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/application/NewsokurCategoryViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NewsokurCategoryViewController.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/12/27.
6 | // Copyright © 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | /**
12 | ViewController to browse ニュー速R list json which is downloaded from api.reddift.net.
13 | */
14 | class NewsokurCategoryViewController: SubredditListCategoryViewController {
15 |
16 | /// Set title for NewsokurCategoryViewController
17 | override init() {
18 | super.init(nibName: nil, bundle: nil)
19 | self.title = NSLocalizedString("ニュー速R", comment: "")
20 | }
21 |
22 | /// Set title for NewsokurCategoryViewController
23 | override init(nibName: String?, bundle: Bundle?) {
24 | super.init(nibName: nibName, bundle: bundle)
25 | self.title = NSLocalizedString("ニュー速R", comment: "")
26 | }
27 |
28 | /// Set title for NewsokurCategoryViewController
29 | required init?(coder: NSCoder) {
30 | super.init(coder: coder)
31 | self.title = NSLocalizedString("ニュー速R", comment: "")
32 | self.tabBarItem = UITabBarItem(title: NSLocalizedString("ニュー速R", comment: ""), image: UIImage(named: "newsokurFolder"), tag: 0)
33 | }
34 |
35 | /// Load json for ニュー速R.
36 | override func loadJSON() {
37 | let session: URLSession = URLSession(configuration: URLSessionConfiguration.default)
38 | guard let url = URL(string: "https://api.reddift.net/newsokur.json")
39 | else { return }
40 | let request = URLRequest(url: url)
41 | let task = session.dataTask(with: request, completionHandler: { (data: Data?, _, _) -> Void in
42 | if let data = data {
43 | (self.categoryLists, self.categoryTitles, self.lastUpdateDate) = SubredditListItem.ReddiftJSON2List(data: data as NSData, showsNSFW: true)
44 | }
45 | DispatchQueue.main.async(execute: { () -> Void in
46 | self.tableView.reloadData()
47 | })
48 | })
49 | task.resume()
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/application/PostFieldView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PostFieldView.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2016/12/12.
6 | // Copyright © 2016年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | class PostFieldView: UIView {
12 | let label = UILabel(frame: CGRect.zero)
13 | let field = UITextField(frame: CGRect.zero)
14 | let line = UIView(frame: CGRect.zero)
15 |
16 | override init(frame: CGRect) {
17 | super.init(frame: frame)
18 | setupSubviews()
19 | }
20 |
21 | required init?(coder aDecoder: NSCoder) {
22 | super.init(coder: aDecoder)
23 | setupSubviews()
24 | }
25 |
26 | func setupSubviews() {
27 | let views: [String: Any] = [
28 | "label": label,
29 | "line": line,
30 | "field": field
31 | ]
32 | label.text = "from"
33 | field.text = "aa"
34 | line.backgroundColor = UIColor.black
35 |
36 | label.translatesAutoresizingMaskIntoConstraints = false
37 | field.translatesAutoresizingMaskIntoConstraints = false
38 | line.translatesAutoresizingMaskIntoConstraints = false
39 |
40 | label.textAlignment = .right
41 | field.textAlignment = .left
42 |
43 | self.addSubview(label)
44 | self.addSubview(field)
45 | self.addSubview(line)
46 |
47 | self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-10-[label]-10-[field]-10-|", options: NSLayoutFormatOptions(), metrics: nil, views: views))
48 | self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[label]-0-|", options: NSLayoutFormatOptions(), metrics: nil, views: views))
49 | self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[field]-0-|", options: NSLayoutFormatOptions(), metrics: nil, views: views))
50 | self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[line]-0-|", options: NSLayoutFormatOptions(), metrics: nil, views: views))
51 | self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:[line(==0.5)]-0-|", options: NSLayoutFormatOptions(), metrics: nil, views: views))
52 | self.addConstraint(NSLayoutConstraint(item: label, attribute: .width, relatedBy: .equal, toItem: self, attribute: .width, multiplier: 0.1, constant: 0))
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/application/ReddiftAPPError.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ReddiftAPPError.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2016/07/28.
6 | // Copyright © 2016年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public enum ReddiftAPPError: Int, Error {
12 | case unknown
13 |
14 | /// thumbnail
15 | case cachedImageFileIsNotFound
16 | case canNotCreateURLFromImageURLString
17 | case canNotCreateFilePathFromImageFileURL
18 | case canNotCreateThumbnailImageFromOriginalImage
19 | case canNotCreateImageFromData
20 | case canNotCreatePNGImageDataFromUIImage
21 | case canNotCreateURLStringFromURL
22 | case canNotAcceptDataFromServer
23 | case canNotGetImageViewForSpecifiedImageURL
24 | }
25 |
--------------------------------------------------------------------------------
/application/ReddiftTextView.h:
--------------------------------------------------------------------------------
1 | //
2 | // UZTextView.h
3 | // Text
4 | //
5 | // Created by sonson on 2013/06/13.
6 | // Copyright (c) 2013年 sonson. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @class ReddiftTextView;
13 |
14 | @protocol ReddiftTextViewDelegate
15 | @end
16 |
17 | @interface ReddiftTextView : UZTextView {
18 | BOOL _isPushedUIMenuController;
19 | }
20 | @property (nonatomic, assign) id UZDelegate;
21 | @end
22 |
--------------------------------------------------------------------------------
/application/ReddiftTextView.m:
--------------------------------------------------------------------------------
1 | //
2 | // UZTextView.m
3 | // Text
4 | //
5 | // Created by sonson on 2013/06/13.
6 | // Copyright (c) 2013年 sonson. All rights reserved.
7 | //
8 |
9 | #import "ReddiftTextView.h"
10 |
11 | #import
12 |
13 | #define TAP_MARGIN 15
14 |
15 | @implementation ReddiftTextView
16 |
17 | #pragma mark - dealloc
18 |
19 | - (void)dealloc {
20 | [[NSNotificationCenter defaultCenter] removeObserver:self];
21 | }
22 |
23 | #pragma mark - for UIMenuController
24 |
25 | /**
26 | * UIMenuControllerのアクションメソッド.
27 | * 選択されているテキストをクリップボードにコピーする.
28 | * @param sender メソッドの呼び出し元.おそらくUIMenuControllerオブジェクト.
29 | **/
30 | - (void)copy:(id)sender {
31 | [self resignFirstResponder];
32 | }
33 |
34 | /**
35 | * UIMenuControllerのアクションメソッド.
36 | * 選択されているテキストでfind2chのスレッドタイトル検索を実行する.
37 | * 実行するとブックマークビューが開かれる.
38 | * @param sender メソッドの呼び出し元.おそらくUIMenuControllerオブジェクト.
39 | **/
40 | - (void)titleSearch:(id)sender {
41 | [self resignFirstResponder];
42 | }
43 |
44 | /**
45 | * UIMenuControllerのアクションメソッド.
46 | * 選択されているテキストでスレッド内部検索を実行する.
47 | * 実行するとブックマークビューが開かれる.
48 | * @param sender メソッドの呼び出し元.おそらくUIMenuControllerオブジェクト.
49 | **/
50 | - (void)threadSearch:(id)sender {
51 | [self resignFirstResponder];
52 | }
53 |
54 | /**
55 | * UIMenuControllerのアクションメソッド.
56 | * 選択されているテキストでGoogle検索を実行する.
57 | * 実行するとWebViewコントローラが開かれる.
58 | * @param sender メソッドの呼び出し元.おそらくUIMenuControllerオブジェクト.
59 | **/
60 | - (void)google:(id)sender {
61 | [self resignFirstResponder];
62 | }
63 |
64 | /**
65 | * UIMenuControllerのアクションメソッド.
66 | * 選択されているテキストをNG IDに追加する.
67 | * @param sender メソッドの呼び出し元.おそらくUIMenuControllerオブジェクト.
68 | **/
69 | - (void)addNGID:(id)sender {
70 | [self resignFirstResponder];
71 | // NSString *text = [self.attributedString.string substringWithRange:self.selectedRange];
72 | // NSString *boardTitle = _res.thread.threadInfo.boardInfo.title;
73 | // [[C2CloudDataManager sharedInstance] addNGIDWithIdentifier:text
74 | // board:_res.thread.threadInfo.boardInfo.board
75 | // boardTitle:boardTitle
76 | // threadTitle:_res.thread.title
77 | // number:@(_res.thread.threadInfo.dat)
78 | // applyToAll:[[NSUserDefaults standardUserDefaults] boolForKey:C2UserDefaultsNGApplyAllThreadsKey]];
79 | }
80 |
81 | /**
82 | * UIMenuControllerのアクションメソッド.
83 | * 選択されているテキストをNGネームに追加する.
84 | * @param sender メソッドの呼び出し元.おそらくUIMenuControllerオブジェクト.
85 | **/
86 | - (void)addNGName:(id)sender {
87 | [self resignFirstResponder];
88 | }
89 |
90 | /**
91 | * UIMenuControllerのアクションメソッド.
92 | * 選択されているテキストをNGワードに追加する.
93 | * @param sender メソッドの呼び出し元.おそらくUIMenuControllerオブジェクト.
94 | **/
95 | - (void)addNGWord:(id)sender {
96 | [self resignFirstResponder];
97 | }
98 |
99 | /**
100 | * UIMenuControllerのアクションメソッド.
101 | * ビューに含まれるすべてのテキストを選択状態にする.
102 | * @param sender メソッドの呼び出し元.おそらくUIMenuControllerオブジェクト.
103 | **/
104 | - (void)selectAll:(id)sender {
105 | [self setSelectedRange:NSMakeRange(0, self.attributedString.length)];
106 | }
107 |
108 | #pragma mark - Override
109 |
110 | - (void)prepareForInitialization {
111 | [super prepareForInitialization];
112 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didStartSelection:) name:@"didStartSelection" object:nil];
113 | }
114 |
115 | - (void)didStartSelection:(NSNotification*)notification {
116 | if (notification.object != self) {
117 | [self cancelSelectedText];
118 | }
119 | }
120 |
121 | - (BOOL)canBecomeFirstResponder {
122 | return YES;
123 | }
124 |
125 | - (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
126 | if (action == @selector(titleSearch:))
127 | return YES;
128 | if (action == @selector(google:))
129 | return YES;
130 | if (action == @selector(threadSearch:))
131 | return YES;
132 | if (action == @selector(copy:))
133 | return YES;
134 | if (action == @selector(addNGID:))
135 | return YES;
136 | if (action == @selector(addNGName:))
137 | return YES;
138 | if (action == @selector(addNGWord:))
139 | return YES;
140 | if (action == @selector(selectAll:))
141 | return YES;
142 | return NO;
143 | }
144 |
145 | @end
146 |
--------------------------------------------------------------------------------
/application/SearchLinkCellar.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SearchLinkCellar.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2016/10/07.
6 | // Copyright © 2016年 sonson. All rights reserved.
7 | //
8 |
9 | import reddift
10 | import Foundation
11 |
12 | class SearchLinkCellar: SubredditCellar {
13 | /// Query for Link search
14 | var query: String
15 |
16 | override func tryLoadingMessage() -> String {
17 | return "Try search with \(query)"
18 | }
19 |
20 | override func loadingMessage() -> String {
21 | return "Searching with \(query)...."
22 | }
23 |
24 | /**
25 | Initialize SearchLinkCellar.
26 | - parameter subredditName: To be written.
27 | - parameter delegate: To be written.
28 | - returns: To be written.
29 | */
30 | init(query aQuery: String, subreddit name: String?, width: CGFloat, fontSize: CGFloat) {
31 | query = aQuery
32 | super.init()
33 | self.width = width
34 | self.fontSize = fontSize
35 | if let name = name {
36 | subreddit = Subreddit(subreddit: name)
37 | }
38 | }
39 |
40 | /**
41 | Search contents.
42 | - parameter appending: To be written.
43 | - parameter width: To be written.
44 | */
45 | override func load(atTheBeginning: Bool) {
46 | /// Do nothing in case paginator is vacant and load subreddit to append contents.
47 | if self.paginator.isVacant && !atTheBeginning { return }
48 | /// Do nothing in case this controller is loading.
49 | if loading { return }
50 | do {
51 | loading = true
52 | try UIApplication.appDelegate()?.session?.getSearch(subreddit, query: query, paginator: paginator, sort: .new, completion: { (result) -> Void in
53 | switch result {
54 | case .failure(let error):
55 | /// Callback
56 | self.postNotification(name: LinkContainerCellarDidLoadName, userInfo: [LinkContainerCellar.errorKey: error, LinkContainerCellar.providerKey: self])
57 | case .success(let listing):
58 | /// Clear all objects before load content from the beginning.
59 | if atTheBeginning { self.removeAllObjects() }
60 |
61 | /// append new contents to self
62 | self.appendContentWithListing(listing: listing, widthConstraint: self.width, atTheBeginning: atTheBeginning)
63 | }
64 | })
65 | } catch {
66 | let nserror = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "\(error)"])
67 | postNotification(name: LinkContainerCellarDidLoadName, userInfo: [LinkContainerCellar.errorKey: nserror, LinkContainerCellar.providerKey: self])
68 | }
69 | }
70 |
71 | }
72 |
--------------------------------------------------------------------------------
/application/SubredditListCategoryTargetType.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SubredditListCategoryTargetType.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2016/08/11.
6 | // Copyright © 2016年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /**
12 | "Safe For Work" flag type.
13 | This type is used for creating title for view controller, tab bar title and URL for json.
14 | This type has NSFW and SFW.
15 | */
16 | enum SubredditListCategoryTargetType {
17 | case NSFW
18 | case SFW
19 |
20 | init(viewController: SubredditListCategoryViewController) {
21 | if viewController.isKind(of: SubredditListNSFWCategoryViewController.self) {
22 | self = .NSFW
23 | } else if viewController.isKind(of: SubredditListSFWCategoryViewController.self) {
24 | self = .SFW
25 | } else {
26 | self = .SFW
27 | }
28 | }
29 |
30 | var tabbarTitle: String {
31 | switch self {
32 | case .NSFW:
33 | return "Category NSFW"
34 | case .SFW:
35 | return "Category SFW"
36 | }
37 | }
38 |
39 | var title: String {
40 | switch self {
41 | case .NSFW:
42 | return "NSFW"
43 | case .SFW:
44 | return "SFW"
45 | }
46 | }
47 |
48 | var url: URL {
49 | switch self {
50 | case .NSFW:
51 | return URL(string: "https://api.reddift.net/nsfw_category_map.json")!
52 | case .SFW:
53 | return URL(string: "https://api.reddift.net/sfw_category_map.json")!
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/application/SubredditListRankingOrderType.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SubredditListRankingOrderType.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2016/08/11.
6 | // Copyright © 2016年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /**
12 | Order type of ranking data at redditlist.com.
13 | There are three order types.
14 | */
15 | enum SubredditListRankingOrderType {
16 | /// Sort by a number of recent activities of the subreddit.
17 | case RecentActivity
18 | /// Sort by a number of subscribers of the subreddit.
19 | case Subscriber
20 | /// Sort by a rate of growth of subscribers of the subreddit.
21 | case Growth
22 |
23 | /// Title for view controller
24 | var title: String {
25 | switch self {
26 | case .RecentActivity:
27 | return "Recent Activity"
28 | case .Subscriber:
29 | return "SUM"
30 | case .Growth:
31 | return "Growth"
32 | }
33 | }
34 |
35 | /// json key for array value.
36 | var jsonKey: String {
37 | switch self {
38 | case .RecentActivity:
39 | return "Recent Activity"
40 | case .Subscriber:
41 | return "Subscribers"
42 | case .Growth:
43 | return "Growth (24Hrs)"
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/application/SubredditListRankingTargetType.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SubredditListRankingTargetType.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2016/08/11.
6 | // Copyright © 2016年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /**
12 | "Safe For Work" flag type of ranking data at redditlist.com.
13 | This type is used for creating title for view controller, tab bar title and URL for json.
14 | This type has NSFW, SFW and all.
15 | */
16 | enum SubredditListRankingTargetType {
17 | case All
18 | case NSFW
19 | case SFW
20 |
21 | init(viewController: SubredditListRankingViewController) {
22 | if viewController.isKind(of: SubredditListAllRankingViewController.self) {
23 | self = .All
24 | } else if viewController.isKind(of: SubredditListNSFWRankingViewController.self) {
25 | self = .NSFW
26 | } else if viewController.isKind(of: SubredditListSFWRankingViewController.self) {
27 | self = .SFW
28 | } else {
29 | self = .All
30 | }
31 | }
32 |
33 | var tabbarTitle: String {
34 | switch self {
35 | case .All:
36 | return "Ranking - All"
37 | case .NSFW:
38 | return "Ranking - NSFW"
39 | case .SFW:
40 | return "Ranking - SFW"
41 | }
42 | }
43 |
44 | var title: String {
45 | switch self {
46 | case .All:
47 | return "Ranking - All subreddits"
48 | case .NSFW:
49 | return "Ranking - NSFW subreddits"
50 | case .SFW:
51 | return "Ranking - SFW subreddits"
52 | }
53 | }
54 |
55 | var url: URL {
56 | switch self {
57 | case .All:
58 | return URL(string: "https://api.reddift.net/all_ranking.json")!
59 | case .NSFW:
60 | return URL(string: "https://api.reddift.net/nsfw_ranking.json")!
61 | case .SFW:
62 | return URL(string: "https://api.reddift.net/sfw_ranking.json")!
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/application/SubredditListViewCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SubredditListViewCell.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/12/29.
6 | // Copyright © 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | /**
12 | Cell for SubredditListViewController.
13 | It displays a subreddit title.
14 | */
15 | class SubredditListViewSubtitleCell: UITableViewCell {
16 | override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
17 | super.init(style: UITableViewCellStyle.subtitle, reuseIdentifier: reuseIdentifier)
18 | }
19 |
20 | required init?(coder: NSCoder) {
21 | super.init(coder: coder)
22 | }
23 | }
24 |
25 | /**
26 | Cell for SubredditListCategoryViewController and SubredditListRankingViewController.
27 | It displays two values. Left title's color is black and right one is light gray.
28 | */
29 | class SubredditListViewRightValueCell: UITableViewCell {
30 | override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
31 | super.init(style: UITableViewCellStyle.value1, reuseIdentifier: reuseIdentifier)
32 | }
33 |
34 | required init?(coder: NSCoder) {
35 | super.init(coder: coder)
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/application/SubredditListViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SubredditListCategoryViewController.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/10/26.
6 | // Copyright © 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | /**
12 | View controller to show subreddits that are obtained from redditlist.com or api.reddift.com.
13 | This controller is used newsokur and hierarchical list of redditlist.com.
14 | */
15 | class SubredditListViewController: UITableViewController {
16 | var list: [SubredditListItem] = []
17 |
18 | @IBAction func close(sender: AnyObject) {
19 | dismiss(animated: true, completion: nil)
20 | }
21 |
22 | override func viewDidLoad() {
23 | super.viewDidLoad()
24 | tableView.register(SubredditListViewSubtitleCell.self, forCellReuseIdentifier: "Cell")
25 | let barbutton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(SubredditListViewController.close(sender:)))
26 | self.navigationItem.rightBarButtonItem = barbutton
27 | }
28 |
29 | override func numberOfSections(in tableView: UITableView) -> Int {
30 | return 1
31 | }
32 |
33 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
34 | return list.count
35 | }
36 |
37 | override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
38 | return 44
39 | }
40 |
41 | override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
42 | let item = list[indexPath.row]
43 | NotificationCenter.default.post(name: SubredditSelectTabBarControllerDidOpenSubredditName, object: nil, userInfo: ["subreddit": item.subreddit])
44 | dismiss(animated: true, completion: nil)
45 | }
46 |
47 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
48 | let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath as IndexPath)
49 |
50 | let item = list[indexPath.row]
51 | if let cell = cell as? SubredditListViewSubtitleCell {
52 | cell.textLabel?.text = item.subreddit
53 | cell.detailTextLabel?.text = item.title
54 | cell.detailTextLabel?.textColor = UIColor.gray
55 | }
56 |
57 | return cell
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/application/SubredditSelectTabBarController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SubredditSelectViewController.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/12/14.
6 | // Copyright © 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | let SubredditSelectTabBarControllerDidOpenSubredditName = Notification.Name(rawValue: "SubredditSelectTabBarControllerDidOpenSubredditName")
12 |
13 | /**
14 | View controller to select a favorite subreddit among list.
15 | The list is generated from reddit
16 | This view controller is shown when right bar bottom item is pushed.
17 | */
18 | class SubredditSelectTabBarController: UITabBarController {
19 |
20 | /**
21 | Show view controllers acording to the NSFW flag.
22 | */
23 | override func viewDidLoad() {
24 | super.viewDidLoad()
25 | let showsNSFW = true
26 | var navigationControllers: [UIViewController] = []
27 | let viewControllers: [(UIViewController, Bool)] = [
28 | (NewsokurCategoryViewController(), showsNSFW),
29 | (SubredditListNSFWCategoryViewController(), showsNSFW),
30 | (SubredditListSFWCategoryViewController(), true),
31 | (SubredditListAllRankingViewController(), showsNSFW),
32 | (SubredditListNSFWRankingViewController(), true),
33 | (SubredditListSFWRankingViewController(), true)
34 | ]
35 | viewControllers.forEach { (vc, flag) in
36 | if flag {
37 | navigationControllers.append(UINavigationController(rootViewController: vc))
38 | }
39 | }
40 | self.viewControllers = navigationControllers
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/application/SubredditSelectViewController.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/application/TabViewCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TabViewCell.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/10/28.
6 | // Copyright © 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension NSLayoutConstraint {
12 |
13 | func setMultiplier(multiplier: CGFloat) {
14 |
15 | let newConstraint = NSLayoutConstraint(
16 | item: firstItem as Any,
17 | attribute: firstAttribute,
18 | relatedBy: relation,
19 | toItem: secondItem,
20 | attribute: secondAttribute,
21 | multiplier: multiplier,
22 | constant: constant)
23 |
24 | newConstraint.priority = priority
25 | newConstraint.shouldBeArchived = self.shouldBeArchived
26 | newConstraint.identifier = self.identifier
27 | newConstraint.isActive = self.isActive
28 |
29 | NSLayoutConstraint.deactivate([self])
30 | NSLayoutConstraint.activate([newConstraint])
31 | }
32 | }
33 |
34 | class TabViewCell: UICollectionViewCell {
35 | @IBOutlet var screenImageView: UIImageView?
36 | @IBOutlet var numberLabel: UILabel?
37 | @IBOutlet var widthRatio: NSLayoutConstraint?
38 | @IBOutlet var aspectRatio: NSLayoutConstraint?
39 |
40 | override func awakeFromNib() {
41 | super.awakeFromNib()
42 | if let size = UIApplication.shared.keyWindow?.rootViewController?.view.frame.size {
43 | let ratio = size.width / (size.height)
44 | widthRatio?.setMultiplier(multiplier: 0.95)
45 | aspectRatio?.setMultiplier(multiplier: ratio)
46 | }
47 | }
48 |
49 | override func prepareForReuse() {
50 | super.prepareForReuse()
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/application/ThingContainable.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ThingContainable.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2016/09/29.
6 | // Copyright © 2016年 sonson. All rights reserved.
7 | //
8 |
9 | import reddift
10 | import Foundation
11 |
12 | let ThingContainableDidUpdate = Notification.Name(rawValue: "ThingContainableDidUpdate")
13 |
14 | class ThingContainable {
15 | internal var intrinsicThing: Thing
16 | var thing: Thing {
17 | get {
18 | return intrinsicThing
19 | }
20 | }
21 |
22 | init(with aThing: Thing) {
23 | intrinsicThing = aThing
24 | }
25 |
26 | var cellIdentifier: String {
27 | return "InvisibleCell"
28 | }
29 |
30 | var height: CGFloat {
31 | return 0
32 |
33 | }
34 |
35 | var isHidden: Bool = false
36 |
37 | // update
38 | func update() {
39 | do {
40 | try UIApplication.appDelegate()?.session?.getInfo([self.thing.name], completion: { (result) in
41 | switch result {
42 | case .failure(let error):
43 | print(error)
44 | case .success(let listing):
45 | if listing.children.count == 1 {
46 | self.intrinsicThing = listing.children[0]
47 | DispatchQueue.main.async(execute: { () -> Void in
48 | NotificationCenter.default.post(name: ThingContainableDidUpdate, object: nil, userInfo: ["contents": self])
49 | })
50 | }
51 | }
52 | })
53 | } catch { print(error) }
54 | }
55 |
56 | // hide
57 | func hide() {
58 | do {
59 | try UIApplication.appDelegate()?.session?.setHide(true, name: self.thing.name, completion: { (result) in
60 | switch result {
61 | case .failure(let error):
62 | print(error)
63 | case .success:
64 | self.update()
65 | }
66 | })
67 | } catch { print(error) }
68 | }
69 |
70 | // report
71 | func report() {
72 | do {
73 | try UIApplication.appDelegate()?.session?.report(self.thing, reason: "", otherReason: "", completion: { (result) in
74 | switch result {
75 | case .failure(let error):
76 | print(error)
77 | case .success(let obj):
78 | print(obj)
79 | }
80 | })
81 | } catch { print(error) }
82 | }
83 |
84 | // vote
85 | func vote(voteDirection: VoteDirection) {
86 | do {
87 | try UIApplication.appDelegate()?.session?.setVote(voteDirection, name: self.thing.name, completion: { (result) in
88 | switch result {
89 | case .failure(let error):
90 | print(error)
91 | case .success:
92 | self.update()
93 | }
94 | })
95 | } catch { print(error) }
96 | }
97 |
98 | // save
99 | func save(saved: Bool) {
100 | do {
101 | try UIApplication.appDelegate()?.session?.setSave(saved, name: self.thing.name, completion: { (result) in
102 | switch result {
103 | case .failure(let error):
104 | print(error)
105 | case .success:
106 | self.update()
107 | }
108 | })
109 | } catch { print(error) }
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/application/Thumbnail.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Thumbnail.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2016/03/26.
6 | // Copyright © 2016年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | enum Thumbnail {
12 | case Image(imageURL: URL, parentID:String)
13 | case Movie(movieURL: URL, thumbnailURL: URL, parentID:String)
14 |
15 | var thumbnailURL: URL {
16 | switch self {
17 | case .Image(let imageURL, _):
18 | return imageURL
19 | case .Movie( _, let thumbnailURL, _):
20 | return thumbnailURL
21 | }
22 | }
23 |
24 | var url: URL {
25 | switch self {
26 | case .Image(let imageURL, _):
27 | return imageURL
28 | case .Movie(let movieURL, _, _):
29 | return movieURL
30 | }
31 | }
32 |
33 | var parentID: String {
34 | switch self {
35 | case .Image(_, let parentID):
36 | return parentID
37 | case .Movie(_, _, let parentID):
38 | return parentID
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/application/ThumbnailLinkContainer.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ThumbnailLinkContainer.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2016/10/05.
6 | // Copyright © 2016年 sonson. All rights reserved.
7 | //
8 |
9 | import reddift
10 | import Foundation
11 |
12 | class ThumbnailLinkContainer: LinkContainer {
13 | let thumbnailURL: URL
14 |
15 | /// Cell identifier for dequeueReusableCellWithIdentifier of FrontViewController class.
16 | override var cellIdentifier: String {
17 | get {
18 | if isHidden {
19 | return "InvisibleCell"
20 | } else {
21 | return "ThumbnailLinkCell"
22 | }
23 | }
24 | }
25 |
26 | override var height: CGFloat {
27 | if isHidden {
28 | return 0
29 | } else {
30 | return ThumbnailLinkCell.estimateHeight(titleHeight: titleSize.height)
31 | }
32 | }
33 |
34 | init(link: Link, width: CGFloat, fontSize: CGFloat = 18, thumbnail: Thumbnail) {
35 | self.thumbnailURL = thumbnail.url
36 | super.init(with: link, width: width, fontSize: fontSize)
37 | self.thumbnails = [thumbnail]
38 | let font = UIFont(name: UIFont.systemFont(ofSize: fontSize).fontName, size: fontSize) ?? UIFont.systemFont(ofSize: fontSize)
39 | attributedTitle = NSAttributedString(string: link.title).reconstruct(with: font, color: UIColor.black, linkColor: UIColor.blue)
40 | titleSize = ThumbnailLinkCell.estimateTitleSize(attributedString: attributedTitle, withBountWidth: width, margin: .zero)
41 | pageLoaded = true
42 | }
43 |
44 | /// download thumbnail
45 | override func downloadImages() {
46 | download(imageURLs: [thumbnailURL], sender: self)
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/application/TitleFieldView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TitleFieldView.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2016/12/12.
6 | // Copyright © 2016年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | class TitleFieldView: PostFieldView {
12 | }
13 |
--------------------------------------------------------------------------------
/application/UIViewController+reddift.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIViewController+reddift.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2016/09/11.
6 | // Copyright © 2016年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | extension UIViewController {
12 | func createImageViewPageControllerWith(_ thumbnails: [Thumbnail], openThumbnail: Thumbnail, isOpenedBy3DTouch: Bool = false) -> ImageViewPageController {
13 | for i in 0 ..< thumbnails.count {
14 | if thumbnails[i].thumbnailURL == openThumbnail.thumbnailURL && thumbnails[i].parentID == openThumbnail.parentID {
15 | return ImageViewPageController.controller(thumbnails: thumbnails, index: i, isOpenedBy3DTouch: isOpenedBy3DTouch)
16 | }
17 | }
18 | return ImageViewPageController.controller(thumbnails: thumbnails, index: 0, isOpenedBy3DTouch: isOpenedBy3DTouch)
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/application/URLFieldView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // URLFieldView.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2016/12/12.
6 | // Copyright © 2016年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | class URLFieldView: PostFieldView {
12 | }
13 |
--------------------------------------------------------------------------------
/application/UZTextViewCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UZTextViewCell.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/09/03.
6 | // Copyright © 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class UZTextViewCell: UITableViewCell {
12 | @IBOutlet var textView: UZTextView?
13 |
14 | override func awakeFromNib() {
15 | super.awakeFromNib()
16 | // Initialization code
17 | }
18 |
19 | override func setSelected(_ selected: Bool, animated: Bool) {
20 | super.setSelected(selected, animated: animated)
21 |
22 | // Configure the view for the selected state
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/application/UserViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UserViewController.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2016/09/13.
6 | // Copyright © 2016年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | class UserViewController: UIViewController {
12 | let name: String
13 |
14 | class func controller(_ name: String) -> UINavigationController {
15 | let con = UserViewController(name)
16 | let nav = UINavigationController(rootViewController: con)
17 | return nav
18 | }
19 |
20 | required init?(coder aDecoder: NSCoder) {
21 | name = ""
22 | super.init(coder: aDecoder)
23 | }
24 |
25 | init(_ aName: String) {
26 | name = aName
27 | super.init(nibName: nil, bundle: nil)
28 | }
29 |
30 | override func viewDidLoad() {
31 | super.viewDidLoad()
32 | let barbutton = UIBarButtonItem(title: "Close", style: .plain, target: self, action: #selector(UserViewController.close(sender:)))
33 | self.navigationItem.rightBarButtonItem = barbutton
34 | view.backgroundColor = UIColor.white
35 | self.navigationItem.title = name
36 | }
37 |
38 | @objc func close(sender: Any) {
39 | dismiss(animated: true, completion: nil)
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/application/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/09/01.
6 | // Copyright (c) 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 | // Do any additional setup after loading the view, typically from a nib.
16 | }
17 |
18 | override func didReceiveMemoryWarning() {
19 | super.didReceiveMemoryWarning()
20 | // Dispose of any resources that can be recreated.
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/application/WebViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WebViewController.swift
3 | // Sample3DTouch
4 | //
5 | // Created by sonson on 2016/09/04.
6 | // Copyright © 2016年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import WebKit
11 |
12 | class WebViewController: UIViewController {
13 | let webView = WKWebView(frame: CGRect.zero)
14 |
15 | override func viewDidLoad() {
16 | super.viewDidLoad()
17 | view.addSubview(webView)
18 | webView.translatesAutoresizingMaskIntoConstraints = false
19 |
20 | let views = ["webView": webView]
21 |
22 | view.addConstraints (
23 | NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[webView]-0-|", options: [], metrics: nil, views: views)
24 | )
25 | view.addConstraints (
26 | NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[webView]-0-|", options: [], metrics: nil, views: views)
27 | )
28 |
29 | let bar = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(WebViewController.close(sender:)))
30 | self.navigationItem.rightBarButtonItem = bar
31 | }
32 |
33 | @objc func close(sender: Any) {
34 | self.dismiss(animated: true, completion: nil)
35 | }
36 |
37 | var url: URL? = nil {
38 | didSet {
39 | if let aUrl = url {
40 | let request = URLRequest(url: aUrl)
41 | webView.load(request)
42 | }
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/application/application-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // Use this file to import your target's public headers that you would like to expose to Swift.
3 | //
4 |
5 | #ifndef reddift_objc_header_h
6 | #define reddift_objc_header_h
7 |
8 | #import "ReddiftTextView.h"
9 | #import
10 |
11 | #endif
12 |
--------------------------------------------------------------------------------
/application/application.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.developer.default-data-protection
6 | NSFileProtectionComplete
7 | keychain-access-groups
8 |
9 | $(AppIdentifierPrefix)com.sonson.reddift
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/application/mona.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/application/mona.ttf
--------------------------------------------------------------------------------
/application/reddift-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // Use this file to import your target's public headers that you would like to expose to Swift.
3 | //
4 |
5 | #ifndef reddift_objc_header_h
6 | #define reddift_objc_header_h
7 |
8 | #import "UZTextView.h"
9 | #import "ReddiftTextView.h"
10 | #import
11 | #import "GTMDefines.h"
12 | #import "GTMNSString+HTML.h"
13 | #import "FLAnimatedImageView.h"
14 | #import "FLAnimatedImage.h"
15 |
16 | #endif
17 |
--------------------------------------------------------------------------------
/application/reddift.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.developer.default-data-protection
6 | NSFileProtectionComplete
7 | keychain-access-groups
8 |
9 | $(AppIdentifierPrefix)com.sonson.reddift
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/application/reddift_config.json.sample:
--------------------------------------------------------------------------------
1 | {
2 | "DeveloperName": "",
3 | "redirect_uri": "",
4 | "client_id": ""
5 | }
--------------------------------------------------------------------------------
/framework/Extension/Dictionary+reddift.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Dictionary+reddift.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/09/17.
6 | // Copyright © 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | private let allowedCharacterSet = CharacterSet(charactersIn: "!$&'()*+,-./0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~")
12 |
13 | /**
14 | Protocol to generate URL query string from Dictionary[String:String].
15 | */
16 | public protocol QueryEscapableString {
17 | var addPercentEncoding: String { get }
18 | }
19 |
20 | extension String: QueryEscapableString {
21 | /**
22 | Returns string by adding percent encoding in UTF-8
23 | Protocol to generate URL query string from Dictionary[String:String].
24 | */
25 | public var addPercentEncoding: String {
26 | get {
27 | return (self as NSString).addingPercentEncoding(withAllowedCharacters: allowedCharacterSet) ?? self
28 | }
29 | }
30 | }
31 |
32 | /**
33 | Protocol to generate URL query string from Dictionary[String:String].
34 | */
35 | extension Dictionary where Key: QueryEscapableString, Value: QueryEscapableString {
36 | /**
37 | Gets escped string.
38 | - returns: Returns string by adding percent encoding in UTF-8
39 | */
40 | var URLQuery: String {
41 | get {
42 | return self.map({"\($0.addPercentEncoding)=\($1.addPercentEncoding)"}).joined(separator: "&")
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/framework/Extension/NSBundle+reddift.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NSBundle+reddift.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/04/13.
6 | // Copyright (c) 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | extension Bundle {
12 | /**
13 | Returns object from default info.plist.
14 |
15 | - parameter key: key for value
16 | - returns: Value
17 | */
18 | class func infoValueInMainBundle(for key: String) -> AnyObject? {
19 | if let obj = self.main.localizedInfoDictionary?[key] {
20 | return obj as AnyObject
21 | }
22 | if let obj = self.main.infoDictionary?[key] {
23 | return obj as AnyObject
24 | }
25 | return nil
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/framework/Extension/NSURLComponents+reddift.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NSURLComponents+reddift.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/05/06.
6 | // Copyright (c) 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | extension URLComponents {
12 | var dictionary: [String: String] {
13 | var parameters: [String: String] = [:]
14 | if #available(macOS 10.10, *) {
15 | if let queryItems = self.queryItems {
16 | for queryItem in queryItems {
17 | #if os(iOS)
18 | parameters[queryItem.name] = queryItem.value
19 | #elseif os(macOS)
20 | if let value = queryItem.value {
21 | parameters[queryItem.name] = value
22 | }
23 | #endif
24 | }
25 | }
26 | } else {
27 | // Fallback on earlier versions
28 | }
29 | return parameters
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/framework/Extension/NSURLRequest+reddift.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NSURLRequest+reddift.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2016/06/05.
6 | // Copyright © 2016年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
--------------------------------------------------------------------------------
/framework/Extension/ReddiftError.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ReddiftError.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2016/07/25.
6 | // Copyright © 2016年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public enum ReddiftError: Int, Error {
12 | case unknown
13 | case tokenIsNotAvailable
14 | case canNotCreateURLRequest
15 |
16 | case specifiedNameTokenNotFoundInKeychain
17 | case tokenNameIsInvalid
18 |
19 | case needsCAPTCHAResponseIsInvalid
20 | case imageOfCAPTCHAIsInvalid
21 | case identifierOfCAPTCHAIsMalformed
22 |
23 | case sr_nameOfRecommendedSubredditKeyNotFound
24 | case nameAsResultOfSearchSubredditKeyNotFound
25 | case submit_textxSubredditKeyNotFound
26 | case jsonObjectIsNotListingThing
27 |
28 | case accountJsonObjectIsMalformed
29 | case accountJsonObjectIsNotDictionary
30 |
31 | case tokenJsonObjectIsNotDictionary
32 | case canNotCreateURLRequestForOAuth2Page
33 | case canNotAllocateDataToCreateURLForOAuth2
34 |
35 | case moreCommentJsonObjectIsNotDictionary
36 | case canNotGetMoreCommentForAnyReason
37 |
38 | case multiredditJsonObjectIsNotDictionary
39 | case multiredditJsonObjectIsMalformed
40 |
41 | case canNotCreateDataObjectForClientIDForBasicAuthentication
42 | case canNotCreateDataObjectForUserInfoForBasicAuthentication
43 |
44 | case dataIsNotUTF8String
45 |
46 | case preferenceJsonObjectIsNotDictionary
47 |
48 | case failedToParseThingFromJsonObject
49 | case commentJsonObjectIsMalformed
50 |
51 | case failedToParseThingFromRedditAny
52 | case failedToParseMultiredditArrayFromRedditAny
53 | case failedToParseListingPairFromRedditAny
54 |
55 | case failedToCreateJSONForMultireadditPosting
56 |
57 | public var _code: Int {
58 | return self.rawValue
59 | }
60 |
61 | public var _description: String {
62 | return "not yet"
63 | }
64 |
65 | public var _domain: String {
66 | return "com.reddift"
67 | }
68 |
69 | public var errorDomain: String {
70 | return self._domain
71 | }
72 |
73 | public var errorCode: Int {
74 | return self._code
75 | }
76 |
77 | public var errorUserInfo: [String: AnyObject] {
78 | return [:]
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/framework/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 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/framework/Model/CAPTCHA.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CAPTCHA.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/05/29.
6 | // Copyright (c) 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /**
12 | CAPTCHA data class.
13 | */
14 | public struct CAPTCHA {
15 | public let iden: String
16 | public let image: CAPTCHAImage
17 |
18 | init(iden: String, image: CAPTCHAImage) {
19 | self.iden = iden
20 | self.image = image
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/framework/Model/Config.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Config.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/04/13.
6 | // Copyright (c) 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /**
12 | Class to manage parameters of reddift.
13 | This class is used as singleton model
14 | */
15 | struct Config {
16 | /// Application verison, be updated by Info.plist later.
17 | let version: String
18 | /// Bundle identifier, be updated by Info.plist later.
19 | let bundleIdentifier: String
20 | /// Developer's reddit user name
21 | let developerName: String
22 | /// OAuth redirect URL you register
23 | let redirectURI: String
24 | /// Application ID
25 | let clientID: String
26 |
27 | /**
28 | Singleton model.
29 | */
30 | static let sharedInstance = Config()
31 |
32 | /**
33 | Returns User-Agent for API
34 | */
35 | var userAgent: String {
36 | return "ios:" + bundleIdentifier + ":v" + version + "(by /u/" + developerName + ")"
37 | }
38 |
39 | /**
40 | Returns scheme of redirect URI.
41 | */
42 | var redirectURIScheme: String {
43 | if let scheme = URL(string: redirectURI)?.scheme {
44 | return scheme
45 | } else {
46 | return ""
47 | }
48 | }
49 |
50 | init() {
51 | version = Bundle.infoValueInMainBundle(for: "CFBundleShortVersionString") as? String ?? "1.0"
52 | bundleIdentifier = Bundle.infoValueInMainBundle(for: "CFBundleIdentifier") as? String ?? ""
53 |
54 | var _developerName: String? = nil
55 | var _redirectURI: String? = nil
56 | var _clientID: String? = nil
57 | if let path = Bundle.main.path(forResource: "reddift_config", ofType: "json") {
58 | if let data = try? Data(contentsOf: URL(fileURLWithPath: path)) {
59 | do {
60 | if let json = try JSONSerialization.jsonObject(with: data, options: []) as? JSONDictionary {
61 | _developerName = json["DeveloperName"] as? String
62 | _redirectURI = json["redirect_uri"] as? String
63 | _clientID = json["client_id"] as? String
64 | }
65 | } catch {
66 |
67 | }
68 | }
69 | }
70 |
71 | developerName = _developerName ?? ""
72 | redirectURI = _redirectURI ?? ""
73 | clientID = _clientID ?? ""
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/framework/Model/Created.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Created.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2017/01/09.
6 | // Copyright © 2017年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public protocol Created {
12 | var created: Int {get}
13 | var createdUtc: Int {get}
14 | }
15 |
--------------------------------------------------------------------------------
/framework/Model/Listing.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Listing.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/04/20.
6 | // Copyright (c) 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /**
12 | Listing object.
13 | This class has children, paginator and more.
14 | */
15 | public struct Listing {
16 | /// elements of the list
17 | public let children: [Thing]
18 | /// paginator of the list
19 | public let paginator: Paginator
20 |
21 | public init() {
22 | self.children = []
23 | self.paginator = Paginator()
24 | }
25 |
26 | public init(children: [Thing], paginator: Paginator) {
27 | self.children = children
28 | self.paginator = paginator
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/framework/Model/Media.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Media.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/04/20.
6 | // Copyright (c) 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /**
12 | Media represents the content which is embeded a link.
13 | */
14 | public struct Media {
15 | /**
16 | example "i.imgur.com"
17 | */
18 | public let type: String
19 | /**
20 | oembed object
21 | */
22 | public let oembed: Oembed
23 | /**
24 | Update each property with JSON object.
25 |
26 | - parameter json: JSON object which is included "t2" JSON.
27 | */
28 | public init(json: JSONDictionary) {
29 | type = json["type"] as? String ?? ""
30 | oembed = Oembed(json: json["oembed"] as? JSONDictionary ?? [:])
31 | }
32 |
33 | public var string: String {
34 | get {
35 | return "{type=\(type)}\n"
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/framework/Model/MediaEmbed.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MediaEmbed.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/04/21.
6 | // Copyright (c) 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import HTMLSpecialCharacters
11 |
12 | /**
13 | Media represents the content which is embeded a link.
14 | */
15 | public struct MediaEmbed {
16 | /// Height of content.
17 | let height: Int
18 | /// Width of content.
19 | let width: Int
20 | /// Information of content.
21 | let content: String
22 | /// Is content scrolled?
23 | let scrolling: Bool
24 |
25 | /**
26 | Update each property with JSON object.
27 |
28 | - parameter json: JSON object which is included "t2" JSON.
29 | */
30 | public init (json: JSONDictionary) {
31 | height = json["height"] as? Int ?? 0
32 | width = json["width"] as? Int ?? 0
33 | let tempContent = json["content"] as? String ?? ""
34 | content = tempContent.unescapeHTML
35 | scrolling = json["scrolling"] as? Bool ?? false
36 | }
37 |
38 | var string: String {
39 | get {
40 | return "{content=\(content)\nsize=\(width)x\(height)}\n"
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/framework/Model/More.swift:
--------------------------------------------------------------------------------
1 | //
2 | // More.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/04/21.
6 | // Copyright (c) 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /**
12 | More object.
13 | "more" is included in Listing object(Maybe).
14 | If Listing object has "more" object, it has mure more children to be downloaded.
15 | */
16 | public struct More: Thing {
17 | /// identifier of Thing like 15bfi0.
18 | public let id: String
19 | /// name of Thing, that is fullname, like t3_15bfi0.
20 | public let name: String
21 | /// type of Thing, like t3.
22 | public static let kind = "more"
23 |
24 | public let parentId: String
25 | public let count: Int
26 | public let children: [String]
27 |
28 | public init(id: String) {
29 | self.id = id
30 | self.name = "\(More.kind)_\(self.id)"
31 | parentId = ""
32 | count = 0
33 | children = []
34 | }
35 |
36 | /**
37 | Parse more object.
38 |
39 | - parameter data: Dictionary, must be generated parsing "more".
40 | - returns: More object as Thing.
41 | */
42 | public init(json data: JSONDictionary) {
43 | id = data["id"] as? String ?? ""
44 | name = data["name"] as? String ?? ""
45 | parentId = data["parent_id"] as? String ?? ""
46 | count = data["count"] as? Int ?? 0
47 | children = data["children"] as? [String] ?? []
48 | }
49 |
50 | public init(id: String, name: String, parentId: String, count: Int = 0, child: String) {
51 | self.id = id
52 | self.name = name
53 | self.parentId = parentId
54 | self.count = count
55 | self.children = [child]
56 | }
57 |
58 | public var isEmpty: Bool {
59 | get {
60 | return id == "_"
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/framework/Model/MultiredditDescription.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MultiredditDescription.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/05/23.
6 | // Copyright (c) 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import HTMLSpecialCharacters
11 |
12 | /**
13 | Multireddit description class.
14 | */
15 | public struct MultiredditDescription {
16 | public let bodyHtml: String
17 | public let bodyMd: String
18 |
19 | public init(json: JSONDictionary) {
20 | let tempBodyHtml = json["body_html"] as? String ?? ""
21 | bodyHtml = tempBodyHtml.unescapeHTML
22 | bodyMd = json["body_md"] as? String ?? ""
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/framework/Model/Oembed.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Oembed.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/04/20.
6 | // Copyright (c) 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import HTMLSpecialCharacters
11 |
12 | /**
13 | Media represents the content which is embeded a link.
14 | */
15 | public struct Oembed {
16 | /**
17 | example, "http://i.imgur.com",
18 | */
19 | public let providerUrl: String
20 | /**
21 | example, "The Internet's visual storytelling community. Explore, share, and discuss the best visual stories the Internet has to offer.",
22 | */
23 | public let description: String
24 | /**
25 | example, "Imgur GIF",
26 | */
27 | public let title: String
28 | /**
29 | example, 245,
30 | */
31 | public let thumbnailWidth: Int
32 | /**
33 | example, 333,
34 | */
35 | public let height: Int
36 | /**
37 | example, 245,
38 | */
39 | public let width: Int
40 | /**
41 | example, "<iframe class=\"embedly-embed\" src=\"//cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fi.imgur.com%2FkhgfcrQ.mp4&src_secure=1&url=http%3A%2F%2Fi.imgur.com%2FkhgfcrQ.gifv&image=http%3A%2F%2Fi.imgur.com%2FkhgfcrQ.gif&key=2aa3c4d5f3de4f5b9120b660ad850dc9&type=video%2Fmp4&schema=imgur\" width=\"245\" height=\"333\" scrolling=\"no\" frameborder=\"0\" allowfullscreen></iframe>",
42 | */
43 | public let html: String
44 | /**
45 | example, "1.0",
46 | */
47 | public let version: String
48 | /**
49 | example, "Imgur",
50 | */
51 | public let providerName: String
52 | /**
53 | example, "http://i.imgur.com/khgfcrQ.gif",
54 | */
55 | public let thumbnailUrl: String
56 | /**
57 | example, "video",
58 | */
59 | public let type: String
60 | /**
61 | example, 333
62 | */
63 | public let thumbnailHeight: Int
64 | /**
65 | Update each property with JSON object.
66 |
67 | - parameter json: JSON object which is included "t2" JSON.
68 | */
69 | public init (json: JSONDictionary) {
70 | self.providerUrl = json["provider_url"] as? String ?? ""
71 | self.description = json["description"] as? String ?? ""
72 | self.title = json["title"] as? String ?? ""
73 | self.thumbnailWidth = json["thumbnail_width"] as? Int ?? 0
74 | self.height = json["height"] as? Int ?? 0
75 | self.width = json["width"] as? Int ?? 0
76 | let tempHtml = json["html"] as? String ?? ""
77 | self.html = tempHtml.unescapeHTML
78 | self.version = json["version"] as? String ?? ""
79 | self.providerName = json["provider_name"] as? String ?? ""
80 | self.thumbnailUrl = json["thumbnail_url"] as? String ?? ""
81 | self.type = json["type"] as? String ?? ""
82 | self.thumbnailHeight = json["thumbnail_height"] as? Int ?? 0
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/framework/Model/Paginator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Paginator.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/04/14.
6 | // Copyright (c) 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /**
12 | Paginator object for paiging listing object.
13 | */
14 | public struct Paginator {
15 | let after: String
16 | let before: String
17 | let modhash: String
18 |
19 | public init() {
20 | self.after = ""
21 | self.before = ""
22 | self.modhash = ""
23 | }
24 |
25 | public init(after: String, before: String, modhash: String) {
26 | self.after = after
27 | self.before = before
28 | self.modhash = modhash
29 | }
30 |
31 | public var isVacant: Bool {
32 | if (!after.isEmpty) || (!before.isEmpty) {
33 | return false
34 | }
35 | return true
36 | }
37 |
38 | /**
39 | Generate dictionary to add query parameters to URL.
40 | If paginator is vacant, returns vacant dictionary as [String:String].
41 |
42 | - returns: Dictionary object for paging.
43 | */
44 | public var parameterDictionary: [String: String] {
45 | get {
46 | var dict: [String: String] = [:]
47 | if !after.isEmpty {
48 | dict["after"] = after
49 | }
50 | if !before.isEmpty {
51 | dict["before"] = before
52 | }
53 | return dict
54 | }
55 | }
56 |
57 | public func dictionaryByAdding(parameters dict: [String: String]) -> [String: String] {
58 | var newDict = dict
59 | if !after.isEmpty {
60 | newDict["after"] = after
61 | }
62 | if !before.isEmpty {
63 | newDict["before"] = before
64 | }
65 | return newDict
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/framework/Model/Response.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Response.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/06/26.
6 | // Copyright © 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /**
12 | Object to eliminate codes to parse http response object.
13 | */
14 | struct Response {
15 | let data: Data
16 | let statusCode: Int
17 |
18 | init(data: Data?, urlResponse: URLResponse?) {
19 | if let data = data {
20 | self.data = data
21 | } else {
22 | self.data = Data()
23 | }
24 | if let httpResponse = urlResponse as? HTTPURLResponse {
25 | statusCode = httpResponse.statusCode
26 | } else {
27 | statusCode = 500
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/framework/Model/SubredditKarma.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SubredditKarma.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/11/16.
6 | // Copyright © 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /**
12 | Subreddit karma object
13 | */
14 | public struct SubredditKarma {
15 | let commentKarma: Int
16 | let linkKarma: Int
17 | let subreddit: String
18 |
19 | init(subreddit: String, commentKarma: Int, linkKarma: Int) {
20 | self.subreddit = subreddit
21 | self.commentKarma = commentKarma
22 | self.linkKarma = linkKarma
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/framework/Model/Thing.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Thing.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/05/27.
6 | // Copyright (c) 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public protocol Thing {
12 | var id: String {get}
13 | var name: String {get}
14 | static var kind: String {get}
15 |
16 | init(id: String)
17 | }
18 |
--------------------------------------------------------------------------------
/framework/Model/Trophy.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Trophy.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/11/13.
6 | // Copyright © 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /**
12 | Trophy object
13 | */
14 | public struct Trophy: Thing {
15 | /// identifier of Thing like 15bfi0.
16 | public let id: String
17 | /// name of Thing, that is fullname, like t3_15bfi0.
18 | public let name: String
19 | /// type of Thing, like t3.
20 | static public let kind = "t6"
21 |
22 | /// Trophy data
23 | public let title: String
24 | public let description: String
25 | public let awardID: String
26 | public let icon40: URL?
27 | public let icon70: URL?
28 | public let url: URL?
29 |
30 | public init(id: String) {
31 | self.id = id
32 | self.name = "\(Comment.kind)_\(self.id)"
33 | self.title = ""
34 | self.description = ""
35 | self.awardID = ""
36 | self.icon40 = nil
37 | self.icon70 = nil
38 | self.url = nil
39 | }
40 |
41 | public init(json: JSONDictionary) {
42 | id = json["id"] as? String ?? ""
43 | name = "\(Trophy.kind)_\(id)"
44 | awardID = json["award_id"] as? String ?? ""
45 | description = json["description"] as? String ?? ""
46 | icon40 = URL(string: (json["icon_40"] as? String ?? ""))
47 | icon70 = URL(string: (json["icon_70"] as? String ?? ""))
48 | url = URL(string: (json["url"] as? String ?? ""))
49 | title = json["name"] as? String ?? ""
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/framework/Model/User.swift:
--------------------------------------------------------------------------------
1 | //
2 | // User.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/11/12.
6 | // Copyright © 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /**
12 | */
13 | public enum UserModPermission: String {
14 | case all
15 | case wiki
16 | case posts
17 | case mail
18 | case flair
19 | case unknown
20 |
21 | public init(_ value: String) {
22 | switch value {
23 | case "all":
24 | self = .all
25 | case "wiki":
26 | self = .wiki
27 | case "posts":
28 | self = .posts
29 | case "mail":
30 | self = .mail
31 | case "flair":
32 | self = .flair
33 | default:
34 | self = .unknown
35 | }
36 | }
37 | }
38 |
39 | /**
40 | User object
41 | */
42 | public struct User {
43 | let date: TimeInterval
44 | let modPermissions: [UserModPermission]
45 | let name: String
46 | let id: String
47 |
48 | public init(date: Double, permissions: [String]?, name: String, id: String) {
49 | self.date = date
50 | if let permissions = permissions {
51 | self.modPermissions = permissions.map({UserModPermission($0)})
52 | } else {
53 | self.modPermissions = []
54 | }
55 | self.name = name
56 | self.id = id
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/framework/Model/Votable.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Votable.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2017/01/09.
6 | // Copyright © 2017年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public protocol Votable {
12 | var ups: Int {get}
13 | var downs: Int {get}
14 | var likes: VoteDirection {get}
15 | }
16 |
--------------------------------------------------------------------------------
/framework/Network/Session+Token.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Session+Token.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/09/21.
6 | // Copyright © 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | func refreshTokenWithJSON(_ result: Result, token: OAuth2Token) -> Result {
12 | switch result {
13 | case .success(let json):
14 | var newJSON = json
15 | newJSON["name"] = token.name as AnyObject
16 | newJSON["refresh_token"] = token.refreshToken as AnyObject
17 | return OAuth2Token.tokenWithJSON(newJSON)
18 | case .failure(let error):
19 | return Result(error: error)
20 | }
21 | }
22 |
23 | extension Session {
24 | /**
25 | Refresh own token.
26 |
27 | - parameter completion: The completion handler to call when the load request is complete.
28 | */
29 | public func refreshToken(_ completion: @escaping (Result) -> Void) throws {
30 | guard let currentToken = token as? OAuth2Token
31 | else { throw ReddiftError.tokenIsNotAvailable as NSError }
32 | do {
33 | try currentToken.refresh({ (result) -> Void in
34 | switch result {
35 | case .failure(let error):
36 | completion(Result(error: error as NSError))
37 | case .success(let newToken):
38 | DispatchQueue.main.async(execute: { () -> Void in
39 | self.token = newToken
40 | do {
41 | try OAuth2TokenRepository.save(token: newToken)
42 | completion(Result(value: newToken))
43 | } catch { completion(Result(error: error as NSError)) }
44 | })
45 | }
46 | })
47 | } catch { throw error }
48 | }
49 |
50 | /**
51 | Revoke own token. After calling this function, this object must be released becuase it has lost any conection.
52 |
53 | - parameter completion: The completion handler to call when the load request is complete.
54 | */
55 | public func revokeToken(_ completion: @escaping (Result) -> Void) throws {
56 | guard let currentToken = token as? OAuth2Token
57 | else { throw ReddiftError.tokenIsNotAvailable as NSError }
58 | do {
59 | try currentToken.revoke({ (result) -> Void in
60 | switch result {
61 | case .failure(let error):
62 | completion(Result(error: error as NSError))
63 | case .success:
64 | DispatchQueue.main.async(execute: { () -> Void in
65 | do {
66 | try OAuth2TokenRepository.removeToken(of: currentToken.name)
67 | completion(Result(value: currentToken))
68 | } catch { completion(Result(error: error as NSError)) }
69 | })
70 | }
71 | })
72 | } catch { throw error }
73 | }
74 |
75 | /**
76 | Set an expired token to self.
77 | This method is implemented in order to test codes to automatiaclly refresh an expired token.
78 | */
79 | public func setDummyExpiredToken() {
80 | if let path = Bundle.main.path(forResource: "expired_token.json", ofType: nil), let data = try? Data(contentsOf: URL(fileURLWithPath: path)) {
81 | do {
82 | if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: AnyObject] {
83 | let token = OAuth2Token(json)
84 | self.token = token
85 | }
86 | } catch { print(error) }
87 | }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/framework/Network/Session+flair.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Session+flair.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/05/19.
6 | // Copyright (c) 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | extension Session {
12 | }
13 |
--------------------------------------------------------------------------------
/framework/Network/Session+gold.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Session+gold.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/05/19.
6 | // Copyright (c) 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | extension Session {
12 | /**
13 | Reddit gold?
14 | Gilds the specified content by fullname?
15 | - parameter fullname: fullname of a thing
16 | - returns: Data task which requests search to reddit.com.
17 | */
18 | @discardableResult
19 | public func gild(_ fullname: String, completion: @escaping (Result) -> Void) throws -> URLSessionDataTask {
20 | let parameter = ["fullname": fullname]
21 | guard let request = URLRequest.requestForOAuth(with: baseURL, path: "/api/v1/gold/gild/", parameter: parameter, method: "POST", token: token)
22 | else { throw ReddiftError.canNotCreateURLRequest as NSError }
23 | let closure = {(data: Data?, response: URLResponse?, error: NSError?) -> Result in
24 | return Result(from: Response(data: data, urlResponse: response), optional: error)
25 | .flatMap(response2Data)
26 | .flatMap(data2Json)
27 | }
28 | return executeTask(request, handleResponse: closure, completion: completion)
29 | }
30 |
31 | /**
32 | Reddit gold?
33 | Gives gold to the specified user whose name is specified by username?
34 | - parameter username: A valid, existing reddit username
35 | - parameter months: an integer between 1 and 36
36 | - returns: Data task which requests search to reddit.com.
37 | */
38 | public func giveGold(_ username: String, months: Int, completion: @escaping (Result) -> Void) throws -> URLSessionDataTask {
39 | let parameter = ["fullname": username, "months": String(months)]
40 | guard let request = URLRequest.requestForOAuth(with: baseURL, path: "/api/v1/gold/give/", parameter: parameter, method: "POST", token: token)
41 | else { throw ReddiftError.canNotCreateURLRequest as NSError }
42 | let closure = {(data: Data?, response: URLResponse?, error: NSError?) -> Result in
43 | return Result(from: Response(data: data, urlResponse: response), optional: error)
44 | .flatMap(response2Data)
45 | .flatMap(data2Json)
46 | }
47 | return executeTask(request, handleResponse: closure, completion: completion)
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/framework/Network/Session+liveThreads.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Session+liveThreads.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/05/19.
6 | // Copyright (c) 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | extension Session {
12 | }
13 |
--------------------------------------------------------------------------------
/framework/Network/Session+misc.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Session+misc.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/05/19.
6 | // Copyright (c) 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | extension Session {
12 | }
13 |
--------------------------------------------------------------------------------
/framework/Network/Session+moderation.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Session+moderation.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/05/19.
6 | // Copyright (c) 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | extension Session {
12 | }
13 |
--------------------------------------------------------------------------------
/framework/Network/Session+search.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Session+search.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/05/19.
6 | // Copyright (c) 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | extension Session {
12 |
13 | /**
14 | Search link with query. If subreddit is nil, this method searched links from all of reddit.com.
15 |
16 | - parameter subreddit: Specified subreddit to which you would like to limit your search.
17 | - parameter query: The search keywords, must be less than 512 characters.
18 | - parameter paginator: Paginator object for paging.
19 | - parameter sort: Sort type, specified by SearchSortBy.
20 | - parameter completion: The completion handler to call when the load request is complete.
21 | - returns: Data task which requests search to reddit.com.
22 | */
23 | @discardableResult
24 | public func getSearch(_ subreddit: Subreddit?, query: String, paginator: Paginator, sort: SearchSortBy, completion: @escaping (Result) -> Void) throws -> URLSessionDataTask {
25 | let parameter = paginator.dictionaryByAdding(parameters: ["q": query, "sort": sort.path])
26 | var path = "/search"
27 | if let subreddit = subreddit { path = subreddit.url + "search" }
28 | guard let request = URLRequest.requestForOAuth(with: baseURL, path: path, parameter: parameter, method: "GET", token: token)
29 | else { throw ReddiftError.canNotCreateURLRequest as NSError }
30 | let closure = {(data: Data?, response: URLResponse?, error: NSError?) -> Result in
31 | return Result(from: Response(data: data, urlResponse: response), optional: error)
32 | .flatMap(response2Data)
33 | .flatMap(data2Json)
34 | .flatMap(json2RedditAny)
35 | .flatMap(redditAny2Object)
36 | }
37 | return executeTask(request, handleResponse: closure, completion: completion)
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/framework/Network/Session+wiki.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Session+wiki.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/05/19.
6 | // Copyright (c) 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | extension Session {
12 | }
13 |
--------------------------------------------------------------------------------
/framework/OAuth/OAuth2TokenRepository.swift:
--------------------------------------------------------------------------------
1 | //
2 | // OAuth2TokenRepository.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/04/14.
6 | // Copyright (c) 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import MiniKeychain
11 |
12 | /**
13 | Repository to contain OAuth2 tokens for reddit.com based on "KeychanAccess".
14 | You can manage mulitple accounts using this class.
15 | OAuth2TokenRepository, is utility class, has only class method.
16 | */
17 | public class OAuth2TokenRepository {
18 | /**
19 | Restores token for OAuth2 from Keychain.
20 | - parameter name: Specifies user name of token you want to restore from Keychain.
21 | - returns: OAuth2Token object.
22 | */
23 | public class func token(of name: String) throws -> OAuth2Token {
24 | let keychain = Keychain(service: Config.sharedInstance.bundleIdentifier)
25 | do {
26 | let data = try keychain.data(of: name)
27 | if let json = try JSONSerialization.jsonObject(with: data, options: []) as? JSONDictionary {
28 | return OAuth2Token(json)
29 | }
30 | throw ReddiftError.specifiedNameTokenNotFoundInKeychain as NSError
31 | } catch {
32 | throw error
33 | }
34 | }
35 |
36 | /**
37 | Restores user name list from Keychain.
38 |
39 | - returns: List contains user names that was used to save tokens.
40 | */
41 | public class var savedNames: [String] {
42 | let keychain = Keychain(service: Config.sharedInstance.bundleIdentifier)
43 | do {
44 | return try keychain.keys()
45 | } catch {
46 | print(error)
47 | return []
48 | }
49 | }
50 |
51 | /**
52 | Saves OAuth2 token object into Keychain.
53 |
54 | - parameter token: OAuth2Token object, that must have valid user name which is used to save it into Keychain.
55 | */
56 | public class func save(token: OAuth2Token) throws {
57 | if token.name.isEmpty {
58 | throw ReddiftError.tokenNameIsInvalid as NSError
59 | }
60 | do {
61 | let data = try JSONSerialization.data(withJSONObject: token.JSONObject, options: [])
62 | let keychain = Keychain(service: Config.sharedInstance.bundleIdentifier)
63 | try keychain.save(key: token.name, data: data)
64 | } catch {
65 | throw error
66 | }
67 | }
68 |
69 | /**
70 | Saves OAuth2 token object into Keychain.
71 |
72 | - parameter token: OAuth2Token object.
73 | - parameter name: Valid user name which is used to save it into Keychain.
74 | */
75 | public class func save(token: OAuth2Token, of name: String) throws {
76 | if name.isEmpty {
77 | throw ReddiftError.tokenNameIsInvalid as NSError
78 | }
79 | do {
80 | let data = try JSONSerialization.data(withJSONObject: token.JSONObject, options: [])
81 | let keychain = Keychain(service: Config.sharedInstance.bundleIdentifier)
82 | try keychain.save(key: name, data: data)
83 | } catch {
84 | throw error
85 | }
86 | }
87 |
88 | /**
89 | Removes OAuth2 token whose user name is specified by the name parmeter from Keychain.
90 |
91 | - parameter name: Valid user name which is used to save it into Keychain.
92 | */
93 | public class func removeToken(of name: String) throws {
94 | if name.isEmpty {
95 | throw ReddiftError.tokenNameIsInvalid as NSError
96 | }
97 | let keychain = Keychain(service: Config.sharedInstance.bundleIdentifier)
98 | keychain.delete(key: name)
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/framework/OAuth/Token.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Token.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/05/28.
6 | // Copyright (c) 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /**
12 | Protocol for OAuthToken.
13 | */
14 | public protocol Token {
15 | /// token
16 | var accessToken: String {get}
17 | /// the type of token
18 | var tokenType: String {get}
19 | var expiresIn: Int {get}
20 | var expiresDate: TimeInterval {get}
21 | var scope: String {get}
22 | var refreshToken: String {get}
23 |
24 | /// user name to identifiy token.
25 | var name: String {get}
26 |
27 | /// base URL of API
28 | static var baseURL: String {get}
29 |
30 | /// vacant token
31 | init()
32 |
33 | /// deserials Token from JSON data
34 | init(_ json: JSONDictionary)
35 | }
36 |
37 | extension Token {
38 | /**
39 | Returns json object
40 |
41 | - returns: Dictinary object containing JSON data.
42 | */
43 | var JSONObject: JSONDictionary {
44 | let dict: JSONDictionary = [
45 | "name": self.name as AnyObject,
46 | "access_token": self.accessToken as AnyObject,
47 | "token_type": self.tokenType as AnyObject,
48 | "expires_in": self.expiresIn as AnyObject,
49 | "expires_date": self.expiresDate as AnyObject,
50 | "scope": self.scope as AnyObject,
51 | "refresh_token": self.refreshToken as AnyObject
52 | ]
53 | return dict
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/framework/Utility/Result.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Result.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/05/06.
6 | // Copyright (c) 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public enum Result {
12 | case success(A)
13 | case failure(NSError)
14 |
15 | public init(value: A) {
16 | self = .success(value)
17 | }
18 |
19 | public init(fromOptional: A?, error: NSError) {
20 | if let value = fromOptional {
21 | self = .success(value)
22 | } else {
23 | self = .failure(error)
24 | }
25 | }
26 |
27 | public init(from: A, optional error: NSError?) {
28 | if let error = error {
29 | self = .failure(error)
30 | } else {
31 | self = .success(from )
32 | }
33 | }
34 |
35 | public init(error: NSError?) {
36 | if let error = error {
37 | self = .failure(error)
38 | } else {
39 | self = .failure(ReddiftError.unknown as NSError)
40 | }
41 | }
42 |
43 | func package(ifSuccess: (A) -> B, ifFailure: (NSError) -> B) -> B {
44 | switch self {
45 | case .success(let value):
46 | return ifSuccess(value)
47 | case .failure(let value):
48 | return ifFailure(value)
49 | }
50 | }
51 |
52 | func map(_ transform: (A) -> B) -> Result {
53 | return flatMap { .success(transform($0)) }
54 | }
55 |
56 | public func flatMap(_ transform: (A) -> Result) -> Result {
57 | return package(
58 | ifSuccess: transform,
59 | ifFailure: Result.failure)
60 | }
61 |
62 | public var error: NSError? {
63 | switch self {
64 | case .failure(let error):
65 | return error
66 | default:
67 | return nil
68 | }
69 | }
70 |
71 | public var value: A? {
72 | switch self {
73 | case .success(let success):
74 | return success
75 | default:
76 | return nil
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/framework/Utility/helper.swift:
--------------------------------------------------------------------------------
1 | //
2 | // helper.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/04/27.
6 | // Copyright (c) 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | #if os(iOS) || os(tvOS)
12 | import UIKit
13 | #elseif os(macOS)
14 | import Cocoa
15 | #endif
16 |
17 | /// Shared color class
18 | #if os(iOS) || os(tvOS)
19 | public typealias ReddiftColor = UIColor
20 | #elseif os(macOS)
21 | public typealias ReddiftColor = NSColor
22 | #endif
23 |
--------------------------------------------------------------------------------
/framework/reddift.h:
--------------------------------------------------------------------------------
1 | //
2 | // reddift.h
3 | // reddift
4 | //
5 | // Created by sonson on 2015/05/01.
6 | // Copyright (c) 2015年 sonson. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #if TARGET_OS_IPHONE
12 | #import
13 | #endif
14 |
15 | //! Project version number for reddift.
16 | FOUNDATION_EXPORT double reddiftVersionNumber;
17 |
18 | //! Project version string for reddift.
19 | FOUNDATION_EXPORT const unsigned char reddiftVersionString[];
20 |
21 | // In this header, you should import all the public headers of your framework using statements like #import
2 |
3 |
4 |
--------------------------------------------------------------------------------
/playground/reddift.playground/Resources/test_config.json.sample:
--------------------------------------------------------------------------------
1 | {
2 | "username": "test user account",
3 | "password": "test user password",
4 | "client_id": "test app client ID(must be script type app)",
5 | "secret": "test app secret"
6 | }
--------------------------------------------------------------------------------
/playground/reddift.playground/Sources/SupportCode.swift:
--------------------------------------------------------------------------------
1 | //
2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to reddift.playground.
3 | //
4 |
--------------------------------------------------------------------------------
/playground/reddift.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/reddift.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = "reddift"
3 | s.version = "2.0.3"
4 | s.summary = "Swift Reddit API Wrapper."
5 | s.description = <<-DESC
6 | reddift is Swift Reddit API Wrapper.
7 | - Supports OAuth2(and DOES NOT support Cookie-authentication).
8 | - Supports multi-accounts using KeyChain.
9 | DESC
10 | s.homepage = "https://github.com/sonsongithub/reddift"
11 | s.license = 'MIT'
12 | s.author = { "sonson" => "yoshida.yuichi@gmail.com" }
13 | s.source = {
14 | :git => "https://github.com/sonsongithub/reddift.git",
15 | :tag => "#{s.version}",
16 | :submodules => true
17 | }
18 |
19 | s.social_media_url = 'https://twitter.com/sonson_twit'
20 |
21 | s.ios.deployment_target = "8.4"
22 | s.osx.deployment_target = "10.9"
23 | s.tvos.deployment_target = "9.2"
24 | s.requires_arc = true
25 |
26 | s.source_files = [
27 | 'framework/*/*.swift'
28 | ]
29 | s.dependency 'HTMLSpecialCharacters'
30 | s.dependency 'MiniKeychain'
31 | end
32 |
--------------------------------------------------------------------------------
/reddift.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/reddift.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/reddift.xcodeproj/xcshareddata/xcschemes/application.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/reddift.xcodeproj/xcshareddata/xcschemes/reddift-tvOS.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
51 |
52 |
53 |
54 |
64 |
65 |
71 |
72 |
73 |
74 |
75 |
76 |
82 |
83 |
89 |
90 |
91 |
92 |
94 |
95 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/test/CAPTCHATest.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CAPTCHATest.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/05/07.
6 | // Copyright (c) 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | #if os(iOS)
13 | import UIKit
14 | #endif
15 |
16 | class CAPTCHATest: SessionTestSpec {
17 |
18 | // now, CAPTCHA API does not work.....?
19 | // func testCheckWhetherCAPTCHAIsNeededOrNot() {
20 | // let msg = "is true or false as Bool"
21 | // print(msg)
22 | // var check_result: Bool? = nil
23 | // let documentOpenExpectation = self.expectation(description: msg)
24 | // do {
25 | // try self.session?.checkNeedsCAPTCHA({(result) -> Void in
26 | // switch result {
27 | // case .failure(let error):
28 | // print(error)
29 | // case .success(let check):
30 | // check_result = check
31 | // }
32 | // XCTAssert(check_result != nil, msg)
33 | // documentOpenExpectation.fulfill()
34 | // })
35 | // } catch { XCTFail((error as NSError).description) }
36 | // self.waitForExpectations(timeout: self.timeoutDuration, handler: nil)
37 | // }
38 |
39 | // now, CAPTCHA API does not work.....?
40 | // func testGetIdenForNewCAPTCHA() {
41 | // let msg = "is String"
42 | // print(msg)
43 | // var iden: String? = nil
44 | // let documentOpenExpectation = self.expectation(description: msg)
45 | // do {
46 | // try self.session?.getIdenForNewCAPTCHA({ (result) -> Void in
47 | // switch result {
48 | // case .failure(let error):
49 | // print(error.description)
50 | // case .success(let identifier):
51 | // iden = identifier
52 | // }
53 | // XCTAssert(iden != nil, msg)
54 | // documentOpenExpectation.fulfill()
55 | // })
56 | // } catch { XCTFail((error as NSError).description) }
57 | // self.waitForExpectations(timeout: self.timeoutDuration, handler: nil)
58 | // }
59 |
60 | // now, CAPTCHA API does not work.....?
61 | // func testSizeOfNewImageGeneratedUsingIden() {
62 | // let msg = "is 120x50"
63 | // print(msg)
64 | //#if os(iOS) || os(tvOS)
65 | // var size: CGSize? = nil
66 | //#elseif os(macOS)
67 | // var size: NSSize? = nil
68 | //#endif
69 | // let documentOpenExpectation = self.expectation(description: msg)
70 | // do {
71 | // try self.session?.getIdenForNewCAPTCHA({ (result) -> Void in
72 | // switch result {
73 | // case .failure(let error):
74 | // print(error.description)
75 | // case .success(let string):
76 | // try! self.session?.getCAPTCHA(string, completion: { (result) -> Void in
77 | // switch result {
78 | // case .failure(let error):
79 | // print(error.description)
80 | // case .success(let image):
81 | // size = image.size
82 | // }
83 | // documentOpenExpectation.fulfill()
84 | // })
85 | // }
86 | // })
87 | // } catch { XCTFail((error as NSError).description) }
88 | // self.waitForExpectations(timeout: self.timeoutDuration, handler: nil)
89 | //
90 | // if let size = size {
91 | //#if os(iOS)
92 | // XCTAssert(size == CGSize(width: 120, height: 50), msg)
93 | //#elseif os(macOS)
94 | // XCTAssert(size == NSSize(width: 120, height: 50), msg)
95 | //#endif
96 | // } else {
97 | // XCTFail(msg)
98 | // }
99 | // }
100 |
101 | }
102 |
--------------------------------------------------------------------------------
/test/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 |
--------------------------------------------------------------------------------
/test/MoreChildrenTest.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MoreChildrenTest.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2016/02/26.
6 | // Copyright © 2016年 sonson. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | class MoreChildrenTest: SessionTestSpec {
12 |
13 | /**
14 | Test procedure
15 | 1. Get Link list from speficified Subreddit.
16 | 2. Get the Link which has the most comments in the list.
17 | 3. Get Comments and More from Link.
18 | 4. Expand More objects.
19 | */
20 | func testGetMoreChildren() {
21 |
22 | var moreList: [More] = []
23 |
24 | // https://www.reddit.com/r/redditdev/comments/2ujhkr/important_api_licensing_terms_clarified/
25 | let link = Link(id: "2ujhkr")
26 |
27 | do {
28 | let documentOpenExpectation = self.expectation(description: "")
29 | try session?.getArticles(link, sort: .new, comments: nil, depth: 1, limit: 10, completion: { (result) -> Void in
30 | switch result {
31 | case .failure(let error):
32 | print(error)
33 | case .success(_, let listing):
34 | let incomming = listing.children.compactMap({ $0 as? More})
35 | moreList.append(contentsOf: incomming)
36 | }
37 | documentOpenExpectation.fulfill()
38 | })
39 | self.waitForExpectations(timeout: self.timeoutDuration, handler: nil)
40 | } catch { XCTFail((error as NSError).description) }
41 |
42 | XCTAssert(moreList.count > 0, "Cannot get More objects.")
43 |
44 | var check = true
45 |
46 | moreList.forEach({
47 | do {
48 | let documentOpenExpectation = self.expectation(description: "")
49 | try session?.getMoreChildren($0.children, link: link, sort: .new, completion: { (result) -> Void in
50 | switch result {
51 | case .failure(let error):
52 | print(error)
53 | check = false
54 | case .success(let list):
55 | // print(list)
56 | if list.count == 0 {
57 | check = false
58 | }
59 | }
60 | documentOpenExpectation.fulfill()
61 | })
62 | self.waitForExpectations(timeout: self.timeoutDuration, handler: nil)
63 | } catch { XCTFail((error as NSError).description) }
64 | })
65 | XCTAssert(check, "Cannot expand More objects.")
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/test/ParseCommentMarkdownTest.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ParseCommentMarkdownTest.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/09/24.
6 | // Copyright © 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | class ParseCommentMarkdownTest: XCTestCase {
12 | var json: Any?
13 |
14 | override func setUp() {
15 | super.setUp()
16 | json = self.jsonFromFileName("comment_parse_data.json")
17 | }
18 |
19 | override func tearDown() {
20 | super.tearDown()
21 | }
22 |
23 | /// Perfomance test for markdown parsing.
24 | func testPerformanceOfParserCommentMarkdown() {
25 | print("Check performance of Simple Markdown Parser to parse reddit's makrdown format.")
26 | print("test data : comment_parse_data.json")
27 |
28 | /// Start to test
29 | self.measure {
30 | }
31 | }
32 |
33 | /// Unit test for markdown parsing
34 | func testParserCommentMarkdown() {
35 | print("Test whether Simple Markdown Parser can parse reddit's makrdown format.")
36 | print("test data : comment_parse_data.json")
37 |
38 | /// Start to test
39 | if let _ = self.json as? [AnyObject] {
40 | }
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/test/ReddiftColorTest.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ReddiftColorTest.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2017/01/05.
6 | // Copyright © 2017年 sonson. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | class ReddiftColorTest: XCTestCase {
12 |
13 | func testReddiftColor() {
14 | let hexString = "#FFFF00"
15 | let color = ReddiftColor.color(with: hexString)
16 | XCTAssert(color.hexString() == hexString)
17 | }
18 |
19 | func testReddiftClassMethodColor() {
20 | XCTAssert(ReddiftColor.red.hexString() == "#FF0000")
21 | XCTAssert(ReddiftColor.green.hexString() == "#00FF00")
22 | XCTAssert(ReddiftColor.blue.hexString() == "#0000FF")
23 | XCTAssert(ReddiftColor.yellow.hexString() == "#FFFF00")
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/test/SearchTest.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SearchTest.swift
3 | // reddift
4 | //
5 | // Created by sonson on 2015/06/01.
6 | // Copyright (c) 2015年 sonson. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | class SearchTest: SessionTestSpec {
12 |
13 | /**
14 | Test procedure
15 | */
16 | func testSearch() {
17 | var links: [Link] = []
18 | let query = "apple"
19 | let msg = "Search subreddit name used of \(query)"
20 | let documentOpenExpectation = self.expectation(description: msg)
21 | let subreddit = Subreddit(subreddit: "apple")
22 |
23 | do {
24 | try self.session?.getSearch(subreddit, query: query, paginator: Paginator(), sort: .new, completion: { (result) -> Void in
25 | switch result {
26 | case .failure(let error):
27 | print(error)
28 | case .success(let listing):
29 | links.append(contentsOf: listing.children.compactMap { $0 as? Link })
30 | }
31 | documentOpenExpectation.fulfill()
32 | })
33 | self.waitForExpectations(timeout: self.timeoutDuration, handler: nil)
34 | } catch { XCTFail((error as NSError).description) }
35 | XCTAssert(links.count > 0, msg)
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/test/data/other/create_token.json:
--------------------------------------------------------------------------------
1 | {"access_token": "37688300-b1c3Fm8YEl5YFqQi0YUESyBxTVA", "token_type": "bearer", "expires_in": 3600, "refresh_token": "37688300-flMxq9iR9sjnPCvepg64V_98Bng", "scope": "edit flair history identity modconfig modflair modlog modposts modwiki mysubreddits privatemessages read report save submit subscribe vote wikiedit wikiread"}
--------------------------------------------------------------------------------
/test/data/other/refresh_token.json:
--------------------------------------------------------------------------------
1 | {"access_token": "37688300-PbETNGjqI-NnVXgJQdUVPV8X1Ng", "token_type": "bearer", "expires_in": 3600, "scope": "edit flair history identity modconfig modflair modlog modposts modwiki mysubreddits privatemessages read report save submit subscribe vote wikiedit wikiread"}
--------------------------------------------------------------------------------
/test/data/response/TrophyList.json:
--------------------------------------------------------------------------------
1 | {"kind": "TrophyList", "data": {"trophies": [{"kind": "t6", "data": {"icon_70": "https://s3.amazonaws.com/redditstatic/award/n00b-70.png", "description": null, "url": null, "icon_40": "https://s3.amazonaws.com/redditstatic/award/n00b-40.png", "award_id": "j", "id": "10wnxy", "name": "New User"}}]}}
2 |
--------------------------------------------------------------------------------
/test/data/response/api_comment_response.json:
--------------------------------------------------------------------------------
1 | {"json": {"errors": [], "data": {"things": [{"kind": "t1", "data": {"subreddit_id": "t5_31t2q", "banned_by": null, "link_id": "t3_35dpes", "likes": true, "replies": "", "user_reports": [], "saved": false, "id": "cr3g41y", "gilded": 0, "archived": false, "report_reasons": null, "author": "sonson_twit", "parent_id": "t3_35dpes", "score": 1, "approved_by": null, "controversiality": 0, "body": "test comment2", "edited": false, "author_flair_css_class": null, "downs": 0, "body_html": "<div class=\"md\"><p>test comment2</p>\n</div>", "subreddit": "sandboxtest", "score_hidden": false, "name": "t1_cr3g41y", "created": 1431192188.0, "author_flair_text": null, "created_utc": 1431163388.0, "ups": 1, "mod_reports": [], "num_reports": null, "distinguished": null}}]}}}
--------------------------------------------------------------------------------
/test/data/response/api_needs_captcha.json:
--------------------------------------------------------------------------------
1 | true
--------------------------------------------------------------------------------
/test/data/response/api_new_captcha.json:
--------------------------------------------------------------------------------
1 | {"json": {"errors": [], "data": {"iden": "3DKrBtTv6nGrB9Pua2HOK7iM0uW7XnV9"}}}
--------------------------------------------------------------------------------
/test/data/response/error.json:
--------------------------------------------------------------------------------
1 | {"error": 401}
--------------------------------------------------------------------------------
/test/data/response/message.json:
--------------------------------------------------------------------------------
1 | {
2 | "kind": "Listing",
3 | "data": {
4 | "modhash": null,
5 | "children": [
6 | {
7 | "kind": "t1",
8 | "data": {
9 | "body": "Checking it out now. I'l.....",
10 | "link_title": "Reddit Redirecting back to iOS app after login",
11 | "was_comment": true,
12 | "first_message": null,
13 | "name": "t1_cqdtl5p",
14 | "first_message_name": null,
15 | "created": 1429150024,
16 | "dest": "sonson_twit",
17 | "author": "supburger",
18 | "created_utc": 1429146424,
19 | "body_html": "<!-- SC_OFF --><div class=\"md\"><p>Check.....",
20 | "subreddit": "redditdev",
21 | "parent_id": "t1_cqdth7o",
22 | "likes": null,
23 | "context": "/r/redditdev/comments/32ik4r/reddit_redirecting_back_to_ios_app_after_login/cqdtl5p?context=3",
24 | "replies": null,
25 | "id": "cqdtl5p",
26 | "new": false,
27 | "distinguished": null,
28 | "subject": "コメントの返信"
29 | }
30 | },
31 | {
32 | "kind": "t1",
33 | "data": {
34 | "body": "Correct. Everything is match.....",
35 | "link_title": "Reddit Redirecting back to iOS app after login",
36 | "was_comment": true,
37 | "first_message": null,
38 | "name": "t1_cqdclak",
39 | "first_message_name": null,
40 | "created": 1429123203,
41 | "dest": "sonson_twit",
42 | "author": "supburger",
43 | "created_utc": 1429119603,
44 | "body_html": "<!-- SC_OFF --><div class=\"md.....",
45 | "subreddit": "redditdev",
46 | "parent_id": "t1_cqdba2b",
47 | "likes": null,
48 | "context": "/r/redditdev/comments/32ik4r/reddit_redirecting_back_to_ios_app_after_login/cqdclak?context=3",
49 | "replies": null,
50 | "id": "cqdclak",
51 | "new": false,
52 | "distinguished": null,
53 | "subject": "コメントの返信"
54 | }
55 | },
56 | {
57 | "kind": "t1",
58 | "data": {
59 | "body": "I did add URL Types to my Xc.....",
60 | "was_comment": true,
61 | "first_message": null,
62 | "name": "t1_cqd7lk1",
63 | "first_message_name": null,
64 | "created": 1429115592,
65 | "dest": "sonson_twit",
66 | "author": "supburger",
67 | "created_utc": 1429111992,
68 | "body_html": "<!-- .....",
69 | "subreddit": "redditdev",
70 | "parent_id": "t1_cqczrs3",
71 | "likes": null,
72 | "context": "/r/redditdev/comments/32ik4r/reddit_redirecting_back_to_ios_app_after_login/cqd7lk1?context=3",
73 | "replies": null,
74 | "id": "cqd7lk1",
75 | "new": false,
76 | "distinguished": null,
77 | "subject": "コメントの返信"
78 | }
79 | },
80 | {
81 | "kind": "t4",
82 | "data": {
83 | "body": "Hello! [Hola!](https://www.reddit.com/r/reddit.com/wiki/templat.....",
84 | "was_comment": false,
85 | "first_message": null,
86 | "name": "t4_36sfhx",
87 | "first_message_name": null,
88 | "created": 1427126074,
89 | "dest": "sonson_twit",
90 | "author": "reddit",
91 | "created_utc": 1427122474,
92 | "body_html": "<!-- SC_.....",
93 | "subreddit": null,
94 | "parent_id": null,
95 | "context": "",
96 | "replies": "",
97 | "id": "36sfhx",
98 | "new": false,
99 | "distinguished": "admin",
100 | "subject": "Hello, /u/sonson_twit! Welcome to reddit!"
101 | }
102 | }
103 | ],
104 | "after": null,
105 | "before": null
106 | }
107 | }
--------------------------------------------------------------------------------
/test/data/response/multi.json:
--------------------------------------------------------------------------------
1 | [{"kind": "LabeledMulti", "data": {"can_edit": true, "display_name": "english", "name": "english", "description_html": "", "created": 1432028681.0, "copied_from": null, "icon_url": null, "subreddits": [{"name": "redditdev"}, {"name": "swift"}], "created_utc": 1431999881.0, "key_color": "#cee3f8", "visibility": "private", "icon_name": "", "weighting_scheme": "classic", "path": "/user/sonson_twit/m/english", "description_md": ""}}, {"kind": "LabeledMulti", "data": {"can_edit": true, "display_name": "mine", "name": "mine", "description_html": "", "created": 1432027779.0, "copied_from": null, "icon_url": null, "subreddits": [{"name": "newsokur"}, {"name": "newsokuvip"}], "created_utc": 1431998979.0, "key_color": "#cee3f8", "visibility": "private", "icon_name": "", "weighting_scheme": "classic", "path": "/user/sonson_twit/m/mine", "description_md": ""}}]
--------------------------------------------------------------------------------
/test/data/response/multidesc.json:
--------------------------------------------------------------------------------
1 | {"kind": "LabeledMultiDescription", "data": {"body_html": "<!-- SC_OFF --><div class=\"md\"><p>updated description</p>\n</div><!-- SC_ON -->", "body_md": "updated description"}}
--------------------------------------------------------------------------------
/test/data/thing/LabeledMulti.json:
--------------------------------------------------------------------------------
1 | {
2 | "can_edit": true,
3 | "display_name": "english",
4 | "name": "english",
5 | "description_html": "",
6 | "created": 1432028681,
7 | "copied_from": null,
8 | "icon_url": null,
9 | "subreddits": [
10 | {
11 | "name": "redditdev"
12 | },
13 | {
14 | "name": "swift"
15 | }
16 | ],
17 | "created_utc": 1431999881,
18 | "key_color": "#cee3f8",
19 | "visibility": "private",
20 | "icon_name": "",
21 | "weighting_scheme": "classic",
22 | "path": "/user/sonson_twit/m/english",
23 | "description_md": ""
24 | }
--------------------------------------------------------------------------------
/test/data/thing/LabeledMultiDescription.json:
--------------------------------------------------------------------------------
1 | {
2 | "body_html": "<!-- SC_OFF --><div class=\"md\"><p>updated</p>\n</div><!-- SC_ON -->",
3 | "body_md": "updated"
4 | }
--------------------------------------------------------------------------------
/test/data/thing/UserList.json:
--------------------------------------------------------------------------------
1 | {
2 | "kind": "UserList",
3 | "data": {
4 | "children": [
5 | {
6 | "date": 1382991535,
7 | "mod_permissions": [],
8 | "name": "PicsMod",
9 | "id": "t2_5onsi"
10 | },
11 | {
12 | "date": 1415392097,
13 | "mod_permissions": [
14 | "all"
15 | ],
16 | "name": "cwenham",
17 | "id": "t2_2fpn"
18 | },
19 | {
20 | "date": 1445810001,
21 | "mod_permissions": [
22 | "wiki",
23 | "posts",
24 | "mail",
25 | "flair"
26 | ],
27 | "name": "adeadhead",
28 | "id": "t2_5tt1l"
29 | }
30 | ]
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/test/data/thing/more.json:
--------------------------------------------------------------------------------
1 | {
2 | "count": 0,
3 | "parent_id": "t1_cp88kh5",
4 | "children": [
5 | "cpddp7v",
6 | "cp8jvj8",
7 | "cp8cv4b"
8 | ],
9 | "name": "t1_cpddp7v",
10 | "id": "cpddp7v"
11 | }
--------------------------------------------------------------------------------
/test/data/thing/t1.json:
--------------------------------------------------------------------------------
1 | {
2 | "subreddit_id": "t5_2qizd",
3 | "banned_by": null,
4 | "link_id": "t3_32wnhw",
5 | "likes": true,
6 | "replies": {
7 | "kind": "Listing",
8 | "data": {
9 | "modhash": null,
10 | "children": [
11 | {
12 | "kind": "more",
13 | "data": {
14 | "count": 0,
15 | "parent_id": "t1_cqfhkcb",
16 | "children": [
17 | "cqfmmpp"
18 | ],
19 | "name": "t1_cqfmmpp",
20 | "id": "cqfmmpp"
21 | }
22 | }
23 | ],
24 | "after": null,
25 | "before": null
26 | }
27 | },
28 | "user_reports": [],
29 | "saved": false,
30 | "id": "cqfhkcb",
31 | "gilded": 0,
32 | "archived": false,
33 | "report_reasons": null,
34 | "author": "Icnoyotl",
35 | "parent_id": "t1_cqfh5kz",
36 | "score": 1,
37 | "approved_by": null,
38 | "controversiality": 0,
39 | "body": "The bot has been having this problem for awhile, there have been thousands of new comments since it last worked properly, so it seems like this must be something recurring? Could it have something to do with our AutoModerator?",
40 | "edited": false,
41 | "author_flair_css_class": null,
42 | "downs": 0,
43 | "body_html": "<div class=\"md\"><p>The bot has been having this problem for awhile, there have been thousands of new comments since it last worked properly, so it seems like this must be something recurring? Could it have something to do with our AutoModerator?</p>\n</div>",
44 | "subreddit": "redditdev",
45 | "score_hidden": false,
46 | "name": "t1_cqfhkcb",
47 | "created": 1429284845,
48 | "author_flair_text": null,
49 | "created_utc": 1429281245,
50 | "distinguished": null,
51 | "mod_reports": [],
52 | "num_reports": null,
53 | "ups": 1
54 | }
--------------------------------------------------------------------------------
/test/data/thing/t2.json:
--------------------------------------------------------------------------------
1 | {
2 | "has_mail": false,
3 | "name": "sonson_twit",
4 | "created": 1427126074,
5 | "hide_from_robots": false,
6 | "gold_creddits": 0,
7 | "created_utc": 1427122474,
8 | "has_mod_mail": false,
9 | "link_karma": 1,
10 | "comment_karma": 1,
11 | "over_18": true,
12 | "is_gold": false,
13 | "is_mod": false,
14 | "gold_expiration": null,
15 | "has_verified_email": false,
16 | "id": "mfsh8",
17 | "inbox_count": 0
18 | }
--------------------------------------------------------------------------------
/test/data/thing/t4.json:
--------------------------------------------------------------------------------
1 | {
2 | "body": "Hello! [Hola!](https://www.reddit.com/r/reddit.com/wiki/templat.....",
3 | "was_comment": false,
4 | "first_message": null,
5 | "name": "t4_36sfhx",
6 | "first_message_name": null,
7 | "created": 1427126074,
8 | "dest": "sonson_twit",
9 | "author": "reddit",
10 | "created_utc": 1427122474,
11 | "body_html": "<!-- SC_.....",
12 | "subreddit": null,
13 | "parent_id": null,
14 | "context": "",
15 | "replies": "",
16 | "id": "36sfhx",
17 | "new": false,
18 | "distinguished": "admin",
19 | "subject": "Hello, /u/sonson_twit! Welcome to reddit!"
20 | }
--------------------------------------------------------------------------------
/test/objc-header.h:
--------------------------------------------------------------------------------
1 | //
2 | // objc-header.h
3 | // redditch
4 | //
5 | // Created by sonson on 2015/04/05.
6 | // Copyright (c) 2015年 sonson. All rights reserved.
7 | //
8 |
9 | #ifndef reddift_test_objc_header_h
10 | #define reddift_test_objc_header_h
11 |
12 | #endif
13 |
--------------------------------------------------------------------------------
/test/test_config.json.enc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sonsongithub/reddift/d93320dc35ad81e7bce9e5b76a87654a5bc84d7b/test/test_config.json.enc
--------------------------------------------------------------------------------
/test/test_config.json.sample:
--------------------------------------------------------------------------------
1 | {
2 | "username": "test user account",
3 | "password": "test user password",
4 | "client_id": "test app client ID(must be script type app)",
5 | "secret": "test app secret"
6 | }
--------------------------------------------------------------------------------