Repository: judi0713/TouTiao
Branch: master
Commit: 8c275d26ab51
Files: 40
Total size: 139.4 KB
Directory structure:
gitextract_n5eo_kqa/
├── .gitignore
├── LICENSE
├── Podfile
├── README.md
├── TouTiao/
│ ├── AppDelegate.swift
│ ├── Assets.xcassets/
│ │ ├── AppIcon.appiconset/
│ │ │ └── Contents.json
│ │ ├── Contents.json
│ │ ├── StatusBarButtonImage.imageset/
│ │ │ └── Contents.json
│ │ ├── TouTiao.imageset/
│ │ │ └── Contents.json
│ │ ├── comment-icon.imageset/
│ │ │ └── Contents.json
│ │ ├── icon-settings.imageset/
│ │ │ └── Contents.json
│ │ ├── icon-upvote.imageset/
│ │ │ └── Contents.json
│ │ └── icon.imageset/
│ │ └── Contents.json
│ ├── Base.lproj/
│ │ └── MainMenu.xib
│ ├── Extension/
│ │ ├── NSDate+Extension.swift
│ │ └── String+Extension.swift
│ ├── Info.plist
│ ├── MainViewController.swift
│ ├── Model/
│ │ └── TTModel.swift
│ ├── Network/
│ │ └── NetWorkFetcher.swift
│ ├── PopViewController.swift
│ ├── Service/
│ │ └── EventMonitor.swift
│ ├── TouTiao.entitlements
│ └── View/
│ ├── PopViewController.swift
│ ├── PopViewController.xib
│ ├── SettingMenuAction.swift
│ ├── TTButton.swift
│ └── TTCell.swift
├── TouTiao.xcodeproj/
│ ├── project.pbxproj
│ └── project.xcworkspace/
│ └── contents.xcworkspacedata
├── TouTiao.xcworkspace/
│ └── contents.xcworkspacedata
├── TouTiaoLauncher/
│ ├── AppDelegate.swift
│ ├── Assets.xcassets/
│ │ └── AppIcon.appiconset/
│ │ └── Contents.json
│ ├── Base.lproj/
│ │ └── MainMenu.xib
│ ├── Info.plist
│ └── TouTiaoLauncher.entitlements
├── TouTiaoTests/
│ ├── Info.plist
│ └── TouTiaoTests.swift
└── TouTiaoUITests/
├── Info.plist
└── TouTiaoUITests.swift
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
.DS_Store
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
!default.xcworkspace
xcuserdata
*.moved-aside
*.mobileprovision
DerivedData
.idea/
Pods
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2013 Catch Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: Podfile
================================================
use_frameworks!
target 'TouTiao' do
pod 'Alamofire'
pod 'Fuzi'
end
================================================
FILE: README.md
================================================
# 开发者头条Mac端插件
下载移步 [release](https://github.com/judi0713/TouTiao/releases)
博客 [开发者头条插件小记](http://walkginkgo.com/ios/2016/05/04/Toutiao.html)
## 简介
最主要的是,这个是个人练手mac开发项目..

开发者头条是我日常用的比较多的看技术方面资料的网站。安利了好多人都在用。
> Alamofire不支持10.10的系统,所以低版本适配暂时做不了。有朋友在issue里说Alamofire可以,但是不知道是不是我哪做的不对没搞定..后面要考试了可能没有时间开发了..希望能有人提prprprprpr!!
## 现在这个版本V1.1
现在上了v1.1版本。修复了夜间模式,增加了开机启动。
感谢[droid-Q](https://github.com/droid-Q)提交的pr。我根据他的代码找到了更好的解决方法,增加了nstask。现在默认就是开机启动了。确实之前没有开机启动太蛋疼了..
希望更多人可以参与进来开发。
## 后面预期要做的
增加菊花。
增加网络层判断以及优化。
上拉刷新。
数据缓存。
重构代码。
增加开机启动。
## 最后
大三了时间也不是很多,后面尽量继续维护吧。
## License
MIT
================================================
FILE: TouTiao/AppDelegate.swift
================================================
//
// AppDelegate.swift
// TouTiao
//
// Created by tesths on 4/1/16.
// Copyright © 2016 tesths. All rights reserved.
//
import Cocoa
import ServiceManagement
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet weak var window: NSWindow!
let launcherAppIdentifier = "com.tesths.TouTiaoLauncher"
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Insert code here to initialize your application
startAtLogin()
}
func applicationWillTerminate(_ aNotification: Notification) {
// Insert code here to tear down your application
}
func startAtLogin() {
//you should move this next line to somewhere else this is for testing purposes only!!!
SMLoginItemSetEnabled(launcherAppIdentifier as CFString, true)
var startedAtLogin = false
for app in NSWorkspace.shared().runningApplications {
if app.bundleIdentifier == launcherAppIdentifier {
startedAtLogin = true
}
}
if startedAtLogin {
DistributedNotificationCenter.default().post(name: .killme, object: Bundle.main.bundleIdentifier!)
print("i killed the launcher app!")
}
}
}
extension Notification.Name {
static let killme = Notification.Name("killme")
}
================================================
FILE: TouTiao/Assets.xcassets/AppIcon.appiconset/Contents.json
================================================
{
"images" : [
{
"size" : "16x16",
"idiom" : "mac",
"filename" : "开发者头条圆角矩形-7.png",
"scale" : "1x"
},
{
"size" : "16x16",
"idiom" : "mac",
"filename" : "开发者头条圆角矩形-6.png",
"scale" : "2x"
},
{
"size" : "32x32",
"idiom" : "mac",
"filename" : "开发者头条圆角矩形-5.png",
"scale" : "1x"
},
{
"size" : "32x32",
"idiom" : "mac",
"filename" : "开发者头条圆角矩形-4.png",
"scale" : "2x"
},
{
"size" : "128x128",
"idiom" : "mac",
"filename" : "开发者头条圆角矩形-3.png",
"scale" : "1x"
},
{
"size" : "128x128",
"idiom" : "mac",
"filename" : "开发者头条圆角矩形-2.png",
"scale" : "2x"
},
{
"size" : "256x256",
"idiom" : "mac",
"filename" : "开发者头条圆角矩形-1.png",
"scale" : "1x"
},
{
"size" : "256x256",
"idiom" : "mac",
"filename" : "开发者头条圆角矩形.png",
"scale" : "2x"
},
{
"size" : "512x512",
"idiom" : "mac",
"filename" : "开发者头条圆角矩形-9.png",
"scale" : "1x"
},
{
"size" : "512x512",
"idiom" : "mac",
"filename" : "开发者头条圆角矩形-8.png",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: TouTiao/Assets.xcassets/Contents.json
================================================
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: TouTiao/Assets.xcassets/StatusBarButtonImage.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "mac"
},
{
"idiom" : "mac",
"scale" : "1x"
},
{
"idiom" : "mac",
"filename" : "StatusBarButtonImage@2x.png",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: TouTiao/Assets.xcassets/TouTiao.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "mac",
"scale" : "1x"
},
{
"idiom" : "mac",
"filename" : "TouTiao@2x.png",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"template-rendering-intent" : "template"
}
}
================================================
FILE: TouTiao/Assets.xcassets/comment-icon.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "mac",
"scale" : "1x"
},
{
"idiom" : "mac",
"filename" : "icon-comment@2x.png",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: TouTiao/Assets.xcassets/icon-settings.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "mac",
"scale" : "1x"
},
{
"idiom" : "mac",
"filename" : "icon-settings.png",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: TouTiao/Assets.xcassets/icon-upvote.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "mac",
"scale" : "1x"
},
{
"idiom" : "mac",
"filename" : "vote.png",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: TouTiao/Assets.xcassets/icon.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "apple-icon-180x180.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: TouTiao/Base.lproj/MainMenu.xib
================================================
================================================
FILE: TouTiao/Extension/NSDate+Extension.swift
================================================
//
// NSDate+Extension.swift
// TouTiao
//
// Created by plusub on 4/26/16.
// Copyright © 2016 tesths. All rights reserved.
//
import Cocoa
extension Date
{
func hour() -> Int
{
//Get Hour
let calendar = Calendar.current
let components = (calendar as NSCalendar).components(.hour, from: self)
let hour = components.hour
//Return Hour
return hour!
}
func minute() -> Int
{
//Get Minute
let calendar = Calendar.current
let components = (calendar as NSCalendar).components(.minute, from: self)
let minute = components.minute
//Return Minute
return minute!
}
func toShortTimeString() -> String
{
//Get Short Time String
let formatter = DateFormatter()
formatter.timeStyle = .short
let timeString = formatter.string(from: self)
//Return Short Time String
return timeString
}
}
================================================
FILE: TouTiao/Extension/String+Extension.swift
================================================
//
// String+Extension.swift
// NotLonely-iOS
//
// Created by plusub on 3/16/16.
// Copyright © 2016 cm. All rights reserved.
//
import Foundation
extension String {
var length: Int {
return characters.count
}
}
================================================
FILE: TouTiao/Info.plist
================================================
CFBundleDevelopmentRegion
en
CFBundleExecutable
$(EXECUTABLE_NAME)
CFBundleIconFile
CFBundleIdentifier
$(PRODUCT_BUNDLE_IDENTIFIER)
CFBundleInfoDictionaryVersion
6.0
CFBundleName
$(PRODUCT_NAME)
CFBundlePackageType
APPL
CFBundleShortVersionString
1.1
CFBundleSignature
????
CFBundleVersion
1.1
LSApplicationCategoryType
public.app-category.news
LSMinimumSystemVersion
$(MACOSX_DEPLOYMENT_TARGET)
LSUIElement
NSAppTransportSecurity
NSAllowsArbitraryLoads
NSHumanReadableCopyright
Copyright © 2016 tesths. All rights reserved.
NSMainNibFile
MainMenu
NSPrincipalClass
NSApplication
================================================
FILE: TouTiao/MainViewController.swift
================================================
//
// MainViewController.swift
// TouTiao
//
// Created by tesths on 4/1/16.
// Copyright © 2016 tesths. All rights reserved.
//
import Cocoa
class MainViewController: NSViewController {
let statusItem = NSStatusBar.system().statusItem(withLength: -2)
let popover = NSPopover()
var eventMonitor: EventMonitor?
override func awakeFromNib() {
if let button = statusItem.button {
button.image = NSImage(named: "TouTiao")
button.action = #selector(MainViewController.togglePopover(_:))
}
popover.behavior = .transient
popover.contentViewController = PopViewController(nibName: "PopViewController", bundle: nil)
popover.appearance = NSAppearance(named: NSAppearanceNameAqua)
popover.behavior = .transient
eventMonitor = EventMonitor(mask: [.leftMouseDown, .rightMouseDown]) { [unowned self] event in
if self.popover.isShown {
self.closePopover(event)
}
}
eventMonitor?.start()
addToLoginItems()
}
override func viewDidLoad() {
super.viewDidLoad()
// Do view setup here.
}
func addToLoginItems() {
// Process.launchedProcess(
// launchPath: "/usr/bin/osascript",
// arguments: [
// "-e",
// "tell application \"System Events\" to make login item at end with properties {path:\"/Applications/TouTiao.app\", hidden:false, name:\"Compute for TouTiao\"}"
// ]
// )
}
func togglePopover(_ sender: AnyObject?) {
if popover.isShown {
closePopover(sender)
} else {
showPopover(sender)
}
}
func showPopover(_ sender: AnyObject?) {
if let button = statusItem.button {
popover.show(relativeTo: button.bounds, of: button, preferredEdge: NSRectEdge.minY)
}
NotificationCenter.default.post(name: Notification.Name(rawValue: "Reload"), object: nil)
eventMonitor?.start()
}
func closePopover(_ sender: AnyObject?) {
popover.performClose(sender)
eventMonitor?.stop()
}
func quit() {
NSApplication.shared().terminate(self)
}
}
================================================
FILE: TouTiao/Model/TTModel.swift
================================================
//
// TTModel.swift
// TouTiao
//
// Created by tesths on 4/11/16.
// Copyright © 2016 tesths. All rights reserved.
//
import Foundation
struct TTModel {
let title: String
let url: String
let href: String
let like: String
let comment: String
}
================================================
FILE: TouTiao/Network/NetWorkFetcher.swift
================================================
//
// NetWorkFetcher.swift
// TouTiao
//
// Created by tesths on 4/11/16.
// Copyright © 2016 tesths. All rights reserved.
//
import Cocoa
import Alamofire
import Fuzi
class NetWorkFetcher: NSObject {
let url = "https://toutiao.io/"
let Hoturl = "https://toutiao.io/posts/hot/7"
let Javaurl = "https://toutiao.io/c/java"
let iOSurl = "https://toutiao.io/c/ios"
let Weburl = "https://toutiao.io/c/fe"
func getReleases(url: String, _ done: @escaping (_ model: [TTModel]?) -> ()) {
Alamofire.request(url, method: .get )
.responseString { response in
guard let html = response.result.value else {
return done(nil)
}
let document = try? XMLDocument(string: html)
let body = document!.xpath("//div[@class='post']")
let releases = body.map { return self.release($0) }.flatMap { return $0 }
done(releases)
}
}
func release(_ element: Fuzi.XMLElement) -> [TTModel] {
var model = [TTModel]()
var url = String()
var href = String()
var title = String()
var like = String()
var comment = String()
let pth = element.xpath(".//div[@class='btn-group-vertical upvote']")
pth.forEach {tt in
for (index, element) in tt.xpath(".//span").enumerated() {
if index == 0 {
like = element.stringValue
break
}
}
}
let pth1 = element.xpath(".//div[@class='meta']/span")
pth1.forEach {tt in
let value = tt.stringValue
comment = value.trimmingCharacters(in: .whitespacesAndNewlines)
}
let pth2 = element.xpath(".//div[@class='meta']")
pth2.forEach {tt in
let value = tt.stringValue.components(separatedBy: "\n")
url = value[1].trimmingCharacters(in: .whitespacesAndNewlines)
}
let pth3 = element.xpath(".//h3[@class='title']/a")
pth3.forEach {tt in
pth3.forEach { pth in
href = pth["href"]!
title = pth.stringValue
}
}
model.append(
TTModel(
title: title,
url: url,
href: href,
like: like,
comment: comment
)
)
return model
}
}
================================================
FILE: TouTiao/PopViewController.swift
================================================
//
// PopViewController.swift
// TouTiao
//
// Created by tesths on 4/1/16.
// Copyright © 2016 tesths. All rights reserved.
//
import Cocoa
class PopViewController: NSViewController {
let fetcher = NetWorkFetcher()
@IBOutlet weak var headView: NSView! {
didSet {
headView.wantsLayer = true
headView.layer?.backgroundColor = NSColor(red:0.16, green:0.69, blue:0.93, alpha:1.00).CGColor
}
}
@IBOutlet weak var titleLabel: NSTextField! {
didSet {
titleLabel.font = NSFont.systemFontOfSize(14)
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do view setup here.
fetcher.getReleases{
result in
print(result)
}
fetcher.gettest {
result in
print(result)
}
}
}
// MARK: - NSTableViewDataSource
extension PopViewController: NSTableViewDataSource {
func numberOfRowsInTableView(aTableView: NSTableView) -> Int {
return 5
}
func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView? {
let cellView = tableView.makeViewWithIdentifier(tableColumn!.identifier, owner: tableView) as! NSTableCellView
if tableColumn!.identifier == "TouTiaoCell" {
cellView.textField!.stringValue = "123"
return cellView
}
return cellView
}
}
extension PopViewController: NSTableViewDelegate {
}
================================================
FILE: TouTiao/Service/EventMonitor.swift
================================================
//
// EventMonitor.swift
// TouTiao
//
// Created by plusub on 4/22/16.
// Copyright © 2016 tesths. All rights reserved.
//
import Cocoa
open class EventMonitor {
fileprivate var monitor: AnyObject?
fileprivate let mask: NSEventMask
fileprivate let handler: (NSEvent?) -> ()
public init(mask: NSEventMask, handler: @escaping (NSEvent?) -> ()) {
self.mask = mask
self.handler = handler
}
deinit {
stop()
}
open func start() {
monitor = NSEvent.addGlobalMonitorForEvents(matching: mask, handler: handler) as AnyObject?
}
open func stop() {
if monitor != nil {
NSEvent.removeMonitor(monitor!)
monitor = nil
}
}
}
================================================
FILE: TouTiao/TouTiao.entitlements
================================================
com.apple.security.app-sandbox
com.apple.security.network.client
================================================
FILE: TouTiao/View/PopViewController.swift
================================================
//
// PopViewController.swift
// TouTiao
//
// Created by tesths on 4/1/16.
// Copyright © 2016 tesths. All rights reserved.
//
import Cocoa
import Fuzi
//import Kanna
class PopViewController: NSViewController {
let fetcher = NetWorkFetcher()
var model = [TTModel]()
let webHome = "https://toutiao.io"
var postUrl : String = ""
@IBOutlet weak var tableView: NSTableView!
@IBOutlet weak var timeTextView: NSTextField!
@IBAction func toutiaoPost(_ sender: Any) {
postUrl = fetcher.url
reloadData()
}
@IBAction func hotPost(_ sender: Any) {
postUrl = fetcher.Hoturl
reloadData()
}
@IBAction func JavaPost(_ sender: Any) {
postUrl = fetcher.Javaurl
reloadData()
}
@IBAction func iOSPost(_ sender: Any) {
postUrl = fetcher.iOSurl
reloadData()
}
@IBAction func WebPost(_ sender: Any) {
postUrl = fetcher.Weburl
reloadData()
}
@IBOutlet weak var headerView: NSView! {
didSet {
headerView.wantsLayer = true
headerView.layer?.backgroundColor = NSColor.white.cgColor
}
}
@IBOutlet weak var footerView: NSView! {
didSet {
footerView.wantsLayer = true
footerView.layer?.backgroundColor = NSColor.init(red:0.16, green:0.69, blue:0.93, alpha:1.00).cgColor
}
}
@IBOutlet weak var titleLabel: NSTextField! {
didSet {
titleLabel.font = NSFont.systemFont(ofSize: 14)
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do view setup here.
NotificationCenter.default.addObserver(self, selector: #selector(PopViewController.reloadData), name:NSNotification.Name(rawValue: "Reload"), object: nil)
postUrl = fetcher.url
}
@IBAction func toggleSettingButton(_ sender: NSView) {
let menu = SettingMenuAction()
menu.perform(sender)
}
func reloadData() {
fetcher.getReleases(url: postUrl) {
result in
self.model = result!
self.tableView.reloadData()
self.setTime()
}
}
func setTime() {
let currentDate = Date()
timeTextView.stringValue = "更新时间 \(currentDate.toShortTimeString())"
}
}
// MARK: - NSTableViewDataSource
extension PopViewController: NSTableViewDataSource {
func numberOfRows(in aTableView: NSTableView) -> Int {
return model.count
}
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
let cellView = tableView.make(withIdentifier: tableColumn!.identifier, owner: tableView) as! TTCell
cellView.configureData(self.model[row])
return cellView
}
}
extension PopViewController: NSTableViewDelegate {
func tableViewSelectionDidChange(_ notification: Notification) {
let table = notification.object as! NSTableView
print(URL(string: model[table.selectedRow].href)!)
NSWorkspace.shared().open(URL(string: webHome + model[table.selectedRow].href)!)
}
}
================================================
FILE: TouTiao/View/PopViewController.xib
================================================
================================================
FILE: TouTiao/View/SettingMenuAction.swift
================================================
//
// SettingMenuAction.swift
// TouTiao
//
// Created by plusub on 4/26/16.
// Copyright © 2016 tesths. All rights reserved.
//
import Cocoa
import ServiceManagement
class SettingMenuAction {
let launcherAppIdentifier = "com.tesths.TouTiaoLauncher"
var autoLaunch: Bool = true
let startMenu = NSMenuItem(title: "开机启动", action: #selector(startLogin), keyEquivalent: "")
func perform(_ sender: NSView) {
let delegate = NSApplication.shared().delegate as! MainViewController
let menu = NSMenu()
// let hotShare = NSMenuItem()
// hotShare.title = "热门分享"
// let share7 = NSMenu(title: "最近 7 天")
// let share30 = NSMenu(title: "最近 30 天")
// let share30 = NSMenu().addItem(withTitle: "最近 30 天", action: #selector(delegate.quit), keyEquivalent: "q")
// let hare90 = NSMenu().addItem(withTitle: "最近 90 天", action: #selector(delegate.quit), keyEquivalent: "q")
// hotShare.submenu = share7
// hotShare.submenu = share30
// menu.addItem(NSMenuItem(title: "开机启动", action: #selector(startLogin), keyEquivalent: ""))
menu.addItem(NSMenuItem(title: "退出", action: #selector(delegate.quit), keyEquivalent: "q"))
NSMenu.popUpContextMenu(menu, with: NSApp.currentEvent!, for: sender)
}
@objc func startLogin() {
autoLaunch = !autoLaunch
if autoLaunch == true {
startMenu.title = "开机启动"
} else {
startMenu.title = "开机不启动"
}
SMLoginItemSetEnabled(launcherAppIdentifier as CFString, autoLaunch)
}
}
================================================
FILE: TouTiao/View/TTButton.swift
================================================
//
// TTButton.swift
// TouTiao
//
// Created by tesths on 25/03/2017.
// Copyright © 2017 tesths. All rights reserved.
//
import Cocoa
@IBDesignable
class TTButton: NSButton
{
@IBInspectable var bgColor: NSColor?
@IBInspectable var textColor: NSColor?
override func awakeFromNib()
{
if let textColor = textColor, let font = font
{
let style = NSMutableParagraphStyle()
style.alignment = .center
let attributes =
[
NSForegroundColorAttributeName: textColor,
NSFontAttributeName: font,
NSParagraphStyleAttributeName: style
] as [String : Any]
let attributedTitle = NSAttributedString(string: title, attributes: attributes)
self.attributedTitle = attributedTitle
}
}
override func draw(_ dirtyRect: NSRect)
{
if let bgColor = bgColor
{
bgColor.setFill()
NSRectFill(dirtyRect)
}
super.draw(dirtyRect)
}
}
================================================
FILE: TouTiao/View/TTCell.swift
================================================
//
// TTCell.swift
// TouTiao
//
// Created by plusub on 4/24/16.
// Copyright © 2016 tesths. All rights reserved.
//
import Cocoa
class TTCell: NSTableCellView {
@IBOutlet weak var titleTextView: NSTextField!
@IBOutlet weak var urlTextField: NSTextField!
@IBOutlet weak var voteTextField: NSTextField!
@IBOutlet weak var commentTextField: NSTextField!
override func awakeFromNib() {
super.awakeFromNib()
wantsLayer = true
layer?.backgroundColor = NSColor.white.cgColor
}
func configureData(_ model: TTModel) {
self.titleTextView.stringValue = model.title
self.urlTextField.stringValue = model.url
self.voteTextField.stringValue = model.like
self.commentTextField.stringValue = model.comment
}
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
}
}
================================================
FILE: TouTiao.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
0632F8C91E866CDE002A7058 /* TTButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0632F8C81E866CDE002A7058 /* TTButton.swift */; };
0632F8D11E8681EE002A7058 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0632F8D01E8681EE002A7058 /* AppDelegate.swift */; };
0632F8D31E8681EE002A7058 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0632F8D21E8681EE002A7058 /* Assets.xcassets */; };
0632F8D61E8681EE002A7058 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0632F8D41E8681EE002A7058 /* MainMenu.xib */; };
0632F8DE1E8682F8002A7058 /* TouTiaoLauncher.app in Resources */ = {isa = PBXBuildFile; fileRef = 0632F8CE1E8681EE002A7058 /* TouTiaoLauncher.app */; };
0632F8E41E868363002A7058 /* TouTiaoLauncher.app in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0632F8CE1E8681EE002A7058 /* TouTiaoLauncher.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
06541A2B1CBB6074004312AC /* TTModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06541A2A1CBB6074004312AC /* TTModel.swift */; };
06541A2E1CBB61B2004312AC /* NetWorkFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06541A2D1CBB61B2004312AC /* NetWorkFetcher.swift */; };
0673B73B1CAE2D06001FBF40 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0673B73A1CAE2D06001FBF40 /* AppDelegate.swift */; };
0673B73D1CAE2D06001FBF40 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0673B73C1CAE2D06001FBF40 /* Assets.xcassets */; };
0673B7401CAE2D06001FBF40 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0673B73E1CAE2D06001FBF40 /* MainMenu.xib */; };
0673B74B1CAE2D06001FBF40 /* TouTiaoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0673B74A1CAE2D06001FBF40 /* TouTiaoTests.swift */; };
0673B7561CAE2D06001FBF40 /* TouTiaoUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0673B7551CAE2D06001FBF40 /* TouTiaoUITests.swift */; };
0673B7681CAE32E1001FBF40 /* MainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0673B7671CAE32E1001FBF40 /* MainViewController.swift */; };
06953AEE1CBCB3040001D698 /* String+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06953AED1CBCB3040001D698 /* String+Extension.swift */; };
74355EC41CCA43BA0029999B /* EventMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74355EC31CCA43BA0029999B /* EventMonitor.swift */; };
7484FE131CCF692300560763 /* NSDate+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7484FE121CCF692300560763 /* NSDate+Extension.swift */; };
7484FE161CCF72B300560763 /* SettingMenuAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7484FE151CCF72B300560763 /* SettingMenuAction.swift */; };
74D0AD2B1CC7A47F00126706 /* PopViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74D0AD291CC7A47F00126706 /* PopViewController.swift */; };
74D0AD2C1CC7A47F00126706 /* PopViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 74D0AD2A1CC7A47F00126706 /* PopViewController.xib */; };
74E7E49B1CCCB64B00DCAE46 /* TTCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74E7E49A1CCCB64B00DCAE46 /* TTCell.swift */; };
FC007F7B55726384DC59FE30 /* Pods_TouTiao.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C000B9EB5493E17915C8E77D /* Pods_TouTiao.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
0632F8DF1E8682F8002A7058 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 0673B72F1CAE2D06001FBF40 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 0632F8CD1E8681EE002A7058;
remoteInfo = TouTiaoLauncher;
};
0673B7471CAE2D06001FBF40 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 0673B72F1CAE2D06001FBF40 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 0673B7361CAE2D06001FBF40;
remoteInfo = TouTiao;
};
0673B7521CAE2D06001FBF40 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 0673B72F1CAE2D06001FBF40 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 0673B7361CAE2D06001FBF40;
remoteInfo = TouTiao;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
0632F8E31E86835A002A7058 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = Contents/Library/LoginItems;
dstSubfolderSpec = 1;
files = (
0632F8E41E868363002A7058 /* TouTiaoLauncher.app in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
060165521E82036D0041842D /* TouTiao.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = TouTiao.entitlements; sourceTree = ""; };
0632F8C81E866CDE002A7058 /* TTButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TTButton.swift; sourceTree = ""; };
0632F8CE1E8681EE002A7058 /* TouTiaoLauncher.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TouTiaoLauncher.app; sourceTree = BUILT_PRODUCTS_DIR; };
0632F8D01E8681EE002A7058 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
0632F8D21E8681EE002A7058 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
0632F8D51E8681EE002A7058 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; };
0632F8D71E8681EE002A7058 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
0632F8DB1E86823C002A7058 /* TouTiaoLauncher.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = TouTiaoLauncher.entitlements; sourceTree = ""; };
06541A2A1CBB6074004312AC /* TTModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TTModel.swift; sourceTree = ""; };
06541A2D1CBB61B2004312AC /* NetWorkFetcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetWorkFetcher.swift; sourceTree = ""; };
0673B7371CAE2D06001FBF40 /* TouTiao.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TouTiao.app; sourceTree = BUILT_PRODUCTS_DIR; };
0673B73A1CAE2D06001FBF40 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
0673B73C1CAE2D06001FBF40 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
0673B73F1CAE2D06001FBF40 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; };
0673B7411CAE2D06001FBF40 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
0673B7461CAE2D06001FBF40 /* TouTiaoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TouTiaoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
0673B74A1CAE2D06001FBF40 /* TouTiaoTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TouTiaoTests.swift; sourceTree = ""; };
0673B74C1CAE2D06001FBF40 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
0673B7511CAE2D06001FBF40 /* TouTiaoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TouTiaoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
0673B7551CAE2D06001FBF40 /* TouTiaoUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TouTiaoUITests.swift; sourceTree = ""; };
0673B7571CAE2D06001FBF40 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
0673B7671CAE32E1001FBF40 /* MainViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainViewController.swift; sourceTree = ""; };
06953AED1CBCB3040001D698 /* String+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+Extension.swift"; sourceTree = ""; };
57BAB250D52BE0BE8AE45323 /* Pods-TouTiao.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TouTiao.debug.xcconfig"; path = "Pods/Target Support Files/Pods-TouTiao/Pods-TouTiao.debug.xcconfig"; sourceTree = ""; };
74355EC31CCA43BA0029999B /* EventMonitor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EventMonitor.swift; sourceTree = ""; };
7484FE121CCF692300560763 /* NSDate+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSDate+Extension.swift"; sourceTree = ""; };
7484FE151CCF72B300560763 /* SettingMenuAction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingMenuAction.swift; sourceTree = ""; };
74D0AD291CC7A47F00126706 /* PopViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PopViewController.swift; sourceTree = ""; };
74D0AD2A1CC7A47F00126706 /* PopViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PopViewController.xib; sourceTree = ""; };
74E7E49A1CCCB64B00DCAE46 /* TTCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TTCell.swift; sourceTree = ""; };
975E04C1B55E348097BD00B9 /* Pods-TouTiao.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TouTiao.release.xcconfig"; path = "Pods/Target Support Files/Pods-TouTiao/Pods-TouTiao.release.xcconfig"; sourceTree = ""; };
C000B9EB5493E17915C8E77D /* Pods_TouTiao.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_TouTiao.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
0632F8CB1E8681EE002A7058 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
0673B7341CAE2D06001FBF40 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
FC007F7B55726384DC59FE30 /* Pods_TouTiao.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
0673B7431CAE2D06001FBF40 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
0673B74E1CAE2D06001FBF40 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
0632F8CF1E8681EE002A7058 /* TouTiaoLauncher */ = {
isa = PBXGroup;
children = (
0632F8DB1E86823C002A7058 /* TouTiaoLauncher.entitlements */,
0632F8D01E8681EE002A7058 /* AppDelegate.swift */,
0632F8D21E8681EE002A7058 /* Assets.xcassets */,
0632F8D41E8681EE002A7058 /* MainMenu.xib */,
0632F8D71E8681EE002A7058 /* Info.plist */,
);
path = TouTiaoLauncher;
sourceTree = "";
};
06541A271CBB5EDE004312AC /* Extension */ = {
isa = PBXGroup;
children = (
06953AED1CBCB3040001D698 /* String+Extension.swift */,
7484FE121CCF692300560763 /* NSDate+Extension.swift */,
);
path = Extension;
sourceTree = "";
};
06541A281CBB5EDE004312AC /* Model */ = {
isa = PBXGroup;
children = (
06541A2A1CBB6074004312AC /* TTModel.swift */,
);
path = Model;
sourceTree = "";
};
06541A291CBB5EDE004312AC /* View */ = {
isa = PBXGroup;
children = (
74D0AD291CC7A47F00126706 /* PopViewController.swift */,
74D0AD2A1CC7A47F00126706 /* PopViewController.xib */,
74E7E49A1CCCB64B00DCAE46 /* TTCell.swift */,
7484FE151CCF72B300560763 /* SettingMenuAction.swift */,
0632F8C81E866CDE002A7058 /* TTButton.swift */,
);
path = View;
sourceTree = "";
};
06541A2C1CBB619B004312AC /* Network */ = {
isa = PBXGroup;
children = (
06541A2D1CBB61B2004312AC /* NetWorkFetcher.swift */,
);
path = Network;
sourceTree = "";
};
0673B72E1CAE2D06001FBF40 = {
isa = PBXGroup;
children = (
0673B7391CAE2D06001FBF40 /* TouTiao */,
0673B7491CAE2D06001FBF40 /* TouTiaoTests */,
0673B7541CAE2D06001FBF40 /* TouTiaoUITests */,
0632F8CF1E8681EE002A7058 /* TouTiaoLauncher */,
0673B7381CAE2D06001FBF40 /* Products */,
6452FF8988F66956159D5EB8 /* Pods */,
5616DC1A69F16F3000F21CFD /* Frameworks */,
);
sourceTree = "";
};
0673B7381CAE2D06001FBF40 /* Products */ = {
isa = PBXGroup;
children = (
0673B7371CAE2D06001FBF40 /* TouTiao.app */,
0673B7461CAE2D06001FBF40 /* TouTiaoTests.xctest */,
0673B7511CAE2D06001FBF40 /* TouTiaoUITests.xctest */,
0632F8CE1E8681EE002A7058 /* TouTiaoLauncher.app */,
);
name = Products;
sourceTree = "";
};
0673B7391CAE2D06001FBF40 /* TouTiao */ = {
isa = PBXGroup;
children = (
060165521E82036D0041842D /* TouTiao.entitlements */,
74355EC21CCA439B0029999B /* Service */,
06541A2C1CBB619B004312AC /* Network */,
06541A271CBB5EDE004312AC /* Extension */,
06541A281CBB5EDE004312AC /* Model */,
06541A291CBB5EDE004312AC /* View */,
0673B73A1CAE2D06001FBF40 /* AppDelegate.swift */,
0673B7671CAE32E1001FBF40 /* MainViewController.swift */,
0673B73C1CAE2D06001FBF40 /* Assets.xcassets */,
0673B73E1CAE2D06001FBF40 /* MainMenu.xib */,
0673B7411CAE2D06001FBF40 /* Info.plist */,
);
path = TouTiao;
sourceTree = "";
};
0673B7491CAE2D06001FBF40 /* TouTiaoTests */ = {
isa = PBXGroup;
children = (
0673B74A1CAE2D06001FBF40 /* TouTiaoTests.swift */,
0673B74C1CAE2D06001FBF40 /* Info.plist */,
);
path = TouTiaoTests;
sourceTree = "";
};
0673B7541CAE2D06001FBF40 /* TouTiaoUITests */ = {
isa = PBXGroup;
children = (
0673B7551CAE2D06001FBF40 /* TouTiaoUITests.swift */,
0673B7571CAE2D06001FBF40 /* Info.plist */,
);
path = TouTiaoUITests;
sourceTree = "";
};
5616DC1A69F16F3000F21CFD /* Frameworks */ = {
isa = PBXGroup;
children = (
C000B9EB5493E17915C8E77D /* Pods_TouTiao.framework */,
);
name = Frameworks;
sourceTree = "";
};
6452FF8988F66956159D5EB8 /* Pods */ = {
isa = PBXGroup;
children = (
57BAB250D52BE0BE8AE45323 /* Pods-TouTiao.debug.xcconfig */,
975E04C1B55E348097BD00B9 /* Pods-TouTiao.release.xcconfig */,
);
name = Pods;
sourceTree = "";
};
74355EC21CCA439B0029999B /* Service */ = {
isa = PBXGroup;
children = (
74355EC31CCA43BA0029999B /* EventMonitor.swift */,
);
path = Service;
sourceTree = "";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
0632F8CD1E8681EE002A7058 /* TouTiaoLauncher */ = {
isa = PBXNativeTarget;
buildConfigurationList = 0632F8D81E8681EE002A7058 /* Build configuration list for PBXNativeTarget "TouTiaoLauncher" */;
buildPhases = (
0632F8CA1E8681EE002A7058 /* Sources */,
0632F8CB1E8681EE002A7058 /* Frameworks */,
0632F8CC1E8681EE002A7058 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = TouTiaoLauncher;
productName = TouTiaoLauncher;
productReference = 0632F8CE1E8681EE002A7058 /* TouTiaoLauncher.app */;
productType = "com.apple.product-type.application";
};
0673B7361CAE2D06001FBF40 /* TouTiao */ = {
isa = PBXNativeTarget;
buildConfigurationList = 0673B75A1CAE2D06001FBF40 /* Build configuration list for PBXNativeTarget "TouTiao" */;
buildPhases = (
52B0ED3AB7C7A3109812DE9C /* [CP] Check Pods Manifest.lock */,
0673B7331CAE2D06001FBF40 /* Sources */,
0673B7341CAE2D06001FBF40 /* Frameworks */,
0673B7351CAE2D06001FBF40 /* Resources */,
B91C8649C7C920E3ADBF3C3D /* [CP] Embed Pods Frameworks */,
92770A1D9D011A674360C60F /* [CP] Copy Pods Resources */,
0632F8E31E86835A002A7058 /* CopyFiles */,
);
buildRules = (
);
dependencies = (
0632F8E01E8682F8002A7058 /* PBXTargetDependency */,
);
name = TouTiao;
productName = TouTiao;
productReference = 0673B7371CAE2D06001FBF40 /* TouTiao.app */;
productType = "com.apple.product-type.application";
};
0673B7451CAE2D06001FBF40 /* TouTiaoTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 0673B75D1CAE2D06001FBF40 /* Build configuration list for PBXNativeTarget "TouTiaoTests" */;
buildPhases = (
0673B7421CAE2D06001FBF40 /* Sources */,
0673B7431CAE2D06001FBF40 /* Frameworks */,
0673B7441CAE2D06001FBF40 /* Resources */,
);
buildRules = (
);
dependencies = (
0673B7481CAE2D06001FBF40 /* PBXTargetDependency */,
);
name = TouTiaoTests;
productName = TouTiaoTests;
productReference = 0673B7461CAE2D06001FBF40 /* TouTiaoTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
0673B7501CAE2D06001FBF40 /* TouTiaoUITests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 0673B7601CAE2D06001FBF40 /* Build configuration list for PBXNativeTarget "TouTiaoUITests" */;
buildPhases = (
0673B74D1CAE2D06001FBF40 /* Sources */,
0673B74E1CAE2D06001FBF40 /* Frameworks */,
0673B74F1CAE2D06001FBF40 /* Resources */,
);
buildRules = (
);
dependencies = (
0673B7531CAE2D06001FBF40 /* PBXTargetDependency */,
);
name = TouTiaoUITests;
productName = TouTiaoUITests;
productReference = 0673B7511CAE2D06001FBF40 /* TouTiaoUITests.xctest */;
productType = "com.apple.product-type.bundle.ui-testing";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
0673B72F1CAE2D06001FBF40 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0820;
LastUpgradeCheck = 0820;
ORGANIZATIONNAME = tesths;
TargetAttributes = {
0632F8CD1E8681EE002A7058 = {
CreatedOnToolsVersion = 8.2.1;
DevelopmentTeam = UTN47S84JC;
ProvisioningStyle = Automatic;
SystemCapabilities = {
com.apple.Sandbox = {
enabled = 1;
};
};
};
0673B7361CAE2D06001FBF40 = {
CreatedOnToolsVersion = 7.3;
DevelopmentTeam = UTN47S84JC;
LastSwiftMigration = 0800;
ProvisioningStyle = Automatic;
SystemCapabilities = {
com.apple.Sandbox = {
enabled = 1;
};
};
};
0673B7451CAE2D06001FBF40 = {
CreatedOnToolsVersion = 7.3;
LastSwiftMigration = 0800;
TestTargetID = 0673B7361CAE2D06001FBF40;
};
0673B7501CAE2D06001FBF40 = {
CreatedOnToolsVersion = 7.3;
LastSwiftMigration = 0800;
TestTargetID = 0673B7361CAE2D06001FBF40;
};
};
};
buildConfigurationList = 0673B7321CAE2D06001FBF40 /* Build configuration list for PBXProject "TouTiao" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 0673B72E1CAE2D06001FBF40;
productRefGroup = 0673B7381CAE2D06001FBF40 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
0673B7361CAE2D06001FBF40 /* TouTiao */,
0673B7451CAE2D06001FBF40 /* TouTiaoTests */,
0673B7501CAE2D06001FBF40 /* TouTiaoUITests */,
0632F8CD1E8681EE002A7058 /* TouTiaoLauncher */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
0632F8CC1E8681EE002A7058 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0632F8D31E8681EE002A7058 /* Assets.xcassets in Resources */,
0632F8D61E8681EE002A7058 /* MainMenu.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
0673B7351CAE2D06001FBF40 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
74D0AD2C1CC7A47F00126706 /* PopViewController.xib in Resources */,
0632F8DE1E8682F8002A7058 /* TouTiaoLauncher.app in Resources */,
0673B73D1CAE2D06001FBF40 /* Assets.xcassets in Resources */,
0673B7401CAE2D06001FBF40 /* MainMenu.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
0673B7441CAE2D06001FBF40 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
0673B74F1CAE2D06001FBF40 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
52B0ED3AB7C7A3109812DE9C /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
92770A1D9D011A674360C60F /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-TouTiao/Pods-TouTiao-resources.sh\"\n";
showEnvVarsInLog = 0;
};
B91C8649C7C920E3ADBF3C3D /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-TouTiao/Pods-TouTiao-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
0632F8CA1E8681EE002A7058 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0632F8D11E8681EE002A7058 /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
0673B7331CAE2D06001FBF40 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
06541A2E1CBB61B2004312AC /* NetWorkFetcher.swift in Sources */,
0673B7681CAE32E1001FBF40 /* MainViewController.swift in Sources */,
74D0AD2B1CC7A47F00126706 /* PopViewController.swift in Sources */,
7484FE161CCF72B300560763 /* SettingMenuAction.swift in Sources */,
7484FE131CCF692300560763 /* NSDate+Extension.swift in Sources */,
06541A2B1CBB6074004312AC /* TTModel.swift in Sources */,
74355EC41CCA43BA0029999B /* EventMonitor.swift in Sources */,
0632F8C91E866CDE002A7058 /* TTButton.swift in Sources */,
0673B73B1CAE2D06001FBF40 /* AppDelegate.swift in Sources */,
06953AEE1CBCB3040001D698 /* String+Extension.swift in Sources */,
74E7E49B1CCCB64B00DCAE46 /* TTCell.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
0673B7421CAE2D06001FBF40 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0673B74B1CAE2D06001FBF40 /* TouTiaoTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
0673B74D1CAE2D06001FBF40 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0673B7561CAE2D06001FBF40 /* TouTiaoUITests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
0632F8E01E8682F8002A7058 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 0632F8CD1E8681EE002A7058 /* TouTiaoLauncher */;
targetProxy = 0632F8DF1E8682F8002A7058 /* PBXContainerItemProxy */;
};
0673B7481CAE2D06001FBF40 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 0673B7361CAE2D06001FBF40 /* TouTiao */;
targetProxy = 0673B7471CAE2D06001FBF40 /* PBXContainerItemProxy */;
};
0673B7531CAE2D06001FBF40 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 0673B7361CAE2D06001FBF40 /* TouTiao */;
targetProxy = 0673B7521CAE2D06001FBF40 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
0632F8D41E8681EE002A7058 /* MainMenu.xib */ = {
isa = PBXVariantGroup;
children = (
0632F8D51E8681EE002A7058 /* Base */,
);
name = MainMenu.xib;
sourceTree = "";
};
0673B73E1CAE2D06001FBF40 /* MainMenu.xib */ = {
isa = PBXVariantGroup;
children = (
0673B73F1CAE2D06001FBF40 /* Base */,
);
name = MainMenu.xib;
sourceTree = "";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
0632F8D91E8681EE002A7058 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CODE_SIGN_ENTITLEMENTS = TouTiaoLauncher/TouTiaoLauncher.entitlements;
CODE_SIGN_IDENTITY = "Mac Developer";
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = UTN47S84JC;
INFOPLIST_FILE = TouTiaoLauncher/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.12;
PRODUCT_BUNDLE_IDENTIFIER = com.tesths.TouTiaoLauncher;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_VERSION = 3.0;
};
name = Debug;
};
0632F8DA1E8681EE002A7058 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CODE_SIGN_ENTITLEMENTS = TouTiaoLauncher/TouTiaoLauncher.entitlements;
CODE_SIGN_IDENTITY = "Mac Developer";
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = UTN47S84JC;
INFOPLIST_FILE = TouTiaoLauncher/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.12;
PRODUCT_BUNDLE_IDENTIFIER = com.tesths.TouTiaoLauncher;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
};
name = Release;
};
0673B7581CAE2D06001FBF40 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
0673B7591CAE2D06001FBF40 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
};
name = Release;
};
0673B75B1CAE2D06001FBF40 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 57BAB250D52BE0BE8AE45323 /* Pods-TouTiao.debug.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = TouTiao/TouTiao.entitlements;
CODE_SIGN_IDENTITY = "Mac Developer";
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = UTN47S84JC;
INFOPLIST_FILE = TouTiao/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.11;
PRODUCT_BUNDLE_IDENTIFIER = com.tt.TouTiao;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
0673B75C1CAE2D06001FBF40 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 975E04C1B55E348097BD00B9 /* Pods-TouTiao.release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = TouTiao/TouTiao.entitlements;
CODE_SIGN_IDENTITY = "Mac Developer";
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = UTN47S84JC;
INFOPLIST_FILE = TouTiao/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.11;
PRODUCT_BUNDLE_IDENTIFIER = com.tt.TouTiao;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Release;
};
0673B75E1CAE2D06001FBF40 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = TouTiaoTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = tesths.TouTiaoTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TouTiao.app/Contents/MacOS/TouTiao";
};
name = Debug;
};
0673B75F1CAE2D06001FBF40 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = TouTiaoTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = tesths.TouTiaoTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TouTiao.app/Contents/MacOS/TouTiao";
};
name = Release;
};
0673B7611CAE2D06001FBF40 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = TouTiaoUITests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = tesths.TouTiaoUITests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
TEST_TARGET_NAME = TouTiao;
};
name = Debug;
};
0673B7621CAE2D06001FBF40 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = TouTiaoUITests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = tesths.TouTiaoUITests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
TEST_TARGET_NAME = TouTiao;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
0632F8D81E8681EE002A7058 /* Build configuration list for PBXNativeTarget "TouTiaoLauncher" */ = {
isa = XCConfigurationList;
buildConfigurations = (
0632F8D91E8681EE002A7058 /* Debug */,
0632F8DA1E8681EE002A7058 /* Release */,
);
defaultConfigurationIsVisible = 0;
};
0673B7321CAE2D06001FBF40 /* Build configuration list for PBXProject "TouTiao" */ = {
isa = XCConfigurationList;
buildConfigurations = (
0673B7581CAE2D06001FBF40 /* Debug */,
0673B7591CAE2D06001FBF40 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
0673B75A1CAE2D06001FBF40 /* Build configuration list for PBXNativeTarget "TouTiao" */ = {
isa = XCConfigurationList;
buildConfigurations = (
0673B75B1CAE2D06001FBF40 /* Debug */,
0673B75C1CAE2D06001FBF40 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
0673B75D1CAE2D06001FBF40 /* Build configuration list for PBXNativeTarget "TouTiaoTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
0673B75E1CAE2D06001FBF40 /* Debug */,
0673B75F1CAE2D06001FBF40 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
0673B7601CAE2D06001FBF40 /* Build configuration list for PBXNativeTarget "TouTiaoUITests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
0673B7611CAE2D06001FBF40 /* Debug */,
0673B7621CAE2D06001FBF40 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 0673B72F1CAE2D06001FBF40 /* Project object */;
}
================================================
FILE: TouTiao.xcodeproj/project.xcworkspace/contents.xcworkspacedata
================================================
================================================
FILE: TouTiao.xcworkspace/contents.xcworkspacedata
================================================
================================================
FILE: TouTiaoLauncher/AppDelegate.swift
================================================
//
// AppDelegate.swift
// TouTiaoLauncher
//
// Created by tesths on 25/03/2017.
// Copyright © 2017 tesths. All rights reserved.
//
import Cocoa
extension Notification.Name {
static let killme = Notification.Name("killme")
}
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate
{
let mainAppIdentifier = "com.tt.TouTiao"
func applicationDidFinishLaunching(_ aNotification: Notification) {
let running = NSWorkspace.shared().runningApplications
var alreadyRunning = false
for app in running {
if app.bundleIdentifier == mainAppIdentifier {
alreadyRunning = true
break
}
}
if !alreadyRunning {
DistributedNotificationCenter.default().addObserver(self, selector: #selector(self.terminate), name: .killme, object: mainAppIdentifier)
let path = Bundle.main.bundlePath as NSString
var components = path.pathComponents
components.removeLast()
components.removeLast()
components.removeLast()
components.append("MacOS")
components.append("TouTiao") //main app name
let newPath = NSString.path(withComponents: components)
NSWorkspace.shared().launchApplication(newPath)
}
else {
self.terminate()
}
}
func terminate() {
// NSLog("I'll be back!")
NSApp.terminate(nil)
}
}
================================================
FILE: TouTiaoLauncher/Assets.xcassets/AppIcon.appiconset/Contents.json
================================================
{
"images" : [
{
"idiom" : "mac",
"size" : "16x16",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "16x16",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "32x32",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "32x32",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "128x128",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "128x128",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "256x256",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "256x256",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "512x512",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "512x512",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: TouTiaoLauncher/Base.lproj/MainMenu.xib
================================================
================================================
FILE: TouTiaoLauncher/Info.plist
================================================
LSBackgroundOnly
CFBundleDevelopmentRegion
en
CFBundleExecutable
$(EXECUTABLE_NAME)
CFBundleIconFile
CFBundleIdentifier
$(PRODUCT_BUNDLE_IDENTIFIER)
CFBundleInfoDictionaryVersion
6.0
CFBundleName
$(PRODUCT_NAME)
CFBundlePackageType
APPL
CFBundleShortVersionString
1.0
CFBundleVersion
1
LSMinimumSystemVersion
$(MACOSX_DEPLOYMENT_TARGET)
NSHumanReadableCopyright
Copyright © 2017 tesths. All rights reserved.
NSMainNibFile
MainMenu
NSPrincipalClass
NSApplication
================================================
FILE: TouTiaoLauncher/TouTiaoLauncher.entitlements
================================================
com.apple.security.app-sandbox
================================================
FILE: TouTiaoTests/Info.plist
================================================
CFBundleDevelopmentRegion
en
CFBundleExecutable
$(EXECUTABLE_NAME)
CFBundleIdentifier
$(PRODUCT_BUNDLE_IDENTIFIER)
CFBundleInfoDictionaryVersion
6.0
CFBundleName
$(PRODUCT_NAME)
CFBundlePackageType
BNDL
CFBundleShortVersionString
1.0
CFBundleSignature
????
CFBundleVersion
1
================================================
FILE: TouTiaoTests/TouTiaoTests.swift
================================================
//
// TouTiaoTests.swift
// TouTiaoTests
//
// Created by tesths on 4/1/16.
// Copyright © 2016 tesths. All rights reserved.
//
import XCTest
@testable import TouTiao
class TouTiaoTests: XCTestCase {
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
func testExample() {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
func testPerformanceExample() {
// This is an example of a performance test case.
self.measure {
// Put the code you want to measure the time of here.
}
}
}
================================================
FILE: TouTiaoUITests/Info.plist
================================================
CFBundleDevelopmentRegion
en
CFBundleExecutable
$(EXECUTABLE_NAME)
CFBundleIdentifier
$(PRODUCT_BUNDLE_IDENTIFIER)
CFBundleInfoDictionaryVersion
6.0
CFBundleName
$(PRODUCT_NAME)
CFBundlePackageType
BNDL
CFBundleShortVersionString
1.0
CFBundleSignature
????
CFBundleVersion
1
================================================
FILE: TouTiaoUITests/TouTiaoUITests.swift
================================================
//
// TouTiaoUITests.swift
// TouTiaoUITests
//
// Created by tesths on 4/1/16.
// Copyright © 2016 tesths. All rights reserved.
//
import XCTest
class TouTiaoUITests: XCTestCase {
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
// In UI tests it is usually best to stop immediately when a failure occurs.
continueAfterFailure = false
// UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
XCUIApplication().launch()
// In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
func testExample() {
// Use recording to get started writing UI tests.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
}