46 Commits

Author SHA1 Message Date
Yagiz Gurgul 763aadbf6a Merge pull request #69 from techinpark/feature/update-readme
Update Installation versions
2020-10-25 00:33:32 +01:00
Fernando e84621b119 Update Installation versions
- update installation versions to `1.4.0`
2020-10-24 21:50:10 +09:00
Yagiz Gurgul edbaca57c5 Merge pull request #68 from yagiz/release/1.4.0
Release 1.4.0 Merge
2020-10-22 23:23:28 +01:00
yagiz 00339064dc version++ 2020-10-22 23:17:47 +01:00
Yagiz Gurgul a03dc3ea15 Merge pull request #50 from DavidObfuscator/master
Move used headers into Public access
2020-10-22 22:19:44 +01:00
Yagiz Gurgul 7286a28a48 Merge pull request #58 from colinhumber/url-cleanup
Cleanup URL formatting in JSON strings
2020-10-22 22:19:21 +01:00
Yagiz Gurgul 026efb672a Merge pull request #67 from fredpi/patch-1
Use official release version of CocoaAsyncSocket
2020-10-22 22:18:58 +01:00
Frederick Pietschmann 5cbd269d19 Use official release version of CocoaAsyncSocket 2020-09-30 11:23:49 +02:00
Colin Humber 8e5704f537 Replace escaped URL strings with unescaped slashes 2019-10-27 13:15:28 -06:00
Yagiz Gurgul 1e7fd0c53b Merge pull request #51 from dcordero/tvOS
Adjust podspec to support tvOS
2019-10-02 13:54:57 +04:00
Yagiz Gurgul a7117ad2aa Merge pull request #56 from ShotaKashihara/master
[iOS 13] fixed a issue that the signature of __NSCFURLLocalSessionConnection changed
2019-10-02 13:52:45 +04:00
Shota Kashihara 51c960374b [iOS 13] fixed a issue that the signature of __NSCFURLLocalSessionConnection changed 2019-10-02 18:35:28 +09:00
David Cordero 2b281ce048 Adjust podspec to support tvOS 2019-06-21 16:39:45 +02:00
David Roka 4b5f46e732 move BagelRequestPacket.h and BagelRequestInfo.h into the Public headers (they are included from another public headers) 2019-06-06 13:00:10 +02:00
Yagiz Gurgul 876fb1e02f fixed filter field vertical issue 2019-05-18 15:40:41 +04:00
Yagiz Gurgul c76fa31802 - jsonviewer was removed.
- light theme fixes.
- performance improvements
2019-05-17 16:38:52 +04:00
Yagiz Gurgul 9b1c7b3beb Merge pull request #35 from swhitty/umbrella-header
Updating Umbrella Header
2019-05-10 15:36:55 +04:00
Yagiz Gurgul 1f55d92188 Merge pull request #38 from AccioSupport/master
Add support for SwiftPM based dependency managers
2019-05-10 15:36:15 +04:00
Yagiz Gurgul 2a9f51d710 Merge pull request #39 from sandorgyulai/fix/missing-patch-requests
Adding support for the missing PATCH http method
2019-05-10 15:33:26 +04:00
Sándor Gyulai dc208e7f77 Adding support for the missing PATCH http method 2019-04-15 10:56:42 +01:00
Cihat Gündüz f07702b8ae [Package.swift] Add CocoaAsyncSocket dependency 2019-04-10 11:04:55 +02:00
Cihat Gündüz 72f6635c0e [README] Document support & installation via Accio 2019-04-10 10:45:05 +02:00
Cihat Gündüz 59b94b09df Add basic SwiftPM manifest file 2019-04-10 10:42:13 +02:00
Simon Whitty e04528da86 Updating Umbrella Header
Xcode warns that the framework umbrella header should import *all* public headers. Downgrading some headers to project, as they do not need to be public.
Explicitly importing all the public headers from the umbrella headers.
2019-03-12 17:39:11 +11:00
Yagiz e1f382c648 lowercased is fixed for enum raw value 2019-02-27 22:30:39 +03:00
Yagiz f491ca18c7 Merge branch 'develop' of https://github.com/yagiz/Bagel 2019-02-27 22:25:42 +03:00
Yagiz Gurgul 7f21e32853 Merge pull request #34 from swhitty/http-additional-headers
RequestHeaders should be retrieved from the `currentRequest`
2019-02-27 22:19:13 +03:00
Yagiz Gurgul 7acbc6b10c Merge pull request #31 from viktorasl/25-null-json-response-view
Render null value in raw JSON viewer
2019-02-27 22:18:58 +03:00
Yagiz Gurgul 8f30d7c158 Merge pull request #30 from Kamajabu/feature/implementing-method-filter
Implementing additional filters for method and status
2019-02-27 22:18:44 +03:00
Yagiz Gurgul cdb1b5f9a1 Merge pull request #28 from ridvank/update-project-readability
Convert request method to enum to improve project readability
2019-02-27 22:18:26 +03:00
Yagiz Gurgul 5a8283b4e6 Merge pull request #27 from abarisain/carrier_delegate
Add support for a BagelCarrier delegate
2019-02-27 22:18:12 +03:00
Simon Whitty f3b560c926 RequestHeaders should be retrieved from the currentRequest
URLSession provides a mechanism for additional HTTP Header fields to be added to each URLRequest that manages via `URLSessionConfiguration.HTTPAdditionalHeaders`

request headers should be retrieved from the currentRequest of the data task to observer these and other headers that iOS automatically sends.
2019-02-26 22:17:43 +11:00
Viktoras Laukevičius 2352378f67 Render null value in raw JSON viewer 2019-02-23 11:21:36 +02:00
Kamil Buczel 6cbd185ef6 Added addressFilterTerm, methodFilterTerm, statusFilterTerm
Updated filtration
Small refactor
2019-02-20 10:02:31 +01:00
Kamil Buczel 1df2878063 Added
addressFilterTextField: NSTextField!
statusFilterTextField: NSTextField!
methodFilterTextField: NSTextField!

Enum for their tags. Updated controlTextDidChange for multiple textfields. Small refactor
2019-02-20 10:02:08 +01:00
Kamil Buczel e6b7e7c834 Adding additional filters layout 2019-02-20 10:01:18 +01:00
Kamil Buczel 15468adaa4 General refactor 2019-02-19 19:27:45 +01:00
Ridvan Kuccuk 9750d92e7c Convert request method to enum to improve project 2019-02-07 16:38:19 +01:00
Arnaud Barisain-Monrose b52c216a3d Add support for a BagelCarrier delegate
Allows the app to intercept bagel packets right before they are sent.

This allows for:
 - Various data rewriting
 - Filtering
2019-02-06 22:28:17 +01:00
Yagiz Gurgul d350acae64 Merge pull request #19 from Amnell/feature/cURL
Add support for generating cURL representation
2019-02-02 16:18:13 +03:00
Yagiz Gurgul 2cb2afa611 Merge pull request #23 from olejnjak/extension-api-only
Use app extension API only
2019-01-25 14:38:37 +03:00
Jakub Olejník d10ddf680d Use app extension API only 2019-01-25 11:21:33 +01:00
Mathias Amnell a618bae9f0 Add support for generating cURL representation 2019-01-23 20:01:41 +01:00
Yagiz Gurgul e702acf897 update README 2019-01-20 17:52:58 +03:00
Yagiz Gurgul 99754523c7 update README 2019-01-20 17:52:22 +03:00
Yagiz Gurgul 9eb0f916e0 version badge is dynamic 2019-01-20 17:51:26 +03:00
49 changed files with 816 additions and 450 deletions
+7 -6
View File
@@ -1,22 +1,23 @@
Pod::Spec.new do |s|
s.name = 'Bagel'
s.version = '1.3.2'
s.version = '1.4.0'
s.summary = 'Bagel is a little native iOS network sniffer.'
s.description = <<-DESC
Bagel is a native iOS network sniffer. It's not a proxy debugger so you don't have to mess around with certificates, proxy settings etc. As long as your iOS devices and your Mac are in the same network, you can view the network traffic of your apps seperated by the devices.
DESC
s.homepage = 'https://github.com/yagiz/Bagel'
s.license = { :type => 'APACHE', :file => 'LICENSE' }
s.author = { 'Yagiz' => 'yagizgurgul@gmail.com' }
s.source = { :git => 'https://github.com/yagiz/Bagel.git', :tag => s.version.to_s }
s.ios.deployment_target = '8.0'
s.tvos.deployment_target = '11.0'
s.source_files = 'iOS/Source/*.{h,m}'
s.dependency 'CocoaAsyncSocket'
s.requires_arc = true
end
+19
View File
@@ -0,0 +1,19 @@
// swift-tools-version:4.2
import PackageDescription
let package = Package(
name: "Bagel",
products: [
.library(name: "Bagel", targets: ["Bagel"])
],
dependencies: [
.package(url: "https://github.com/robbiehanson/CocoaAsyncSocket.git", .upToNextMajor(from: "7.6.4")),
],
targets: [
.target(
name: "Bagel",
dependencies: ["CocoaAsyncSocket"],
path: "iOS/Source"
)
]
)
+11 -5
View File
@@ -5,8 +5,10 @@
<img src="https://img.shields.io/badge/CocoaPods-compatible-4BC51D.svg?style=flat" /></a>
<a href="https://github.com/Carthage/Carthage" alt="Carthage">
<img src="https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat" /></a>
<a href="https://github.com/yagiz/Bagel/releases/tag/1.3.1" alt="Version">
<img src="https://img.shields.io/badge/version-1.3.1-blue.svg?style=flat" /></a>
<a href="https://github.com/JamitLabs/Accio" alt="Accio">
<img src="https://img.shields.io/badge/Accio-supported-0A7CF5.svg?style=flat" /></a>
<a href="https://github.com/yagiz/Bagel/releases" alt="Version">
<img src="https://img.shields.io/github/release/yagiz/Bagel.svg" /></a>
</p>
Bagel is a little native iOS network debugger. It's not a proxy debugger so you don't have to mess around with certificates, proxy settings etc. As long as your iOS devices and your Mac are in the same network, you can view the network traffic of your apps seperated by the devices or simulators.
@@ -20,12 +22,16 @@ Bagel is a little native iOS network debugger. It's not a proxy debugger so you
- Build and archive the project.
#### Install iOS Client
#### CocoaPods
```sh
pod 'Bagel', '~> 1.3.2'
```shhttps://img.shields.io/badge/version-1.3.1-blue.svg?style=flat
pod 'Bagel', '~> 1.4.0'
```
##### Carthage
```sh
github "yagiz/Bagel" "1.3.2"
github "yagiz/Bagel" "1.4.0"
```
##### Accio
```swift
.package(url: "https://github.com/yagiz/Bagel.git", .upToNextMajor(from: "1.4.0")),
```
### Usage
+12 -6
View File
@@ -9,7 +9,7 @@
/* Begin PBXBuildFile section */
3760A45B21F1383F004D1E07 /* BagelDeviceModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 3760A44121F1383F004D1E07 /* BagelDeviceModel.m */; };
3760A45C21F1383F004D1E07 /* BagelRequestCarrier.m in Sources */ = {isa = PBXBuildFile; fileRef = 3760A44221F1383F004D1E07 /* BagelRequestCarrier.m */; };
3760A45D21F1383F004D1E07 /* BagelController.h in Headers */ = {isa = PBXBuildFile; fileRef = 3760A44321F1383F004D1E07 /* BagelController.h */; settings = {ATTRIBUTES = (Public, ); }; };
3760A45D21F1383F004D1E07 /* BagelController.h in Headers */ = {isa = PBXBuildFile; fileRef = 3760A44321F1383F004D1E07 /* BagelController.h */; };
3760A45E21F1383F004D1E07 /* BagelUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 3760A44421F1383F004D1E07 /* BagelUtility.m */; };
3760A45F21F1383F004D1E07 /* BagelProjectModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 3760A44521F1383F004D1E07 /* BagelProjectModel.h */; settings = {ATTRIBUTES = (Public, ); }; };
3760A46021F1383F004D1E07 /* BagelConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 3760A44621F1383F004D1E07 /* BagelConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -17,23 +17,24 @@
3760A46221F1383F004D1E07 /* BagelRequestInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 3760A44821F1383F004D1E07 /* BagelRequestInfo.m */; };
3760A46321F1383F004D1E07 /* BagelURLSessionInjector.m in Sources */ = {isa = PBXBuildFile; fileRef = 3760A44921F1383F004D1E07 /* BagelURLSessionInjector.m */; };
3760A46421F1383F004D1E07 /* BagelBaseModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 3760A44A21F1383F004D1E07 /* BagelBaseModel.m */; };
3760A46521F1383F004D1E07 /* BagelURLConnectionInjector.h in Headers */ = {isa = PBXBuildFile; fileRef = 3760A44B21F1383F004D1E07 /* BagelURLConnectionInjector.h */; settings = {ATTRIBUTES = (Public, ); }; };
3760A46521F1383F004D1E07 /* BagelURLConnectionInjector.h in Headers */ = {isa = PBXBuildFile; fileRef = 3760A44B21F1383F004D1E07 /* BagelURLConnectionInjector.h */; };
3760A46621F1383F004D1E07 /* BagelBrowser.m in Sources */ = {isa = PBXBuildFile; fileRef = 3760A44C21F1383F004D1E07 /* BagelBrowser.m */; };
3760A46721F1383F004D1E07 /* BagelRequestPacket.h in Headers */ = {isa = PBXBuildFile; fileRef = 3760A44D21F1383F004D1E07 /* BagelRequestPacket.h */; settings = {ATTRIBUTES = (Public, ); }; };
3760A46821F1383F004D1E07 /* BagelController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3760A44E21F1383F004D1E07 /* BagelController.m */; };
3760A46921F1383F004D1E07 /* BagelRequestCarrier.h in Headers */ = {isa = PBXBuildFile; fileRef = 3760A44F21F1383F004D1E07 /* BagelRequestCarrier.h */; settings = {ATTRIBUTES = (Public, ); }; };
3760A46921F1383F004D1E07 /* BagelRequestCarrier.h in Headers */ = {isa = PBXBuildFile; fileRef = 3760A44F21F1383F004D1E07 /* BagelRequestCarrier.h */; };
3760A46A21F1383F004D1E07 /* BagelDeviceModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 3760A45021F1383F004D1E07 /* BagelDeviceModel.h */; settings = {ATTRIBUTES = (Public, ); }; };
3760A46B21F1383F004D1E07 /* BagelProjectModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 3760A45121F1383F004D1E07 /* BagelProjectModel.m */; };
3760A46C21F1383F004D1E07 /* BagelUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = 3760A45221F1383F004D1E07 /* BagelUtility.h */; settings = {ATTRIBUTES = (Public, ); }; };
3760A46D21F1383F004D1E07 /* BagelURLSessionInjector.h in Headers */ = {isa = PBXBuildFile; fileRef = 3760A45321F1383F004D1E07 /* BagelURLSessionInjector.h */; settings = {ATTRIBUTES = (Public, ); }; };
3760A46D21F1383F004D1E07 /* BagelURLSessionInjector.h in Headers */ = {isa = PBXBuildFile; fileRef = 3760A45321F1383F004D1E07 /* BagelURLSessionInjector.h */; };
3760A46E21F1383F004D1E07 /* BagelRequestInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 3760A45421F1383F004D1E07 /* BagelRequestInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
3760A46F21F1383F004D1E07 /* Bagel.h in Headers */ = {isa = PBXBuildFile; fileRef = 3760A45521F1383F004D1E07 /* Bagel.h */; settings = {ATTRIBUTES = (Public, ); }; };
3760A47021F1383F004D1E07 /* BagelConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 3760A45621F1383F004D1E07 /* BagelConfiguration.m */; };
3760A47121F1383F004D1E07 /* BagelRequestPacket.m in Sources */ = {isa = PBXBuildFile; fileRef = 3760A45721F1383F004D1E07 /* BagelRequestPacket.m */; };
3760A47221F1383F004D1E07 /* BagelBrowser.h in Headers */ = {isa = PBXBuildFile; fileRef = 3760A45821F1383F004D1E07 /* BagelBrowser.h */; settings = {ATTRIBUTES = (Public, ); }; };
3760A47221F1383F004D1E07 /* BagelBrowser.h in Headers */ = {isa = PBXBuildFile; fileRef = 3760A45821F1383F004D1E07 /* BagelBrowser.h */; };
3760A47321F1383F004D1E07 /* BagelURLConnectionInjector.m in Sources */ = {isa = PBXBuildFile; fileRef = 3760A45921F1383F004D1E07 /* BagelURLConnectionInjector.m */; };
3760A47421F1383F004D1E07 /* BagelBaseModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 3760A45A21F1383F004D1E07 /* BagelBaseModel.h */; settings = {ATTRIBUTES = (Public, ); }; };
3760A47B21F13A47004D1E07 /* CocoaAsyncSocket.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3760A47A21F13A47004D1E07 /* CocoaAsyncSocket.framework */; };
51102CE2220B87290067EB63 /* BagelCarrierDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 51102CE1220B857E0067EB63 /* BagelCarrierDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@@ -66,6 +67,7 @@
3760A45A21F1383F004D1E07 /* BagelBaseModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BagelBaseModel.h; sourceTree = "<group>"; };
3760A47521F13872004D1E07 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = SOURCE_ROOT; };
3760A47A21F13A47004D1E07 /* CocoaAsyncSocket.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CocoaAsyncSocket.framework; path = Carthage/Build/iOS/CocoaAsyncSocket.framework; sourceTree = SOURCE_ROOT; };
51102CE1220B857E0067EB63 /* BagelCarrierDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BagelCarrierDelegate.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -107,6 +109,7 @@
3760A44A21F1383F004D1E07 /* BagelBaseModel.m */,
3760A45821F1383F004D1E07 /* BagelBrowser.h */,
3760A44C21F1383F004D1E07 /* BagelBrowser.m */,
51102CE1220B857E0067EB63 /* BagelCarrierDelegate.h */,
3760A44621F1383F004D1E07 /* BagelConfiguration.h */,
3760A45621F1383F004D1E07 /* BagelConfiguration.m */,
3760A44321F1383F004D1E07 /* BagelController.h */,
@@ -147,11 +150,12 @@
buildActionMask = 2147483647;
files = (
3760A46F21F1383F004D1E07 /* Bagel.h in Headers */,
51102CE2220B87290067EB63 /* BagelCarrierDelegate.h in Headers */,
3760A45D21F1383F004D1E07 /* BagelController.h in Headers */,
3760A47221F1383F004D1E07 /* BagelBrowser.h in Headers */,
3760A46021F1383F004D1E07 /* BagelConfiguration.h in Headers */,
3760A46E21F1383F004D1E07 /* BagelRequestInfo.h in Headers */,
3760A46921F1383F004D1E07 /* BagelRequestCarrier.h in Headers */,
3760A46E21F1383F004D1E07 /* BagelRequestInfo.h in Headers */,
3760A46721F1383F004D1E07 /* BagelRequestPacket.h in Headers */,
3760A46A21F1383F004D1E07 /* BagelDeviceModel.h in Headers */,
3760A46C21F1383F004D1E07 /* BagelUtility.h in Headers */,
@@ -364,6 +368,7 @@
3760A43E21F13817004D1E07 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
@@ -394,6 +399,7 @@
3760A43F21F13817004D1E07 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
+7 -1
View File
@@ -28,7 +28,13 @@ FOUNDATION_EXPORT double BagelVersionNumber;
FOUNDATION_EXPORT const unsigned char BagelVersionString[];
#import <Foundation/Foundation.h>
#import "BagelConfiguration.h"
#import <Bagel/BagelBaseModel.h>
#import <Bagel/BagelCarrierDelegate.h>
#import <Bagel/BagelConfiguration.h>
#import <Bagel/BagelDeviceModel.h>
#import <Bagel/BagelProjectModel.h>
#import <Bagel/BagelUtility.h>
@interface Bagel : NSObject
+36
View File
@@ -0,0 +1,36 @@
//
// Copyright (c) 2018 Bagel (https://github.com/yagiz/Bagel)
//
// 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.
#import "BagelRequestPacket.h"
@protocol BagelCarrierDelegate <NSObject>
@optional
/**
Called right before Bagel sends a request packet to the Mac app.
Allows your delegate to modify the packet on the fly, or abort the operation.
Return a modified request packet, or nil if you want to filter it out.
*/
- (nullable BagelRequestPacket*)bagelCarrierWillSendRequest:(nonnull BagelRequestPacket*)request;
@end
+3
View File
@@ -20,6 +20,7 @@
// THE SOFTWARE.
#import <Foundation/Foundation.h>
#import "BagelCarrierDelegate.h"
#import "BagelProjectModel.h"
#import "BagelDeviceModel.h"
#import "BagelUtility.h"
@@ -29,6 +30,8 @@
@property (nonatomic, strong) BagelProjectModel* project;
@property (nonatomic, strong) BagelDeviceModel* device;
@property (nonatomic, weak) id<BagelCarrierDelegate> carrierDelegate;
@property (nonatomic) uint16_t netservicePort;
@property (nonatomic, strong) NSString* netserviceType;
@property (nonatomic, strong) NSString* netserviceDomain;
+9
View File
@@ -214,6 +214,15 @@ static NSString* queueId = @"com.yagiz.bagel.injectController";
packet.project = self.configuration.project;
packet.device = self.configuration.device;
id<BagelCarrierDelegate> carrierDelegate = self.configuration.carrierDelegate;
if ([carrierDelegate respondsToSelector:@selector(bagelCarrierWillSendRequest:)]) {
packet = [carrierDelegate bagelCarrierWillSendRequest:packet];
if (packet == nil) {
return;
}
}
[self.browser sendPacket:packet];
}
+2 -2
View File
@@ -86,14 +86,14 @@
if (self.urlSessionTask) {
requestInfo.url = self.urlSessionTask.originalRequest.URL;
requestInfo.requestHeaders = self.self.urlSessionTask.originalRequest.allHTTPHeaderFields;
requestInfo.requestHeaders = self.self.urlSessionTask.currentRequest.allHTTPHeaderFields;
requestInfo.requestBody = self.self.urlSessionTask.originalRequest.HTTPBody;
requestInfo.requestMethod = self.self.urlSessionTask.originalRequest.HTTPMethod;
}else if (self.urlConnection) {
requestInfo.url = self.urlConnection.originalRequest.URL;
requestInfo.requestHeaders = self.self.urlConnection.originalRequest.allHTTPHeaderFields;
requestInfo.requestHeaders = self.self.urlConnection.currentRequest.allHTTPHeaderFields;
requestInfo.requestBody = self.self.urlConnection.originalRequest.HTTPBody;
requestInfo.requestMethod = self.self.urlConnection.originalRequest.HTTPMethod;
+26 -1
View File
@@ -41,11 +41,13 @@
dump:
- (void)_didFinishWithError:(id)arg1;
- (void)_didReceiveData:(id)arg1;
- (void)_didReceiveResponse:(id)arg1 sniff:(bool)arg2;
- (void)_didReceiveResponse:(id)arg1 sniff:(bool)arg2; // ~> iOS 12
- (void)_didReceiveResponse:(id)arg1 sniff:(bool)arg2 rewrite:(bool)arg3; // iOS 13
https://github.com/JackRostron/iOS8-Runtime-Headers
https://github.com/ksenks/iOS9-Runtime-Headers
https://github.com/JaviSoto/iOS10-Runtime-Headers
https://github.com/LeoNatan/Apple-Runtime-Headers
*/
#pragma mark NSURLSession Injection
@@ -109,6 +111,29 @@
- (void)swizzleSessionDidReceiveResponse : (Class) class
{
if (@available(iOS 13.0, *)) {
SEL selector = NSSelectorFromString(@"_didReceiveResponse:sniff:rewrite:");
Method m = class_getInstanceMethod(class, selector);
if (m && [class instancesRespondToSelector:selector]) {
typedef void (*OriginalIMPBlockType)(id self, SEL _cmd, id arg1, BOOL sniff, BOOL rewrite);
OriginalIMPBlockType originalIMPBlock = (OriginalIMPBlockType)method_getImplementation(m);
__weak BagelURLSessionInjector* weakSelf = self;
void (^swizzledSessionDidReceiveResponse)(id, id, BOOL, BOOL) = ^void(id self, id arg1, BOOL sniff, BOOL rewrite) {
[weakSelf.delegate urlSessionInjector:weakSelf didReceiveResponse:[self valueForKey:@"task"] response:arg1];
originalIMPBlock(self, _cmd, arg1, sniff, rewrite);
};
method_setImplementation(m, imp_implementationWithBlock(swizzledSessionDidReceiveResponse));
}
return;
}
SEL selector = NSSelectorFromString(@"_didReceiveResponse:sniff:");
Method m = class_getInstanceMethod(class, selector);
+44 -14
View File
@@ -7,6 +7,9 @@
objects = {
/* Begin PBXBuildFile section */
1191142A21F8B9CB00BFCA48 /* CURLRepresentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1191142921F8B9CB00BFCA48 /* CURLRepresentation.swift */; };
8A814D05228ECCED0049A64E /* DetailSectionProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A814D04228ECCED0049A64E /* DetailSectionProtocol.swift */; };
8A814D07229025FF0049A64E /* VerticallyCenteredTextFieldCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A814D06229025FF0049A64E /* VerticallyCenteredTextFieldCell.swift */; };
9AAA3A9C54B46F8D2C8DD674 /* Pods_Bagel.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00E3BE2EECB0984D92EFCA30 /* Pods_Bagel.framework */; };
BC1F5B37216746D30045C871 /* FontManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC1F5B36216746D30045C871 /* FontManager.swift */; };
BC32643621738AF0006452FE /* KeyValueRepresentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC32643521738AF0006452FE /* KeyValueRepresentation.swift */; };
@@ -114,6 +117,9 @@
/* Begin PBXFileReference section */
00E3BE2EECB0984D92EFCA30 /* Pods_Bagel.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Bagel.framework; sourceTree = BUILT_PRODUCTS_DIR; };
1191142921F8B9CB00BFCA48 /* CURLRepresentation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CURLRepresentation.swift; sourceTree = "<group>"; };
8A814D04228ECCED0049A64E /* DetailSectionProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailSectionProtocol.swift; sourceTree = "<group>"; };
8A814D06229025FF0049A64E /* VerticallyCenteredTextFieldCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerticallyCenteredTextFieldCell.swift; sourceTree = "<group>"; };
BC1F5B36216746D30045C871 /* FontManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontManager.swift; sourceTree = "<group>"; };
BC32643521738AF0006452FE /* KeyValueRepresentation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyValueRepresentation.swift; sourceTree = "<group>"; };
BC5E76C8216A64DB000F658D /* Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = "<group>"; };
@@ -236,6 +242,14 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
1191142821F8B9AB00BFCA48 /* CURLRepresentation */ = {
isa = PBXGroup;
children = (
1191142921F8B9CB00BFCA48 /* CURLRepresentation.swift */,
);
path = CURLRepresentation;
sourceTree = "<group>";
};
659EF5768D424A8F8EEB1541 /* Frameworks */ = {
isa = PBXGroup;
children = (
@@ -244,6 +258,17 @@
name = Frameworks;
sourceTree = "<group>";
};
8A814D03228EC5DB0049A64E /* Cells */ = {
isa = PBXGroup;
children = (
BCA60B4B2162439200B9DCAD /* StatusPacketTableCellView.swift */,
BCFB675621D977C2000199ED /* MethodPacketTableCellView.swift */,
BCA60B4D2162439E00B9DCAD /* URLPacketTableCellView.swift */,
BCEB9AB6217DD546008BBF3C /* DatePacketTableCellView.swift */,
);
path = Cells;
sourceTree = "<group>";
};
BC1F5B35216746CA0045C871 /* Fonts */ = {
isa = PBXGroup;
children = (
@@ -269,6 +294,7 @@
BC61DA762162BD52000F6D2F /* DetailSections */ = {
isa = PBXGroup;
children = (
8A814D04228ECCED0049A64E /* DetailSectionProtocol.swift */,
BC9C77A62163803700E8ADE8 /* DataViewController */,
BC9C779821634D3E00E8ADE8 /* KeyValueListViewController */,
BC9C779521634D1F00E8ADE8 /* OverviewViewController */,
@@ -352,9 +378,9 @@
BC9C77A62163803700E8ADE8 /* DataViewController */ = {
isa = PBXGroup;
children = (
BC9C77C12163984200E8ADE8 /* Sections */,
BC9C77A42163803400E8ADE8 /* DataViewController.swift */,
BC9C77A72163805000E8ADE8 /* DataViewModel.swift */,
BC9C77C12163984200E8ADE8 /* Sections */,
BC9C77AA216385BF00E8ADE8 /* DataTextViewController */,
BC9C77A9216385B600E8ADE8 /* DataJSONViewController */,
);
@@ -493,6 +519,7 @@
BCEB9AA9217CB0BB008BBF3C /* OverviewRepresentation */,
BC32643421738AB5006452FE /* ParameterRepresentation */,
BC75A8082173636A00A2A5B3 /* DataRepresentation */,
1191142821F8B9AB00BFCA48 /* CURLRepresentation */,
);
name = ContentRepresentation;
path = ContentRepresentation/ContentRepresentation;
@@ -545,10 +572,7 @@
BCFC852921383171001EC6D7 /* Packets.storyboard */,
BCFC853521383650001EC6D7 /* PacketsViewController.swift */,
BCA60B472162403F00B9DCAD /* PacketsViewModel.swift */,
BCA60B4B2162439200B9DCAD /* StatusPacketTableCellView.swift */,
BCFB675621D977C2000199ED /* MethodPacketTableCellView.swift */,
BCA60B4D2162439E00B9DCAD /* URLPacketTableCellView.swift */,
BCEB9AB6217DD546008BBF3C /* DatePacketTableCellView.swift */,
8A814D03228EC5DB0049A64E /* Cells */,
);
path = Packets;
sourceTree = "<group>";
@@ -574,6 +598,7 @@
BCB6FD6821627D5400D6F03C /* TransparentSplitView.swift */,
BCDF0EC321662CA10030710C /* FlatTableRowView.swift */,
BC911A462168EB0A00B755D4 /* ContentBar.swift */,
8A814D06229025FF0049A64E /* VerticallyCenteredTextFieldCell.swift */,
);
path = Views;
sourceTree = "<group>";
@@ -696,7 +721,7 @@
TargetAttributes = {
BCD0E022210F5E0D00CE5C7B = {
CreatedOnToolsVersion = 9.2;
ProvisioningStyle = Automatic;
ProvisioningStyle = Manual;
};
BCD0E034210F5E0D00CE5C7B = {
CreatedOnToolsVersion = 9.2;
@@ -799,18 +824,16 @@
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Bagel/Pods-Bagel-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/CocoaAsyncSocket/CocoaAsyncSocket.framework",
"${BUILT_PRODUCTS_DIR}/Highlightr/Highlightr.framework",
"${BUILT_PRODUCTS_DIR}/macOSThemeKit/macOSThemeKit.framework",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
);
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CocoaAsyncSocket.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Highlightr.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/macOSThemeKit.framework",
);
runOnlyForDeploymentPostprocessing = 0;
@@ -833,6 +856,7 @@
BCEB9AA2217C94C1008BBF3C /* BagelExtensions.swift in Sources */,
BCBD86E2215916C9009CBEA7 /* BagelController.swift in Sources */,
BCEB9AA8217CAA23008BBF3C /* OverviewRepresentation.swift in Sources */,
8A814D05228ECCED0049A64E /* DetailSectionProtocol.swift in Sources */,
BCEB9AB9217DD653008BBF3C /* Date.swift in Sources */,
BC9C77A52163803400E8ADE8 /* DataViewController.swift in Sources */,
BCA60B4C2162439200B9DCAD /* StatusPacketTableCellView.swift in Sources */,
@@ -857,6 +881,7 @@
BCFC853021383267001EC6D7 /* ProjectsViewController.swift in Sources */,
BCA60B442162395000B9DCAD /* DevicesViewModel.swift in Sources */,
BC73DFAE215BFB18002E533B /* BagelPublisher.swift in Sources */,
1191142A21F8B9CB00BFCA48 /* CURLRepresentation.swift in Sources */,
BCA60B41216201B900B9DCAD /* BagelConfiguration.swift in Sources */,
BC61DA752162B976000F6D2F /* DetailViewModel.swift in Sources */,
BC9C77B22163897600E8ADE8 /* DataTextViewModel.swift in Sources */,
@@ -880,6 +905,7 @@
BCFC855021384981001EC6D7 /* BagelPacket.swift in Sources */,
BCE21E3E2162C15900A65B29 /* KeyValueListViewController.swift in Sources */,
BCA60B4E2162439E00B9DCAD /* URLPacketTableCellView.swift in Sources */,
8A814D07229025FF0049A64E /* VerticallyCenteredTextFieldCell.swift in Sources */,
BCFC853B21384239001EC6D7 /* ProjectTableCellView.swift in Sources */,
BCFC853E21384443001EC6D7 /* BaseTableView.swift in Sources */,
BCBD86E62159172B009CBEA7 /* BagelDeviceController.swift in Sources */,
@@ -1053,13 +1079,15 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = Bagel/Bagel.entitlements;
CODE_SIGN_STYLE = Automatic;
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = WJ26RLBF55;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = Bagel/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.11;
PRODUCT_BUNDLE_IDENTIFIER = com.yagiz.Bagel;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_VERSION = 4.2;
};
name = Debug;
@@ -1070,13 +1098,15 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = Bagel/Bagel.entitlements;
CODE_SIGN_STYLE = Automatic;
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = WJ26RLBF55;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = Bagel/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.11;
PRODUCT_BUNDLE_IDENTIFIER = com.yagiz.Bagel;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_VERSION = 4.2;
};
name = Release;
+1 -1
View File
@@ -11,7 +11,7 @@ import Cocoa
extension Date {
private static let readableFormat = "dd/MM/yyyy HH:mm:ss"
var readble: String {
var readable: String {
return self.format(dateFormat: Date.readableFormat)
}
@@ -0,0 +1,40 @@
//
// asdas.swift
// Bagel
//
// Created by Yagiz Gurgul on 5/18/19.
// Copyright © 2019 Yagiz Lab. All rights reserved.
//
import Cocoa
//credits: https://stackoverflow.com/questions/11775128/set-text-vertical-center-in-nstextfield
class VerticallyCenteredTextFieldCell: NSTextFieldCell {
func adjustedFrame(toVerticallyCenterText rect: NSRect) -> NSRect {
// super would normally draw text at the top of the cell
var titleRect = super.titleRect(forBounds: rect)
let minimumHeight = self.cellSize(forBounds: rect).height
titleRect.origin.y += (titleRect.height - minimumHeight) / 2
titleRect.size.height = minimumHeight
return titleRect
}
override func edit(withFrame rect: NSRect, in controlView: NSView, editor textObj: NSText, delegate: Any?, event: NSEvent?) {
super.edit(withFrame: adjustedFrame(toVerticallyCenterText: rect), in: controlView, editor: textObj, delegate: delegate, event: event)
}
override func select(withFrame rect: NSRect, in controlView: NSView, editor textObj: NSText, delegate: Any?, start selStart: Int, length selLength: Int) {
super.select(withFrame: adjustedFrame(toVerticallyCenterText: rect), in: controlView, editor: textObj, delegate: delegate, start: selStart, length: selLength)
}
override func drawInterior(withFrame cellFrame: NSRect, in controlView: NSView) {
super.drawInterior(withFrame: adjustedFrame(toVerticallyCenterText: cellFrame), in: controlView)
}
override func draw(withFrame cellFrame: NSRect, in controlView: NSView) {
super.draw(withFrame: cellFrame, in: controlView)
}
}
@@ -9,24 +9,19 @@
import Cocoa
import WebKit
import macOSThemeKit
import Highlightr
class DataJSONViewController: BaseViewController {
var viewModel: DataJSONViewModel?
var isRaw: Bool = false
@IBOutlet weak var webView: WebView!
let highlightr = Highlightr()
@IBOutlet var rawTextView: NSTextView!
@IBOutlet weak var rawTextScrollView: NSScrollView!
@IBOutlet weak var rawButton: NSButton!
@IBOutlet weak var copyToClipboardButton: NSButton!
private var isWebViewLoaded: Bool = false
var onWebViewDidFinishLoading : (()->())?
var onWebViewInitialLoading : (()->())?
@IBOutlet weak var progressIndicator: NSProgressIndicator!
override func setup() {
@@ -35,96 +30,43 @@ class DataJSONViewController: BaseViewController {
NotificationCenter.default.addObserver(self, selector: #selector(changedTheme(_:)), name: .didChangeTheme, object: nil)
self.viewModel?.onChange = { [weak self] in
self?.refresh()
}
self.refresh()
self.refreshHighlightrTheme()
}
func setupJSONViewer(didFinishLoad: (()->())? = nil ) {
self.onWebViewDidFinishLoading = didFinishLoad
let filePath = Bundle.main.path(forResource: "jsonviewer", ofType: "html")!
let fileURL = URL(fileURLWithPath: filePath)
let htmlRequest = URLRequest(url: fileURL)
self.webView.frameLoadDelegate = self
self.webView.drawsBackground = false
self.webView.mainFrame.load(htmlRequest)
self.refreshJSONEditorTheme()
}
func refresh() {
if self.isRaw {
self.rawTextScrollView.isHidden = false
self.webView.isHidden = true
self.rawButton.state = .on
}else {
self.rawTextScrollView.isHidden = true
self.webView.isHidden = false
self.rawButton.state = .off
}
self.rawTextView.string = ""
if let jsonString = self.viewModel?.dataRepresentation?.rawString {
if self.isWebViewLoaded {
self.webView.windowScriptObject.callWebScriptMethod("renderJSONString", withArguments: [jsonString])
}else{
self.setupJSONViewer {
self.webView.windowScriptObject.callWebScriptMethod("renderJSONString", withArguments: [jsonString])
self.progressIndicator.isHidden = false
self.progressIndicator.startAnimation(nil)
DispatchQueue.global(qos: .background).async {
if let highlightedCode = self.highlightr?.highlight(jsonString, as: "json") {
DispatchQueue.main.async {
self.rawTextView.textStorage?.setAttributedString(highlightedCode)
self.progressIndicator.isHidden = true
self.progressIndicator.stopAnimation(nil)
}
}
}
self.rawTextView.textStorage?.setAttributedString(TextStyles.codeAttributedString(string: jsonString ))
}
}
func refreshJSONEditorTheme() {
func refreshHighlightrTheme() {
if ThemeManager.shared.effectiveTheme === ThemeManager.lightTheme {
self.webView.windowScriptObject.callWebScriptMethod("changeThemeToLight", withArguments: [])
self.highlightr?.setTheme(to: "github")
}else if ThemeManager.shared.effectiveTheme === ThemeManager.darkTheme {
self.webView.windowScriptObject.callWebScriptMethod("changeThemeToDark", withArguments: [])
self.highlightr?.setTheme(to: "paraiso-dark")
}
}
@objc private func changedTheme(_ notification: Notification) {
self.refreshJSONEditorTheme()
self.refreshHighlightrTheme()
}
@IBAction func rawButtonAction(_ sender: Any) {
self.isRaw = !self.isRaw
self.refresh()
}
@IBAction func copyButtonAction(_ sender: Any) {
self.viewModel?.copyToClipboard()
}
}
extension DataJSONViewController: WebFrameLoadDelegate {
func webView(_ sender: WebView!, didFinishLoadFor frame: WebFrame!) {
if self.isWebViewLoaded == false {
self.isWebViewLoaded = true
self.onWebViewDidFinishLoading?()
}
self.refreshJSONEditorTheme()
}
}
@@ -8,7 +8,7 @@
import Cocoa
class DataViewController: BaseViewController {
class DataViewController: BaseViewController, DetailSectionProtocol {
var viewModel: DataViewModel?
@@ -18,13 +18,15 @@ class DataViewController: BaseViewController {
override func setup() {
self.viewModel?.onChange = { [weak self] in
self?.refresh()
}
self.refresh()
}
func refreshViewModel() {
self.viewModel?.didSelectPacket()
}
override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
@@ -14,14 +14,11 @@ class DataViewModel: BaseViewModel {
var dataRepresentation: DataRepresentation?
func register() {
NotificationCenter.default.addObserver(self, selector: #selector(self.didSelectPacket), name: BagelNotifications.didSelectPacket, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.didSelectPacket), name: BagelNotifications.didUpdatePacket, object: nil)
//
}
@objc func didSelectPacket() {
self.packet = BagelController.shared.selectedProjectController?.selectedDeviceController?.selectedPacket
}
}
@@ -0,0 +1,13 @@
//
// DetailSectionProtocol.swift
// Bagel
//
// Created by Yagiz Gurgul on 5/17/19.
// Copyright © 2019 Yagiz Lab. All rights reserved.
//
import Cocoa
protocol DetailSectionProtocol {
func refreshViewModel()
}
@@ -9,7 +9,7 @@
import Cocoa
import macOSThemeKit
class KeyValueListViewController: BaseViewController {
class KeyValueListViewController: BaseViewController, DetailSectionProtocol {
var viewModel: KeyValueViewModel?
@@ -45,6 +45,9 @@ class KeyValueListViewController: BaseViewController {
self.refresh()
}
func refreshViewModel() {
self.viewModel?.didSelectPacket()
}
func setupTableViewHeaders() {
@@ -9,14 +9,18 @@
import Cocoa
import macOSThemeKit
class OverviewViewController: BaseViewController {
class OverviewViewController: BaseViewController, DetailSectionProtocol {
@IBOutlet var overviewTextView: NSTextView!
@IBOutlet weak var curlButton: NSButton!
@IBOutlet weak var copyToClipboardButton: NSButton!
var viewModel: OverviewViewModel?
private var isCurl: Bool = false
override func setup() {
self.copyToClipboardButton.image = ThemeImage.copyToClipboardIcon
@@ -29,14 +33,33 @@ class OverviewViewController: BaseViewController {
self.refresh()
}
func refreshViewModel() {
self.viewModel?.didSelectPacket()
}
func refresh() {
self.overviewTextView.textStorage?.setAttributedString(TextStyles.codeAttributedString(string: self.viewModel?.overviewRepresentation?.rawString ?? ""))
if isCurl {
self.overviewTextView.textStorage?.setAttributedString(TextStyles.codeAttributedString(string: self.viewModel?.curlRepresentation?.rawString ?? ""))
curlButton.state = .on
} else {
self.overviewTextView.textStorage?.setAttributedString(TextStyles.codeAttributedString(string: self.viewModel?.overviewRepresentation?.rawString ?? ""))
curlButton.state = .off
}
}
@IBAction func curlButtonAction(_ sender: Any) {
self.isCurl.toggle()
self.refresh()
}
@IBAction func copyButtonAction(_ sender: Any) {
self.viewModel?.copyToClipboard()
if isCurl {
self.viewModel?.copyCURLToClipboard()
} else {
self.viewModel?.copyTextToClipboard()
}
}
}
@@ -12,6 +12,7 @@ class OverviewViewModel: BaseViewModel {
var packet: BagelPacket?
var overviewRepresentation: OverviewRepresentation?
var curlRepresentation: CURLRepresentation?
func register() {
@@ -26,12 +27,17 @@ class OverviewViewModel: BaseViewModel {
if let requestInfo = self.packet?.requestInfo {
self.overviewRepresentation = OverviewRepresentation(requestInfo: requestInfo)
self.curlRepresentation = CURLRepresentation(requestInfo: requestInfo)
}
self.onChange?()
}
func copyToClipboard() {
func copyTextToClipboard() {
self.overviewRepresentation?.copyToClipboard()
}
func copyCURLToClipboard() {
self.curlRepresentation?.copyToClipboard()
}
}
@@ -9,7 +9,6 @@
import Cocoa
enum DetailType: Int {
case overview = 0
case requestHeaders = 1
case requestParameters = 2
@@ -32,6 +31,14 @@ class DetailViewController: BaseViewController {
@IBOutlet weak var detailButtonResponseHeaders: NSButton!
@IBOutlet weak var detailButtonResponseBody: NSButton!
var overview: OverviewViewController?
var requestHeaders: KeyValueListViewController?
var requestParameters: KeyValueListViewController?
var requestBody: DataViewController?
var responseHeaders: KeyValueListViewController?
var responseData: DataViewController?
var sections = [DetailSectionProtocol?]()
var typeButtons = [NSButton]()
@IBOutlet weak var tabView: NSTabView!
@@ -58,51 +65,48 @@ class DetailViewController: BaseViewController {
func setupDetailTypeViews() {
let overview = self.storyboard?.instantiateController(withIdentifier: OverviewViewController.identifier) as! OverviewViewController
overview.viewModel = OverviewViewModel()
overview.viewModel?.register()
let overviewTabItem = NSTabViewItem(viewController: overview)
let requestHeaders = self.storyboard?.instantiateController(withIdentifier: KeyValueListViewController.identifier) as! KeyValueListViewController
requestHeaders.viewModel = RequestHeadersViewModel()
requestHeaders.viewModel?.register()
let requestHeadersTabItem = NSTabViewItem(viewController: requestHeaders)
self.requestHeaders = self.storyboard?.instantiateController(withIdentifier: KeyValueListViewController.identifier) as? KeyValueListViewController
self.requestHeaders?.viewModel = RequestHeadersViewModel()
self.requestHeaders?.viewModel?.register()
let requestHeadersTabItem = NSTabViewItem(viewController: self.requestHeaders!)
let requestParameters = self.storyboard?.instantiateController(withIdentifier: KeyValueListViewController.identifier) as! KeyValueListViewController
requestParameters.viewModel = RequestParametersViewModel()
requestParameters.viewModel?.register()
let requestParametersTabItem = NSTabViewItem(viewController: requestParameters)
self.requestParameters = self.storyboard?.instantiateController(withIdentifier: KeyValueListViewController.identifier) as? KeyValueListViewController
self.requestParameters?.viewModel = RequestParametersViewModel()
self.requestParameters?.viewModel?.register()
let requestParametersTabItem = NSTabViewItem(viewController: self.requestParameters!)
let requestBody = self.storyboard?.instantiateController(withIdentifier: DataViewController.identifier) as! DataViewController
requestBody.viewModel = RequestBodyViewModel()
requestBody.viewModel?.register()
let requestBodyTabItem = NSTabViewItem(viewController: requestBody)
self.requestBody = self.storyboard?.instantiateController(withIdentifier: DataViewController.identifier) as? DataViewController
self.requestBody?.viewModel = RequestBodyViewModel()
self.requestBody?.viewModel?.register()
let requestBodyTabItem = NSTabViewItem(viewController: self.requestBody!)
let responseHeaders = self.storyboard?.instantiateController(withIdentifier: KeyValueListViewController.identifier) as! KeyValueListViewController
responseHeaders.viewModel = ResponseHeadersViewModel()
responseHeaders.viewModel?.register()
let responseHeadersTabItem = NSTabViewItem(viewController: responseHeaders)
self.responseHeaders = self.storyboard?.instantiateController(withIdentifier: KeyValueListViewController.identifier) as? KeyValueListViewController
self.responseHeaders?.viewModel = ResponseHeadersViewModel()
self.responseHeaders?.viewModel?.register()
let responseHeadersTabItem = NSTabViewItem(viewController: self.responseHeaders!)
let responseData = self.storyboard?.instantiateController(withIdentifier: DataViewController.identifier) as! DataViewController
responseData.viewModel = ResponseDataViewModel()
responseData.viewModel?.register()
let responseDataTabItem = NSTabViewItem(viewController: responseData)
self.responseData = self.storyboard?.instantiateController(withIdentifier: DataViewController.identifier) as? DataViewController
self.responseData?.viewModel = ResponseDataViewModel()
self.responseData?.viewModel?.register()
let responseDataTabItem = NSTabViewItem(viewController: self.responseData!)
self.tabView.addTabViewItem(overviewTabItem)
self.tabView.addTabViewItem(requestHeadersTabItem)
self.tabView.addTabViewItem(requestParametersTabItem)
self.tabView.addTabViewItem(requestBodyTabItem)
self.tabView.addTabViewItem(responseHeadersTabItem)
self.tabView.addTabViewItem(responseDataTabItem)
}
@IBAction func selectDetailButtonAction(_ sender: NSButton) {
@@ -117,7 +121,11 @@ class DetailViewController: BaseViewController {
self.tabView.selectTabViewItem(at: self.currentDetailType.rawValue)
self.urlTextField.stringValue = self.viewModel?.packet?.requestInfo?.url ?? ""
self.httpMethodTextField.stringValue = self.viewModel?.packet?.requestInfo?.requestMethod ?? ""
self.httpMethodTextField.stringValue = self.viewModel?.packet?.requestInfo?.requestMethod?.rawValue ?? ""
if let detailSection = self.tabView.selectedTabViewItem?.viewController as? DetailSectionProtocol {
detailSection.refreshViewModel()
}
}
func refreshTypeButtons() {
@@ -14,7 +14,7 @@ class DetailViewModel: BaseViewModel {
func register() {
NotificationCenter.default.addObserver(self, selector: #selector(self.refreshPacket), name: BagelNotifications.didUpdatePacket, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.didUpdatePacket), name: BagelNotifications.didUpdatePacket, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.refreshPacket), name: BagelNotifications.didSelectPacket, object: nil)
}
+43 -58
View File
@@ -3,7 +3,6 @@
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14460.31"/>
<plugIn identifier="com.apple.WebKitIBPlugin" version="14460.31"/>
<capability name="Named colors" minToolsVersion="9.0"/>
<capability name="System colors introduced in macOS 10.14" minToolsVersion="10.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
@@ -23,12 +22,6 @@
<rect key="frame" x="0.0" y="0.0" width="450" height="300"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<webView translatesAutoresizingMaskIntoConstraints="NO" id="1KQ-pz-LuO">
<rect key="frame" x="5" y="35" width="440" height="260"/>
<webPreferences key="preferences" defaultFontSize="16" defaultFixedFontSize="13" minimumFontSize="0">
<nil key="identifier"/>
</webPreferences>
</webView>
<scrollView borderType="none" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Kzt-Tt-u1z">
<rect key="frame" x="5" y="35" width="440" height="260"/>
<clipView key="contentView" drawsBackground="NO" id="tSO-9U-bT5">
@@ -42,15 +35,6 @@
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<size key="minSize" width="440" height="260"/>
<size key="maxSize" width="618" height="10000000"/>
<attributedString key="textStorage">
<fragment content="Test">
<attributes>
<color key="NSColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<font key="NSFont" size="13" name="DroidSansMono"/>
<paragraphStyle key="NSParagraphStyle" alignment="natural" lineBreakMode="wordWrapping" baseWritingDirection="natural" tighteningFactorForTruncation="0.0"/>
</attributes>
</fragment>
</attributedString>
<color key="insertionPointColor" name="labelColor" catalog="System" colorSpace="catalog"/>
</textView>
</subviews>
@@ -84,21 +68,8 @@
<action selector="copyButtonAction:" target="8u2-ww-n8g" id="3kL-eK-0JK"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="yg1-GN-IMK">
<rect key="frame" x="385" y="7" width="30" height="16"/>
<buttonCell key="cell" type="recessed" title="Raw" bezelStyle="recessed" alignment="center" state="on" imageScaling="proportionallyDown" inset="2" id="bRx-1D-NLK">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="systemBold" size="12"/>
</buttonCell>
<color key="contentTintColor" red="0.70980392156862748" green="0.49803921568627452" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<connections>
<action selector="rawButtonAction:" target="8u2-ww-n8g" id="vcZ-CW-yGn"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="yg1-GN-IMK" firstAttribute="centerY" secondItem="tH8-rD-qu8" secondAttribute="centerY" id="cWq-vS-yIg"/>
<constraint firstItem="TF2-SH-jlL" firstAttribute="leading" secondItem="yg1-GN-IMK" secondAttribute="trailing" constant="10" id="h7L-Pi-Ue6"/>
<constraint firstAttribute="trailing" secondItem="TF2-SH-jlL" secondAttribute="trailing" constant="10" id="zKF-W8-SOG"/>
</constraints>
</view>
@@ -108,19 +79,20 @@
</constraints>
<color key="fillColor" name="contentBottomBarColor"/>
</box>
<progressIndicator wantsLayer="YES" horizontalHuggingPriority="750" verticalHuggingPriority="750" maxValue="100" bezeled="NO" indeterminate="YES" controlSize="small" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="lIx-UW-mkL">
<rect key="frame" x="217" y="157" width="16" height="16"/>
</progressIndicator>
</subviews>
<constraints>
<constraint firstItem="Kzt-Tt-u1z" firstAttribute="leading" secondItem="IZk-5R-el5" secondAttribute="leading" constant="5" id="7Gh-Km-9aI"/>
<constraint firstAttribute="trailing" secondItem="aFQ-TQ-tH5" secondAttribute="trailing" id="D4w-JE-KvI"/>
<constraint firstItem="Kzt-Tt-u1z" firstAttribute="top" secondItem="IZk-5R-el5" secondAttribute="top" constant="5" id="FnJ-NZ-XH3"/>
<constraint firstItem="aFQ-TQ-tH5" firstAttribute="top" secondItem="1KQ-pz-LuO" secondAttribute="bottom" constant="5" id="NC6-1q-sWf"/>
<constraint firstItem="1KQ-pz-LuO" firstAttribute="top" secondItem="IZk-5R-el5" secondAttribute="top" constant="5" id="VCN-3B-15j"/>
<constraint firstItem="lIx-UW-mkL" firstAttribute="centerY" secondItem="Kzt-Tt-u1z" secondAttribute="centerY" id="TfO-gP-mGf"/>
<constraint firstAttribute="bottom" secondItem="aFQ-TQ-tH5" secondAttribute="bottom" id="XZk-qL-jn6"/>
<constraint firstAttribute="trailing" secondItem="1KQ-pz-LuO" secondAttribute="trailing" constant="5" id="XeR-ym-LFH"/>
<constraint firstAttribute="trailing" secondItem="Kzt-Tt-u1z" secondAttribute="trailing" constant="5" id="ceY-2X-tZr"/>
<constraint firstItem="1KQ-pz-LuO" firstAttribute="leading" secondItem="IZk-5R-el5" secondAttribute="leading" constant="5" id="jyS-XC-0ce"/>
<constraint firstItem="aFQ-TQ-tH5" firstAttribute="top" secondItem="Kzt-Tt-u1z" secondAttribute="bottom" constant="5" id="oQ5-XH-nr0"/>
<constraint firstItem="aFQ-TQ-tH5" firstAttribute="leading" secondItem="IZk-5R-el5" secondAttribute="leading" id="oyz-R8-6Ls"/>
<constraint firstItem="lIx-UW-mkL" firstAttribute="centerX" secondItem="Kzt-Tt-u1z" secondAttribute="centerX" id="vVt-fc-1dk"/>
</constraints>
</view>
<color key="fillColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
@@ -135,10 +107,9 @@
</view>
<connections>
<outlet property="copyToClipboardButton" destination="TF2-SH-jlL" id="3TU-hc-eWY"/>
<outlet property="rawButton" destination="yg1-GN-IMK" id="l6P-tZ-Hdr"/>
<outlet property="progressIndicator" destination="lIx-UW-mkL" id="sro-h4-fgO"/>
<outlet property="rawTextScrollView" destination="Kzt-Tt-u1z" id="VUq-Jn-laj"/>
<outlet property="rawTextView" destination="mk4-BM-kwp" id="OKy-sC-5hZ"/>
<outlet property="webView" destination="1KQ-pz-LuO" id="Ky7-EI-Wvj"/>
</connections>
</viewController>
<customObject id="4sz-TD-uE0" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
@@ -207,8 +178,21 @@
<action selector="copyButtonAction:" target="dbv-oR-1ws" id="ZeH-wK-TFV"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ze8-fq-lWt">
<rect key="frame" x="379" y="7" width="36" height="16"/>
<buttonCell key="cell" type="recessed" title="cURL" bezelStyle="recessed" alignment="center" state="on" imageScaling="proportionallyDown" inset="2" id="MSt-7f-JHj">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="systemBold" size="12"/>
</buttonCell>
<color key="contentTintColor" red="0.70980392160000005" green="0.49803921569999998" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<connections>
<action selector="curlButtonAction:" target="dbv-oR-1ws" id="H2c-aD-nWX"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="ze8-fq-lWt" firstAttribute="centerY" secondItem="9zZ-1e-l97" secondAttribute="centerY" id="9Mr-Ib-eBx"/>
<constraint firstItem="U6O-Tm-OuZ" firstAttribute="leading" secondItem="ze8-fq-lWt" secondAttribute="trailing" constant="10" id="pzJ-6j-Rbh"/>
<constraint firstAttribute="trailing" secondItem="U6O-Tm-OuZ" secondAttribute="trailing" constant="10" id="tkO-3l-Gzv"/>
</constraints>
</view>
@@ -241,6 +225,7 @@
</view>
<connections>
<outlet property="copyToClipboardButton" destination="U6O-Tm-OuZ" id="Bis-TZ-SjP"/>
<outlet property="curlButton" destination="ze8-fq-lWt" id="FCG-bS-aGL"/>
<outlet property="overviewTextView" destination="yGA-r3-ock" id="sTN-fX-keW"/>
</connections>
</viewController>
@@ -290,7 +275,7 @@
<fragment content="sad kasd jasj dksad jkasjd jkasdjk asjkd jksadjk asjk djksajk jkdajk jkdsa jkdjk jkas djkkajsa dk">
<attributes>
<color key="NSColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<font key="NSFont" size="13" name="DroidSansMono"/>
<font key="NSFont" metaFont="system"/>
<paragraphStyle key="NSParagraphStyle" alignment="natural" lineBreakMode="wordWrapping" baseWritingDirection="natural" tighteningFactorForTruncation="0.0"/>
</attributes>
</fragment>
@@ -343,7 +328,7 @@
<rect key="frame" x="0.0" y="12" width="135" height="20"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" sendsActionOnEndEditing="YES" title="Table View Cell" id="3SO-nF-Jew">
<font key="font" size="12" name="DroidSansMono"/>
<font key="font" metaFont="cellTitle"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@@ -377,7 +362,7 @@
<rect key="frame" x="0.0" y="12" width="299" height="20"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" sendsActionOnEndEditing="YES" title="Table View Cell" id="GJr-nQ-UMJ">
<font key="font" size="12" name="DroidSansMono"/>
<font key="font" metaFont="cellTitle"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@@ -622,24 +607,24 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="mm2-yo-sQB">
<rect key="frame" x="-2" y="319" width="29" height="19"/>
<rect key="frame" x="-2" y="320" width="31" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="GET" id="S1x-ff-DRQ">
<font key="font" size="13" name="EffraMedium-Regular"/>
<font key="font" metaFont="systemBold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<box boxType="custom" borderWidth="0.0" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="dHd-eX-X4k" customClass="ContentBar" customModule="Bagel" customModuleProvider="target">
<rect key="frame" x="35" y="313" width="415" height="30"/>
<rect key="frame" x="37" y="313" width="413" height="30"/>
<view key="contentView" id="N8G-6p-Gm5">
<rect key="frame" x="0.0" y="0.0" width="415" height="30"/>
<rect key="frame" x="0.0" y="0.0" width="413" height="30"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="749" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Baz-mg-73Q">
<rect key="frame" x="3" y="6" width="409" height="18"/>
<rect key="frame" x="3" y="6" width="407" height="18"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" focusRingType="none" alignment="left" placeholderString="" id="0y6-ve-dir">
<font key="font" size="12" name="DroidSansMono"/>
<font key="font" metaFont="cellTitle"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</textFieldCell>
@@ -662,24 +647,24 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="VkR-Eh-dut">
<rect key="frame" x="8" y="24" width="43" height="14"/>
<rect key="frame" x="4" y="24" width="47" height="11"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="REQUEST" id="RAI-o2-Cnk">
<font key="font" size="9" name="Effra-Regular"/>
<font key="font" metaFont="miniSystem"/>
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="CjX-gd-hJy">
<rect key="frame" x="393" y="24" width="49" height="14"/>
<rect key="frame" x="393" y="24" width="53" height="11"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="RESPONSE" id="To7-5v-rDc">
<font key="font" size="9" name="Effra-Regular"/>
<font key="font" metaFont="miniSystem"/>
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="bAp-ri-UFe">
<rect key="frame" x="10" y="5" width="61" height="16"/>
<buttonCell key="cell" type="recessed" title="Overview" bezelStyle="recessed" alignment="center" imageScaling="proportionallyDown" inset="2" id="xgV-Ww-yRI">
<rect key="frame" x="5" y="5" width="61" height="16"/>
<buttonCell key="cell" type="recessed" title="Overview" bezelStyle="recessed" alignment="left" imageScaling="proportionallyDown" inset="2" id="xgV-Ww-yRI">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="systemBold" size="12"/>
</buttonCell>
@@ -689,7 +674,7 @@
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="8PC-Xx-Vf2">
<rect key="frame" x="76" y="5" width="55" height="16"/>
<rect key="frame" x="71" y="5" width="55" height="16"/>
<buttonCell key="cell" type="recessed" title="Headers" bezelStyle="recessed" alignment="center" imageScaling="proportionallyDown" inset="2" id="KXE-eM-j9x">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="systemBold" size="12"/>
@@ -700,7 +685,7 @@
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="n6S-iw-EMD">
<rect key="frame" x="136" y="5" width="74" height="16"/>
<rect key="frame" x="131" y="5" width="74" height="16"/>
<buttonCell key="cell" type="recessed" title="Parameters" bezelStyle="recessed" alignment="center" imageScaling="proportionallyDown" inset="2" id="uXx-df-zfb">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="systemBold" size="12"/>
@@ -711,7 +696,7 @@
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="q0l-Zj-81U">
<rect key="frame" x="215" y="5" width="35" height="16"/>
<rect key="frame" x="210" y="5" width="35" height="16"/>
<buttonCell key="cell" type="recessed" title="Body" bezelStyle="recessed" alignment="center" imageScaling="proportionallyDown" inset="2" id="OwQ-ev-5Ro">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="systemBold" size="12"/>
@@ -747,18 +732,18 @@
<constraints>
<constraint firstItem="8PC-Xx-Vf2" firstAttribute="leading" secondItem="bAp-ri-UFe" secondAttribute="trailing" constant="5" id="1mc-yz-mgq"/>
<constraint firstAttribute="bottom" secondItem="q0l-Zj-81U" secondAttribute="bottom" constant="5" id="3k5-tO-FAq"/>
<constraint firstItem="CjX-gd-hJy" firstAttribute="top" secondItem="mdX-jW-LeM" secondAttribute="top" constant="2" id="5zO-JW-fKB"/>
<constraint firstItem="CjX-gd-hJy" firstAttribute="top" secondItem="mdX-jW-LeM" secondAttribute="top" constant="5" id="5zO-JW-fKB"/>
<constraint firstAttribute="bottom" secondItem="n6S-iw-EMD" secondAttribute="bottom" constant="5" id="F7d-r1-iQi"/>
<constraint firstAttribute="bottom" secondItem="iHW-q5-odR" secondAttribute="bottom" constant="5" id="Gac-Ke-z7e"/>
<constraint firstItem="c5S-pb-Yh4" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="q0l-Zj-81U" secondAttribute="trailing" constant="10" id="MQY-bY-Jpb"/>
<constraint firstItem="n6S-iw-EMD" firstAttribute="leading" secondItem="8PC-Xx-Vf2" secondAttribute="trailing" constant="5" id="PnM-tu-QVt"/>
<constraint firstAttribute="bottom" secondItem="bAp-ri-UFe" secondAttribute="bottom" constant="5" id="Qgl-om-xeI"/>
<constraint firstItem="bAp-ri-UFe" firstAttribute="leading" secondItem="mdX-jW-LeM" secondAttribute="leading" constant="10" id="byv-vb-2FQ"/>
<constraint firstItem="bAp-ri-UFe" firstAttribute="leading" secondItem="mdX-jW-LeM" secondAttribute="leading" constant="5" id="byv-vb-2FQ"/>
<constraint firstAttribute="bottom" secondItem="8PC-Xx-Vf2" secondAttribute="bottom" constant="5" id="elQ-Cu-eps"/>
<constraint firstItem="q0l-Zj-81U" firstAttribute="leading" secondItem="n6S-iw-EMD" secondAttribute="trailing" constant="5" id="gVc-ZG-ZpH"/>
<constraint firstItem="VkR-Eh-dut" firstAttribute="top" secondItem="mdX-jW-LeM" secondAttribute="top" constant="2" id="mZJ-VP-TjL"/>
<constraint firstItem="VkR-Eh-dut" firstAttribute="leading" secondItem="mdX-jW-LeM" secondAttribute="leading" constant="10" id="o3O-wX-HgZ"/>
<constraint firstAttribute="trailing" secondItem="CjX-gd-hJy" secondAttribute="trailing" constant="10" id="r14-ow-HHw"/>
<constraint firstItem="VkR-Eh-dut" firstAttribute="top" secondItem="mdX-jW-LeM" secondAttribute="top" constant="5" id="mZJ-VP-TjL"/>
<constraint firstItem="VkR-Eh-dut" firstAttribute="leading" secondItem="mdX-jW-LeM" secondAttribute="leading" constant="6" id="o3O-wX-HgZ"/>
<constraint firstAttribute="trailing" secondItem="CjX-gd-hJy" secondAttribute="trailing" constant="6" id="r14-ow-HHw"/>
<constraint firstItem="iHW-q5-odR" firstAttribute="leading" secondItem="c5S-pb-Yh4" secondAttribute="trailing" constant="5" id="rh1-ij-aqe"/>
<constraint firstItem="iHW-q5-odR" firstAttribute="leading" secondItem="c5S-pb-Yh4" secondAttribute="trailing" constant="5" id="uTv-Ai-tkP"/>
<constraint firstAttribute="trailing" secondItem="iHW-q5-odR" secondAttribute="trailing" constant="5" id="wBp-gU-t8d"/>
@@ -0,0 +1,28 @@
//
// DatePacketTableCellView.swift
// Bagel
//
// Created by Yagiz Gurgul on 22.10.2018.
// Copyright © 2018 Yagiz Lab. All rights reserved.
//
import Cocoa
import macOSThemeKit
class DatePacketTableCellView: NSTableCellView {
@IBOutlet private weak var titleTextField: NSTextField!
var packet: BagelPacket? {
didSet{
guard let packet = packet else { return }
refresh(with: packet)
}
}
func refresh(with packet: BagelPacket) {
titleTextField.textColor = ThemeColor.secondaryLabelColor
titleTextField.stringValue = packet.requestInfo?.startDate?.readable ?? ""
}
}
@@ -0,0 +1,48 @@
//
// MethodPacketTableCellView.swift
// Bagel
//
// Created by Yagiz Gurgul on 31.12.2018.
// Copyright © 2018 Yagiz Lab. All rights reserved.
//
import Cocoa
import macOSThemeKit
class MethodPacketTableCellView: NSTableCellView {
@IBOutlet private weak var titleTextField: NSTextField!
var packet: BagelPacket?{
didSet{
guard let packet = packet else { return }
refresh(with: packet)
}
}
func refresh(with packet: BagelPacket) {
var methodColor = ThemeColor.httpMethodDefaultColor
if let requestMethod = packet.requestInfo?.requestMethod {
switch requestMethod {
case .get:
methodColor = ThemeColor.httpMethodGetColor
case .put:
methodColor = ThemeColor.httpMethodPutColor
case .post:
methodColor = ThemeColor.httpMethodPostColor
case .delete:
methodColor = ThemeColor.httpMethodDeleteColor
case .patch:
methodColor = ThemeColor.httpMethodPatchColor
case .head:
break
}
}
self.titleTextField.textColor = methodColor
self.titleTextField.stringValue = packet.requestInfo?.requestMethod?.rawValue ?? ""
}
}
@@ -0,0 +1,28 @@
//
// URLPacketTableCellView.swift
// Bagel
//
// Created by Yagiz Gurgul on 1.10.2018.
// Copyright © 2018 Yagiz Lab. All rights reserved.
//
import Cocoa
import macOSThemeKit
class URLPacketTableCellView: NSTableCellView {
@IBOutlet private weak var titleTextField: NSTextField!
var packet: BagelPacket? {
didSet{
guard let packet = packet else { return }
refresh(with: packet)
}
}
func refresh(with packet: BagelPacket) {
titleTextField.textColor = ThemeColor.labelColor
titleTextField.stringValue = packet.requestInfo?.url ?? ""
}
}
@@ -1,30 +0,0 @@
//
// DatePacketTableCellView.swift
// Bagel
//
// Created by Yagiz Gurgul on 22.10.2018.
// Copyright © 2018 Yagiz Lab. All rights reserved.
//
import Cocoa
import macOSThemeKit
class DatePacketTableCellView: NSTableCellView {
@IBOutlet weak var titleTextField: NSTextField!
var packet: BagelPacket!
{
didSet
{
self.refresh()
}
}
func refresh() {
self.titleTextField.textColor = ThemeColor.secondaryLabelColor
self.titleTextField.stringValue = self.packet.requestInfo?.startDate?.readble ?? ""
}
}
@@ -1,42 +0,0 @@
//
// MethodPacketTableCellView.swift
// Bagel
//
// Created by Yagiz Gurgul on 31.12.2018.
// Copyright © 2018 Yagiz Lab. All rights reserved.
//
import Cocoa
import macOSThemeKit
class MethodPacketTableCellView: NSTableCellView {
@IBOutlet weak var titleTextField: NSTextField!
var packet: BagelPacket!
{
didSet
{
self.refresh()
}
}
func refresh() {
var methodColor = ThemeColor.httpMethodDefaultColor
if self.packet.requestInfo?.requestMethod == "GET" {
methodColor = ThemeColor.httpMethodGetColor
}else if self.packet.requestInfo?.requestMethod == "POST" {
methodColor = ThemeColor.httpMethodPostColor
}else if self.packet.requestInfo?.requestMethod == "PUT" {
methodColor = ThemeColor.httpMethodPutColor
}else if self.packet.requestInfo?.requestMethod == "DELETE" {
methodColor = ThemeColor.httpMethodDeleteColor
}
self.titleTextField.textColor = methodColor
self.titleTextField.stringValue = self.packet.requestInfo?.requestMethod ?? ""
}
}
+115 -25
View File
@@ -62,16 +62,20 @@
<rect key="frame" x="1" y="1" width="40" height="20"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="RPO-QB-zWr">
<rect key="frame" x="5" y="0.0" width="34" height="20"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="RPO-QB-zWr">
<rect key="frame" x="1" y="2" width="38" height="16"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="200" id="nCW-um-xTy">
<font key="font" size="12" name="DroidSansMono"/>
<font key="font" metaFont="cellTitle"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="RPO-QB-zWr" secondAttribute="trailing" constant="3" id="Bl5-Mf-dwQ"/>
<constraint firstItem="RPO-QB-zWr" firstAttribute="leading" secondItem="VPk-w5-xdq" secondAttribute="leading" constant="3" id="YyA-98-4ns"/>
<constraint firstItem="RPO-QB-zWr" firstAttribute="centerY" secondItem="VPk-w5-xdq" secondAttribute="centerY" id="bJ7-DX-WK4"/>
</constraints>
<connections>
<outlet property="titleTextField" destination="RPO-QB-zWr" id="VPe-A4-zOx"/>
</connections>
@@ -94,16 +98,20 @@
<rect key="frame" x="44" y="1" width="52" height="20"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9sG-qU-mJh">
<rect key="frame" x="5" y="0.0" width="46" height="20"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="9sG-qU-mJh">
<rect key="frame" x="1" y="2" width="50" height="16"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="GET" id="Ntk-Pw-UR8">
<font key="font" size="12" name="DroidSansMono"/>
<font key="font" metaFont="cellTitle"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstItem="9sG-qU-mJh" firstAttribute="centerY" secondItem="eqC-zI-qTu" secondAttribute="centerY" id="NId-x2-FL3"/>
<constraint firstItem="9sG-qU-mJh" firstAttribute="leading" secondItem="eqC-zI-qTu" secondAttribute="leading" constant="3" id="VuC-XE-gYP"/>
<constraint firstAttribute="trailing" secondItem="9sG-qU-mJh" secondAttribute="trailing" constant="3" id="pQk-mB-u44"/>
</constraints>
<connections>
<outlet property="titleTextField" destination="9sG-qU-mJh" id="yHT-2o-p1v"/>
</connections>
@@ -127,16 +135,20 @@
<rect key="frame" x="99" y="1" width="142" height="20"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Ipb-Zo-mzM">
<rect key="frame" x="5" y="2" width="136" height="18"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="Ipb-Zo-mzM">
<rect key="frame" x="1" y="2" width="140" height="16"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" sendsActionOnEndEditing="YES" title="Table View Cell" id="ADt-eY-pVa">
<font key="font" size="12" name="DroidSansMono"/>
<font key="font" metaFont="cellTitle"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstItem="Ipb-Zo-mzM" firstAttribute="centerY" secondItem="gqm-6g-9Tm" secondAttribute="centerY" id="089-Tb-l6q"/>
<constraint firstAttribute="trailing" secondItem="Ipb-Zo-mzM" secondAttribute="trailing" constant="3" id="RTe-RC-zjX"/>
<constraint firstItem="Ipb-Zo-mzM" firstAttribute="leading" secondItem="gqm-6g-9Tm" secondAttribute="leading" constant="3" id="Yxt-Rz-Fyj"/>
</constraints>
<connections>
<outlet property="titleTextField" destination="Ipb-Zo-mzM" id="799-wV-bdT"/>
</connections>
@@ -160,16 +172,20 @@
<rect key="frame" x="244" y="1" width="319" height="20"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="lqc-CZ-vWv">
<rect key="frame" x="5" y="2" width="313" height="18"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="lqc-CZ-vWv">
<rect key="frame" x="1" y="2" width="317" height="16"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" sendsActionOnEndEditing="YES" title="Table View Cell" id="j9t-nF-LfF">
<font key="font" size="12" name="DroidSansMono"/>
<font key="font" metaFont="cellTitle"/>
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="lqc-CZ-vWv" secondAttribute="trailing" constant="3" id="1sE-0a-tGJ"/>
<constraint firstItem="lqc-CZ-vWv" firstAttribute="centerY" secondItem="0Hf-Bc-1kK" secondAttribute="centerY" id="JmM-u4-IIX"/>
<constraint firstItem="lqc-CZ-vWv" firstAttribute="leading" secondItem="0Hf-Bc-1kK" secondAttribute="leading" constant="3" id="OSr-vD-oKm"/>
</constraints>
<connections>
<outlet property="titleTextField" destination="lqc-CZ-vWv" id="1uF-Ck-sP4"/>
</connections>
@@ -218,25 +234,25 @@
</connections>
</button>
<box boxType="custom" borderWidth="0.0" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="ECf-Ip-WqV">
<rect key="frame" x="5" y="5" width="200" height="20"/>
<rect key="frame" x="56" y="5" width="200" height="20"/>
<view key="contentView" id="Vap-9R-hh7">
<rect key="frame" x="0.0" y="0.0" width="200" height="20"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Nh8-PV-Qe4">
<rect key="frame" x="3" y="0.0" width="194" height="20"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" focusRingType="none" placeholderString="Filter" id="OhO-md-Jfb">
<font key="font" size="13" name="Effra-Regular"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" focusRingType="none" alignment="left" placeholderString="URL" id="OhO-md-Jfb" customClass="VerticallyCenteredTextFieldCell" customModule="Bagel" customModuleProvider="target">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="labelColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstItem="Nh8-PV-Qe4" firstAttribute="top" secondItem="Vap-9R-hh7" secondAttribute="top" id="MVc-al-bQg"/>
<constraint firstAttribute="bottom" secondItem="Nh8-PV-Qe4" secondAttribute="bottom" id="OFG-SD-vdg"/>
<constraint firstItem="Nh8-PV-Qe4" firstAttribute="leading" secondItem="Vap-9R-hh7" secondAttribute="leading" constant="5" id="fZy-Mx-aKw"/>
<constraint firstAttribute="trailing" secondItem="Nh8-PV-Qe4" secondAttribute="trailing" constant="5" id="sjk-3w-cno"/>
<constraint firstAttribute="trailing" secondItem="Nh8-PV-Qe4" secondAttribute="trailing" constant="5" id="4ZG-Sf-1uU"/>
<constraint firstItem="Nh8-PV-Qe4" firstAttribute="top" secondItem="Vap-9R-hh7" secondAttribute="top" id="B0T-d6-3Tn"/>
<constraint firstAttribute="bottom" secondItem="Nh8-PV-Qe4" secondAttribute="bottom" id="YGK-pm-Vwj"/>
<constraint firstItem="Nh8-PV-Qe4" firstAttribute="leading" secondItem="Vap-9R-hh7" secondAttribute="leading" constant="5" id="afa-g0-7um"/>
</constraints>
</view>
<constraints>
@@ -244,11 +260,83 @@
</constraints>
<color key="fillColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</box>
<box boxType="custom" borderWidth="0.0" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="iSU-u4-CHh">
<rect key="frame" x="264" y="5" width="72" height="20"/>
<view key="contentView" id="bTY-Gz-LX8">
<rect key="frame" x="0.0" y="0.0" width="72" height="20"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="K4O-j7-3QY">
<rect key="frame" x="3" y="0.0" width="66" height="20"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" focusRingType="none" placeholderString="Status" id="phe-Xy-3Ds" customClass="VerticallyCenteredTextFieldCell" customModule="Bagel" customModuleProvider="target">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="labelColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstItem="K4O-j7-3QY" firstAttribute="top" secondItem="bTY-Gz-LX8" secondAttribute="top" id="FDv-mK-aCx"/>
<constraint firstAttribute="bottom" secondItem="K4O-j7-3QY" secondAttribute="bottom" id="NLP-tQ-b3h"/>
<constraint firstItem="K4O-j7-3QY" firstAttribute="leading" secondItem="bTY-Gz-LX8" secondAttribute="leading" constant="5" id="jYY-Gr-yNL"/>
<constraint firstAttribute="trailing" secondItem="K4O-j7-3QY" secondAttribute="trailing" constant="5" id="kQY-kN-zBh"/>
</constraints>
</view>
<constraints>
<constraint firstAttribute="width" constant="72" id="4UX-81-bxQ"/>
</constraints>
<color key="fillColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</box>
<box boxType="custom" borderWidth="0.0" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="D6h-Wu-m6x">
<rect key="frame" x="344" y="5" width="72" height="20"/>
<view key="contentView" id="c8Z-eD-ZA3">
<rect key="frame" x="0.0" y="0.0" width="72" height="20"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="H4n-d7-YFE">
<rect key="frame" x="3" y="0.0" width="66" height="20"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" focusRingType="none" placeholderString="Method" id="OPB-NY-4Xr" customClass="VerticallyCenteredTextFieldCell" customModule="Bagel" customModuleProvider="target">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="labelColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstItem="H4n-d7-YFE" firstAttribute="top" secondItem="c8Z-eD-ZA3" secondAttribute="top" id="9y6-Yi-ucB"/>
<constraint firstAttribute="bottom" secondItem="H4n-d7-YFE" secondAttribute="bottom" id="Cyz-B4-rvl"/>
<constraint firstItem="H4n-d7-YFE" firstAttribute="leading" secondItem="c8Z-eD-ZA3" secondAttribute="leading" constant="5" id="h4Y-eh-hvG"/>
<constraint firstAttribute="trailing" secondItem="H4n-d7-YFE" secondAttribute="trailing" constant="5" id="nUm-kG-UZt"/>
</constraints>
</view>
<constraints>
<constraint firstAttribute="width" constant="72" id="VTl-fD-bqE"/>
</constraints>
<color key="fillColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</box>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="mer-XV-N6Z">
<rect key="frame" x="6" y="7" width="44" height="17"/>
<textFieldCell key="cell" lineBreakMode="clipping" enabled="NO" alignment="left" title="Filters" usesSingleLineMode="YES" id="6LO-kQ-Zld">
<font key="font" metaFont="systemSemibold" size="13"/>
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstItem="ECf-Ip-WqV" firstAttribute="leading" secondItem="dvd-KM-mI8" secondAttribute="leading" constant="5" id="ABc-aZ-M1W"/>
<constraint firstItem="iSU-u4-CHh" firstAttribute="top" secondItem="ECf-Ip-WqV" secondAttribute="top" id="5oz-DR-Sw5"/>
<constraint firstItem="D6h-Wu-m6x" firstAttribute="centerY" secondItem="dvd-KM-mI8" secondAttribute="centerY" id="BZt-2l-JqE"/>
<constraint firstItem="iSU-u4-CHh" firstAttribute="leading" secondItem="ECf-Ip-WqV" secondAttribute="trailing" constant="8" id="CoD-4z-PnH"/>
<constraint firstAttribute="trailing" secondItem="9pa-LD-9G6" secondAttribute="trailing" constant="10" id="I5N-4v-LhZ"/>
<constraint firstItem="ECf-Ip-WqV" firstAttribute="leading" secondItem="mer-XV-N6Z" secondAttribute="trailing" constant="8" id="RK9-XR-Ise"/>
<constraint firstItem="mer-XV-N6Z" firstAttribute="centerY" secondItem="dvd-KM-mI8" secondAttribute="centerY" id="RTh-dM-w05"/>
<constraint firstItem="mer-XV-N6Z" firstAttribute="leading" secondItem="dvd-KM-mI8" secondAttribute="leading" constant="8" id="Xcv-L7-Hct"/>
<constraint firstItem="D6h-Wu-m6x" firstAttribute="top" secondItem="iSU-u4-CHh" secondAttribute="top" id="Yvc-7W-bLI"/>
<constraint firstItem="D6h-Wu-m6x" firstAttribute="leading" secondItem="iSU-u4-CHh" secondAttribute="trailing" constant="8" id="aN8-9B-2x0"/>
<constraint firstItem="iSU-u4-CHh" firstAttribute="centerY" secondItem="dvd-KM-mI8" secondAttribute="centerY" id="doj-wZ-8Ip"/>
<constraint firstItem="D6h-Wu-m6x" firstAttribute="bottom" secondItem="iSU-u4-CHh" secondAttribute="bottom" id="id1-Ml-nZr"/>
<constraint firstItem="ECf-Ip-WqV" firstAttribute="top" secondItem="dvd-KM-mI8" secondAttribute="top" constant="5" id="jC1-ca-z56"/>
<constraint firstItem="iSU-u4-CHh" firstAttribute="bottom" secondItem="ECf-Ip-WqV" secondAttribute="bottom" id="qNt-eG-ll1"/>
<constraint firstAttribute="bottom" secondItem="ECf-Ip-WqV" secondAttribute="bottom" constant="5" id="zBj-Zq-CfZ"/>
</constraints>
</view>
@@ -284,8 +372,10 @@
</constraints>
</view>
<connections>
<outlet property="addressFilterTextField" destination="Nh8-PV-Qe4" id="lwy-vX-lgx"/>
<outlet property="clearButton" destination="9pa-LD-9G6" id="IyR-HG-dqR"/>
<outlet property="filterTextField" destination="Nh8-PV-Qe4" id="lwy-vX-lgx"/>
<outlet property="methodFilterTextField" destination="H4n-d7-YFE" id="fPg-CN-Znu"/>
<outlet property="statusFilterTextField" destination="K4O-j7-3QY" id="BGB-aB-n5p"/>
<outlet property="tableView" destination="CKi-fU-sLr" id="v7l-Ps-Ash"/>
</connections>
</viewController>
@@ -10,7 +10,18 @@ import Cocoa
import macOSThemeKit
class PacketsViewController: BaseViewController {
struct TableIdentifiers {
static let statusCode = "statusCode"
static let method = "method"
static let url = "url"
static let date = "date"
}
enum FilterTags: Int {
case address, status, method
}
static var statusColumnWidth = CGFloat(50.0)
static var methodColumnWidth = CGFloat(55.0)
static var dateColumnWidth = CGFloat(150.0)
@@ -20,7 +31,10 @@ class PacketsViewController: BaseViewController {
@IBOutlet weak var clearButton: NSButton!
@IBOutlet weak var tableView: BaseTableView!
@IBOutlet weak var filterTextField: NSTextField!
@IBOutlet weak var addressFilterTextField: NSTextField!
@IBOutlet weak var statusFilterTextField: NSTextField!
@IBOutlet weak var methodFilterTextField: NSTextField!
override func setup() {
@@ -31,133 +45,120 @@ class PacketsViewController: BaseViewController {
self.tableView.backgroundColor = ThemeColor.controlBackgroundColor
self.tableView.gridColor = ThemeColor.gridColor
self.filterTextField.backgroundColor = ThemeColor.controlBackgroundColor
self.filterTextField.delegate = self
setupFilterTextFields()
self.viewModel?.onChange = { [weak self] in
self?.refresh()
}
self.setupTableViewHeaders()
}
private func setupFilterTextFields() {
self.addressFilterTextField.backgroundColor = ThemeColor.controlBackgroundColor
self.addressFilterTextField.tag = FilterTags.address.rawValue
self.addressFilterTextField.delegate = self
self.statusFilterTextField.backgroundColor = ThemeColor.controlBackgroundColor
self.statusFilterTextField.tag = FilterTags.status.rawValue
self.statusFilterTextField.delegate = self
self.methodFilterTextField.backgroundColor = ThemeColor.controlBackgroundColor
self.methodFilterTextField.tag = FilterTags.method.rawValue
self.methodFilterTextField.delegate = self
}
func refresh() {
let isScrolledToBottom = self.isScrolledToBottom()
self.tableView.reloadData()
if let selectedItemIndex = self.viewModel?.selectedItemIndex {
self.tableView.selectRowIndexes(IndexSet(integer: selectedItemIndex), byExtendingSelection: false)
}
if isScrolledToBottom {
if isScrolledToBottom() {
self.scrollToBottom()
}
}
func setupTableViewHeaders() {
for tableColumn in self.tableView.tableColumns {
if tableColumn.identifier.rawValue == "statusCode" {
switch tableColumn.identifier.rawValue {
case TableIdentifiers.statusCode:
tableColumn.headerCell = FlatTableHeaderCell(textCell: "Status")
tableColumn.width = PacketsViewController.statusColumnWidth
}else if tableColumn.identifier.rawValue == "method" {
case TableIdentifiers.method:
tableColumn.headerCell = FlatTableHeaderCell(textCell: "Method")
tableColumn.width = PacketsViewController.methodColumnWidth
}else if tableColumn.identifier.rawValue == "url" {
case TableIdentifiers.url:
tableColumn.headerCell = FlatTableHeaderCell(textCell: "URL")
tableColumn.width = self.view.frame.size.width - PacketsViewController.statusColumnWidth - PacketsViewController.dateColumnWidth - PacketsViewController.methodColumnWidth
}else if tableColumn.identifier.rawValue == "date" {
tableColumn.width = self.view.frame.size.width - PacketsViewController.statusColumnWidth - PacketsViewController.dateColumnWidth - PacketsViewController.methodColumnWidth
case TableIdentifiers.date:
tableColumn.headerCell = FlatTableHeaderCell(textCell: "Date")
tableColumn.width = PacketsViewController.dateColumnWidth
default:
break
}
}
}
@IBAction func clearButtonAction(_ sender: Any) {
self.viewModel?.clearPackets()
}
}
extension PacketsViewController: NSTableViewDelegate, NSTableViewDataSource
{
extension PacketsViewController: NSTableViewDelegate, NSTableViewDataSource {
func numberOfRows(in tableView: NSTableView) -> Int {
return self.viewModel?.itemCount() ?? 0
}
func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? {
return FlatTableRowView()
}
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
guard let identifier = tableColumn?.identifier.rawValue else { return nil }
if (tableColumn?.identifier)!.rawValue == "statusCode" {
switch identifier {
case TableIdentifiers.statusCode:
let cell: StatusPacketTableCellView = self.tableView.makeView(withOwner: nil)!
cell.packet = self.viewModel?.item(at: row)
cell.backgroundStyle = .normal
return cell
}else if (tableColumn?.identifier)!.rawValue == "method" {
case TableIdentifiers.method:
let cell: MethodPacketTableCellView = self.tableView.makeView(withOwner: nil)!
cell.packet = self.viewModel?.item(at: row)
cell.backgroundStyle = .normal
return cell
}else if (tableColumn?.identifier)!.rawValue == "url" {
case TableIdentifiers.url:
let cell: URLPacketTableCellView = self.tableView.makeView(withOwner: nil)!
cell.packet = self.viewModel?.item(at: row)
cell.backgroundStyle = .normal
return cell
}else if (tableColumn?.identifier)!.rawValue == "date" {
case TableIdentifiers.date:
let cell: DatePacketTableCellView = self.tableView.makeView(withOwner: nil)!
cell.packet = self.viewModel?.item(at: row)
cell.backgroundStyle = .normal
return cell
default:
return nil
}
return nil
}
func tableViewSelectionDidChange(_ notification: Notification) {
let selectedRow = self.tableView.selectedRow
if selectedRow >= 0 , let item = self.viewModel?.item(at: selectedRow) {
if item !== self.viewModel?.selectedItem {
self.onPacketSelect?(item)
}
}else {
guard selectedRow >= 0, let item = self.viewModel?.item(at: selectedRow) else {
self.onPacketSelect?(nil)
return
}
guard item !== self.viewModel?.selectedItem else { return }
self.onPacketSelect?(item)
}
}
@@ -166,8 +167,18 @@ extension PacketsViewController: NSTableViewDelegate, NSTableViewDataSource
extension PacketsViewController: NSTextFieldDelegate {
func controlTextDidChange(_ obj: Notification) {
guard let tag = (obj.object as? NSTextField)?.tag else { return }
guard let filterTag = FilterTags(rawValue: tag) else { return }
self.viewModel?.filterTerm = self.filterTextField.stringValue
switch filterTag {
case .address:
viewModel?.addressFilterTerm = addressFilterTextField.stringValue
case .method:
viewModel?.methodFilterTerm = methodFilterTextField.stringValue
case .status:
viewModel?.statusFilterTerm = statusFilterTextField.stringValue
}
}
}
@@ -176,17 +187,11 @@ extension PacketsViewController: NSTextFieldDelegate {
extension PacketsViewController {
func isScrolledToBottom() -> Bool {
if self.tableView.enclosingScrollView?.verticalScroller?.floatValue ?? 0 > 0.9 {
return true
}
return false
return tableView.enclosingScrollView?.verticalScroller?.floatValue ?? 0 > 0.9
}
func scrollToBottom() {
self.tableView.scrollToEndOfDocument(nil)
tableView.scrollToEndOfDocument(nil)
}
}
@@ -9,15 +9,31 @@
import Cocoa
class PacketsViewModel: BaseListViewModel<BagelPacket> {
var filterTerm = "" {
var addressFilterTerm = "" {
didSet {
self.refreshItems()
}
}
var methodFilterTerm = "" {
didSet {
self.refreshItems()
}
}
var statusFilterTerm = "" {
didSet {
self.refreshItems()
}
}
private var allPackets: [BagelPacket] {
return BagelController.shared.selectedProjectController?.selectedDeviceController?.packets ?? []
}
func register() {
NotificationCenter.default.addObserver(self, selector: #selector(self.refreshItems), name: BagelNotifications.didGetPacket, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.refreshItems), name: BagelNotifications.didUpdatePacket, object: nil)
@@ -27,46 +43,61 @@ class PacketsViewModel: BaseListViewModel<BagelPacket> {
NotificationCenter.default.addObserver(self, selector: #selector(self.refreshItems), name: BagelNotifications.didSelectDevice, object: nil)
}
var selectedItem: BagelPacket? {
return BagelController.shared.selectedProjectController?.selectedDeviceController?.selectedPacket
}
var selectedItemIndex: Int? {
guard let selectedItem = self.selectedItem else { return nil }
if let selectedItem = self.selectedItem {
return self.items.firstIndex { $0 === selectedItem }
}
return nil
return self.items.firstIndex { $0 === selectedItem }
}
@objc func refreshItems() {
self.filter(items: BagelController.shared.selectedProjectController?.selectedDeviceController?.packets ?? [])
self.onChange?()
items = filter(items: allPackets)
onChange?()
}
func filter(items: [BagelPacket]?) {
func filter(items: [BagelPacket]) -> [BagelPacket] {
var filteredItems = performAddressFiltration(items)
filteredItems = performMethodFiltration(filteredItems)
return performStatusFiltration(filteredItems)
}
func performAddressFiltration(_ items: [BagelPacket]) -> [BagelPacket] {
guard addressFilterTerm.count > 0 else {
return items
}
if let items = items, filterTerm.count > 0 {
self.items = items.filter({ (packet) -> Bool in
return packet.requestInfo?.url?.contains(self.filterTerm) ?? true
})
}else{
self.items = BagelController.shared.selectedProjectController?.selectedDeviceController?.packets ?? []
return items.filter {
$0.requestInfo?.url?.contains(self.addressFilterTerm) ?? true }
}
func performMethodFiltration(_ items: [BagelPacket]) -> [BagelPacket] {
guard methodFilterTerm.count > 0 else {
return items
}
return items.filter
{ $0.requestInfo?.requestMethod?.rawValue.lowercased()
.contains(self.methodFilterTerm.lowercased()) ?? true }
}
func performStatusFiltration(_ items: [BagelPacket]) -> [BagelPacket] {
guard statusFilterTerm.count > 0 else {
return items
}
guard !statusFilterTerm.trimmingCharacters(in: .whitespaces).isEmpty else {
return items.filter { $0.requestInfo?.statusCode?.trimmingCharacters(in: .whitespaces).isEmpty ?? true}
}
return items.filter
{ $0.requestInfo?.statusCode?.contains(self.statusFilterTerm) ?? false
}
}
func clearPackets() {
BagelController.shared.selectedProjectController?.selectedDeviceController?.clear()
self.refreshItems()
}
@@ -1,30 +0,0 @@
//
// URLPacketTableCellView.swift
// Bagel
//
// Created by Yagiz Gurgul on 1.10.2018.
// Copyright © 2018 Yagiz Lab. All rights reserved.
//
import Cocoa
import macOSThemeKit
class URLPacketTableCellView: NSTableCellView {
@IBOutlet weak var titleTextField: NSTextField!
var packet: BagelPacket!
{
didSet
{
self.refresh()
}
}
func refresh() {
self.titleTextField.textColor = ThemeColor.labelColor
self.titleTextField.stringValue = self.packet.requestInfo?.url ?? ""
}
}
@@ -25,7 +25,7 @@ class ProjectTableCellView: NSTableCellView {
if self.isSelected {
self.titleTextField.font = FontManager.mainMediumFont(size: 14)
self.titleTextField.textColor = ThemeColor.textColor
self.titleTextField.textColor = ThemeColor.projectTextColor
}else {
self.titleTextField.font = FontManager.mainFont(size: 14)
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="14313.18" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14313.18"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14460.31"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
@@ -24,7 +24,7 @@
<rect key="frame" x="0.0" y="0.0" width="110" height="554"/>
<autoresizingMask key="autoresizingMask"/>
<size key="intercellSpacing" width="3" height="0.0"/>
<color key="backgroundColor" white="0.20000000000000001" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<color key="backgroundColor" name="windowFrameTextColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn width="107" minWidth="40" maxWidth="1000" id="rGP-F4-s0d">
@@ -54,10 +54,10 @@
<color key="fillColor" red="0.53333333333333333" green="0.32941176470588235" blue="0.81568627450980391" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</box>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="eTZ-eS-sg0">
<rect key="frame" x="8" y="16" width="35" height="19"/>
<rect key="frame" x="8" y="17" width="37" height="17"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" allowsUndo="NO" sendsActionOnEndEditing="YES" alignment="left" title="Label" id="Tv4-Qg-efw">
<font key="font" size="13" name="EffraMedium-Regular"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<font key="font" metaFont="system"/>
<color key="textColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
@@ -21,11 +21,8 @@ class ProjectsViewController: BaseViewController {
self.tableView.delegate = self
self.tableView.dataSource = self
self.tableView.backgroundColor = ThemeColor.projectListBackgroundColor
self.viewModel?.onChange = { [weak self] in
self?.refresh()
}
}
+2 -2
View File
@@ -19,9 +19,9 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<string>1.0.1</string>
<key>CFBundleVersion</key>
<string>100</string>
<string>101</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSHumanReadableCopyright</key>
+4
View File
@@ -59,6 +59,10 @@ extension DarkTheme {
return NSColor(hexString: "#232323")
}
@objc var projectTextColor: NSColor {
return NSColor(hexString: "#ffffff")
}
@objc var deviceListBackgroundColor: NSColor {
return NSColor(hexString: "#262626")
}
+4
View File
@@ -58,6 +58,10 @@ extension LightTheme {
return NSColor(hexString: "#232323")
}
@objc var projectTextColor: NSColor {
return NSColor(hexString: "#ffffff")
}
@objc var deviceListBackgroundColor: NSColor {
return NSColor(hexString: "#F6F6F6")
}
+8
View File
@@ -66,6 +66,10 @@ extension ThemeColor {
return ThemeColor.color(with: #function)
}
static var projectTextColor: ThemeColor {
return ThemeColor.color(with: #function)
}
static var deviceListBackgroundColor: ThemeColor {
return ThemeColor.color(with: #function)
}
@@ -97,6 +101,10 @@ extension ThemeColor {
return ThemeColor.color(with: #function)
}
static var httpMethodPatchColor: ThemeColor {
return ThemeColor.color(with: #function)
}
static var httpMethodDefaultColor: ThemeColor {
return ThemeColor.color(with: #function)
}
@@ -9,7 +9,6 @@
import Cocoa
class BagelPacket: Codable {
var packetId: String?
var requestInfo: BagelRequestInfo?
@@ -8,12 +8,21 @@
import Cocoa
enum RequestMethod: String, Codable {
case get = "GET"
case post = "POST"
case put = "PUT"
case delete = "DELETE"
case patch = "PATCH"
case head = "HEAD"
}
class BagelRequestInfo: Codable {
var url: String?
var requestHeaders: [String: String]?
var requestBody: String?
var requestMethod: String?
var requestMethod: RequestMethod?
var responseHeaders: [String: String]?
var responseData: String?
@@ -0,0 +1,52 @@
//
// CURLRepresentation.swift
// Bagel
//
// Created by Mathias Amnell on 2019-01-23.
// Copyright © 2019 Yagiz Lab. All rights reserved.
//
import Cocoa
class CURLRepresentation: ContentRepresentation {
init(requestInfo: BagelRequestInfo?) {
super.init()
if let requestInfo = requestInfo {
self.rawString = requestInfo.curlString
}
}
}
extension BagelRequestInfo {
// Credits to shaps80
// https://gist.github.com/shaps80/ba6a1e2d477af0383e8f19b87f53661d
fileprivate var curlString: String {
guard let url = url else { return "" }
var baseCommand = "curl \(url)"
if requestMethod == .head {
baseCommand += " --head"
}
var command = [baseCommand]
if let method = self.requestMethod, method != .get && method != .head {
command.append("-X \(method)")
}
if let headers = requestHeaders {
for (key, value) in headers where key != "Cookie" {
command.append("-H '\(key): \(value)'")
}
}
if let data = requestBody {
command.append("-d '\(data)'")
}
return command.joined(separator: " \\\n\t")
}
}
@@ -36,7 +36,7 @@ class DataRepresentationParser {
if let jsonString = String(data: jsonData, encoding: .utf8) {
let jsonData = DataJSONRepresentation(data: data)
jsonData.rawString = jsonString
jsonData.rawString = jsonString.replacingOccurrences(of: "\\/", with: "/")
return jsonData
}
}
@@ -18,7 +18,7 @@ class OverviewRepresentation: ContentRepresentation {
var overviewString = ""
overviewString = overviewString + (requestInfo.requestMethod ?? "")
overviewString = overviewString + (requestInfo.requestMethod?.rawValue ?? "")
overviewString = overviewString + " "
overviewString = overviewString + (requestInfo.url ?? "")
+1 -1
View File
@@ -62,7 +62,7 @@
}
if (value === null) {
return '<li><span class="key">"' + encode(key) + '": </span><span class="null">"' + encode(value) + '"</span></li>';
return '<li><span class="key">"' + encode(key) + '": </span><span class="null">null</span></li>';
}
switch(type){
+1 -1
View File
@@ -9,7 +9,7 @@
function renderJSONString(jsonString)
{
$('#json-container').jsonview(jsonString);
<!-- $('#json-container').jsonview(jsonString);-->
}
function changeThemeToLight() {
+2 -1
View File
@@ -1,5 +1,5 @@
# Uncomment the next line to define a global platform for your project
platform :osx, '10.10'
platform :osx, '10.11'
target 'Bagel' do
# Uncomment the next line if you're using Swift or would like to use dynamic frameworks
@@ -7,5 +7,6 @@ target 'Bagel' do
pod 'CocoaAsyncSocket'
pod 'macOSThemeKit', '~> 1.2.0'
pod 'Highlightr'
end
+7 -3
View File
@@ -1,20 +1,24 @@
PODS:
- CocoaAsyncSocket (7.6.3)
- Highlightr (2.1.0)
- macOSThemeKit (1.2.3)
DEPENDENCIES:
- CocoaAsyncSocket
- Highlightr
- macOSThemeKit (~> 1.2.0)
SPEC REPOS:
https://github.com/cocoapods/specs.git:
https://github.com/CocoaPods/Specs.git:
- CocoaAsyncSocket
- Highlightr
- macOSThemeKit
SPEC CHECKSUMS:
CocoaAsyncSocket: eafaa68a7e0ec99ead0a7b35015e0bf25d2c8987
Highlightr: 595f3e100737c8de41113385da8bd0b5b65212c6
macOSThemeKit: 651af12838675beac5547687226a270c294f8f84
PODFILE CHECKSUM: ebe70cf0430bb9673b9d2acef3c2a16142460de8
PODFILE CHECKSUM: 6e39cacd4a77b09b958e2e6f8b405bbc2340dfc2
COCOAPODS: 1.6.0.beta.2
COCOAPODS: 1.8.4