-
-
Notifications
You must be signed in to change notification settings - Fork 374
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Realtime updates #110
base: develop
Are you sure you want to change the base?
Realtime updates #110
Changes from 90 commits
f651263
7d6ef56
2c15600
0a6211c
25e31f5
7877f11
525bc90
377ed2b
39bb1d2
ab129b4
3f8da9f
552f92d
0cdd676
61a7135
f8b7c29
431a74a
e80fad4
3115a45
f670668
f8623eb
b84ccf0
a592d01
07204ba
0715615
595faa5
c4dbf86
be90707
ae7a970
4cb7863
8c34f57
b370ab3
f2f635c
d9b8301
1775cb4
5306c3f
82c448c
bfa0c5b
3b29dea
75f3f20
4c2e4cf
7cdc1b4
185f486
77d51ad
1321663
ca86931
d742a18
2115bac
ec48433
d05fc38
f23fec5
1b05881
89f4b77
ae14311
17f0f66
c221f94
b76b96b
ab5ea18
f6afff9
6f94d0b
6e4d6bf
e3850c1
5850255
644e6a6
e2afeec
3962ba6
02d03d1
aa81276
dcf4ae4
bf2e3d1
d9b8194
5115865
df7c104
fa10f66
a6bf27b
15e555b
f988096
c8ad2ec
c593cae
147748b
a77fdd2
d58bb30
1a19875
b3450d6
ab58a02
ffc1fee
8537d3f
b6e51d2
89aad8c
81d39ab
2f81a67
7219fd4
705c497
511558f
7d80af6
5ffb418
0ef518a
836439b
c9f35fa
55c016f
39d80a1
9910ef1
1e824f0
9b06f79
5c31131
a0ea910
e14097d
35321c2
7784601
0f6565a
a76cf97
b0c7a25
1fd9bab
eb74da9
5aadaa0
ae5e77f
1234229
44e1515
726444e
45b8748
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,65 +1,68 @@ | ||
.DS_Store | ||
*.xcuserdatad | ||
|
||
# Created by https://www.gitignore.io/api/xcode,osx | ||
|
||
### OSX ### | ||
*.DS_Store | ||
.AppleDouble | ||
.LSOverride | ||
|
||
# Icon must end with two \r | ||
.DS_Store | ||
*.xcuserdatad | ||
# Created by https://www.gitignore.io/api/xcode,osx | ||
### OSX ### | ||
*.DS_Store | ||
.AppleDouble | ||
.LSOverride | ||
# Icon must end with two \r | ||
Icon | ||
|
||
# Thumbnails | ||
._* | ||
|
||
# Files that might appear in the root of a volume | ||
.DocumentRevisions-V100 | ||
.fseventsd | ||
.Spotlight-V100 | ||
.TemporaryItems | ||
.Trashes | ||
.VolumeIcon.icns | ||
.com.apple.timemachine.donotpresent | ||
|
||
# Directories potentially created on remote AFP share | ||
.AppleDB | ||
.AppleDesktop | ||
Network Trash Folder | ||
Temporary Items | ||
.apdisk | ||
|
||
### Xcode ### | ||
# Xcode | ||
# | ||
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore | ||
|
||
## Build generated | ||
build/ | ||
DerivedData/ | ||
|
||
## Various settings | ||
*.pbxuser | ||
!default.pbxuser | ||
*.mode1v3 | ||
!default.mode1v3 | ||
*.mode2v3 | ||
!default.mode2v3 | ||
*.perspectivev3 | ||
!default.perspectivev3 | ||
xcuserdata/ | ||
|
||
## Other | ||
*.moved-aside | ||
*.xccheckout | ||
*.xcscmblueprint | ||
|
||
### Xcode Patch ### | ||
*.xcodeproj/* | ||
!*.xcodeproj/project.pbxproj | ||
!*.xcodeproj/xcshareddata/ | ||
!*.xcworkspace/contents.xcworkspacedata | ||
/*.gcno | ||
|
||
# End of https://www.gitignore.io/api/xcode,osx | ||
|
||
# Thumbnails | ||
._* | ||
|
||
# Files that might appear in the root of a volume | ||
.DocumentRevisions-V100 | ||
.fseventsd | ||
.Spotlight-V100 | ||
.TemporaryItems | ||
.Trashes | ||
.VolumeIcon.icns | ||
.com.apple.timemachine.donotpresent | ||
|
||
# Directories potentially created on remote AFP share | ||
.AppleDB | ||
.AppleDesktop | ||
Network Trash Folder | ||
Temporary Items | ||
.apdisk | ||
|
||
### Xcode ### | ||
# Xcode | ||
# | ||
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore | ||
|
||
## Build generated | ||
build/ | ||
DerivedData/ | ||
|
||
## Various settings | ||
*.pbxuser | ||
!default.pbxuser | ||
*.mode1v3 | ||
!default.mode1v3 | ||
*.mode2v3 | ||
!default.mode2v3 | ||
*.perspectivev3 | ||
!default.perspectivev3 | ||
xcuserdata/ | ||
|
||
## Other | ||
*.moved-aside | ||
*.xccheckout | ||
*.xcscmblueprint | ||
|
||
### Xcode Patch ### | ||
*.xcodeproj/* | ||
!*.xcodeproj/project.pbxproj | ||
!*.xcodeproj/xcshareddata/ | ||
!*.xcworkspace/contents.xcworkspacedata | ||
/*.gcno | ||
|
||
# End of https://www.gitignore.io/api/xcode,osx | ||
|
||
Pods/ | ||
*.xcworkspace/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
//: Playground - noun: a place where people can play | ||
|
||
import Foundation | ||
import PlaygroundSupport | ||
|
||
|
||
|
||
|
||
extension String { | ||
|
||
func uppercaseFirstLetter() -> String { | ||
let paranthesisCount = components(separatedBy: "]").count - 1 | ||
let stringWithoutParanthesis = dropFirst(paranthesisCount) | ||
|
||
return String(repeating: "[", count: paranthesisCount) + stringWithoutParanthesis.capitalized | ||
} | ||
|
||
func lowercaseFirstLetter() -> String { | ||
return prefix(1).lowercased() + dropFirst() | ||
} | ||
|
||
var camelCasedString: String { | ||
return components(separatedBy: CharacterSet(charactersIn: "_ ")).map{ $0.lowercased().uppercaseFirstLetter() }.joined() | ||
} | ||
|
||
var singular: String { | ||
let paranthesisCount = components(separatedBy: "]").count - 1 | ||
let stringWithoutParanthesis = dropLast(paranthesisCount) | ||
|
||
if stringWithoutParanthesis.last == "s" { | ||
return stringWithoutParanthesis.dropLast() + String(repeating: "]", count: paranthesisCount) | ||
} | ||
|
||
return self | ||
} | ||
} | ||
|
||
|
||
|
||
|
||
class Parser<T> { | ||
|
||
func canParse(_ value: Any) -> Bool { | ||
return value is T | ||
} | ||
|
||
func getPropertyType() -> String { | ||
return "\(T.self)" | ||
} | ||
} | ||
|
||
extension Parser where T == [String: Any] { | ||
|
||
func parse(_ value: Any) -> T { | ||
return value as! T | ||
} | ||
|
||
func getPropertyType(name: String) -> String { | ||
return "\(name)" | ||
} | ||
} | ||
|
||
extension Parser where T == [Any] { | ||
|
||
func parse(_ value: Any) -> T { | ||
return value as! T | ||
} | ||
} | ||
|
||
|
||
|
||
class CodableClass: CustomStringConvertible { | ||
|
||
var className: String | ||
var properties: [(String, String)] = [] | ||
|
||
init(className: String) { | ||
self.className = className | ||
} | ||
|
||
func addProperty(name: String, type: String) { | ||
properties.append((name, type)) | ||
} | ||
|
||
var description: String { | ||
var str = "class \(className.camelCasedString.singular): Codable {\n\n" | ||
str += properties.map{ "\tvar \($0.0.camelCasedString.lowercaseFirstLetter()): \($0.1.camelCasedString.singular)!" }.joined(separator: "\n") | ||
str += "\n\n\tenum CodingKeys: String, CodingKey {\n" | ||
str += properties.map{"\t\tcase \($0.0.camelCasedString.lowercaseFirstLetter()) = \"\($0.0)\""}.joined(separator: "\n") | ||
str += "\n\t}" | ||
str += "\n}\n\n" | ||
return str | ||
} | ||
} | ||
|
||
|
||
|
||
class Json2Codable { | ||
|
||
private let intParser = Parser<Int>() | ||
private let stringParser = Parser<String>() | ||
private let doubleParser = Parser<Double>() | ||
private let dictionaryParser = Parser<[String: Any]>() | ||
private let arrayParser = Parser<[Any]>() | ||
|
||
private var codableClasses: [CodableClass] = [] | ||
|
||
func convertToCodable(name: String, from dictionary: [String: Any]) -> CodableClass { | ||
let codableClass = getCodableClass(name: name) | ||
|
||
dictionary.keys.forEach { key in | ||
codableClass.addProperty( | ||
name: key, | ||
type: convertToProperty(key: key, value: dictionary[key]!) | ||
) | ||
} | ||
|
||
return codableClass | ||
} | ||
|
||
private func convertToProperty(key: String, value: Any) -> String { | ||
if intParser.canParse(value) { | ||
return intParser.getPropertyType() | ||
} else if doubleParser.canParse(value) { | ||
return doubleParser.getPropertyType() | ||
} else if stringParser.canParse(value) { | ||
return stringParser.getPropertyType() | ||
} else if dictionaryParser.canParse(value) { | ||
convertToCodable(name: key, from: dictionaryParser.parse(value)) | ||
return dictionaryParser.getPropertyType(name: key) | ||
} else if arrayParser.canParse(value) { | ||
return "[\(convertToProperty(key: key, value: arrayParser.parse(value).first!))]" | ||
} | ||
|
||
return "" | ||
} | ||
|
||
private func getCodableClass(name: String) -> CodableClass { | ||
var codableClass: CodableClass | ||
|
||
if let foundClass = codableClasses.first(where: { $0.className == name }) { | ||
codableClass = foundClass | ||
} else { | ||
codableClass = CodableClass(className: name) | ||
codableClasses.append(codableClass) | ||
} | ||
|
||
return codableClass | ||
} | ||
|
||
func getResourceName(from url: String?) -> String { | ||
guard let url = url else { | ||
return "ClassName" | ||
} | ||
|
||
var components = url.split(separator: "/") | ||
if let _ = Int(components.last ?? "") { | ||
components = Array(components.dropLast()) | ||
} | ||
|
||
return String(components.last ?? "").singular | ||
} | ||
|
||
func printClasses() { | ||
codableClasses.forEach{ print($0) } | ||
} | ||
} | ||
|
||
|
||
|
||
|
||
do { | ||
let str = "{\n \"greeting\": \"Welcome to quicktype!\",\n \"some_url\": \"https://facebook.com\",\n \"instructions\": {\n \"tests\": [\n [\n {\"name\": \"Type or paste JSON here\"},\n {\"name\": \"Or choose a sample above\"},\n {\"name\": \"quicktype will generate code in your\"},\n {\"name\": \"chosen language to parse the sample data\"}\n ]\n ]\n }\n}" | ||
let data = str.data(using: .utf8)! | ||
let dictionary = try JSONSerialization.jsonObject(with: data) as! [String: Any] | ||
let converter = Json2Codable() | ||
print(converter.getResourceName(from: "https://jsonplaceholder.typicode.com/posts/1/comments")) | ||
// converter.convertToCodable(name: "welcome", from: dictionary) | ||
// converter.printClasses() | ||
} catch { | ||
|
||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> | ||
<playground version='5.0' target-platform='ios'> | ||
<timeline fileName='timeline.xctimeline'/> | ||
</playground> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,9 @@ Feel free to contribute :) | |
| ![](https://raw.githubusercontent.com/kasketis/netfox/master/assets/overview1_5_3.gif) | ![](https://cloud.githubusercontent.com/assets/1402212/12893260/78f90916-ce90-11e5-830a-d1a1b91b2ac4.png) | | ||
|---|---| | ||
|
||
### netfox_mac app working in parallel with iOS app | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure this should be at the top of the README. It's really cool, but I think the primary functionality of Netfox should be showcased first. |
||
![](https://d2ffutrenqvap3.cloudfront.net/items/2S0C1j2e3D3A3H2P020E/Screen%20Recording%202018-02-23%20at%2001.45%20PM.gif) | ||
|
||
## Installation | ||
|
||
### CocoaPods | ||
|
@@ -99,6 +102,18 @@ to prevent library’s execution on your production app. | |
|
||
You can add the DEBUG symbol with the -DDEBUG entry. Set it in the "Swift Compiler - Custom Flags" section -> "Other Swift Flags" line in project’s "Build Settings" | ||
|
||
If you want to use netfox with the netfox_mac application, you should start netfox in the following way: | ||
|
||
#### Swift | ||
<pre> | ||
NFX.sharedInstance().startServer() | ||
</pre> | ||
|
||
#### Obj-C | ||
<pre> | ||
[[NFX sharedInstance] startServer]; | ||
</pre> | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same |
||
## Usage | ||
|
||
Just shake your device and check what's going right or wrong! | ||
|
@@ -154,6 +169,9 @@ Tip: You can use the url of the host (for example "https://www.github.com") to i | |
- Clear data within the app | ||
- Statistics: Check cool things like average response time, total response size and more for your selected types of responses | ||
- Info: Check your IP address, your app version and build number and other things within the app | ||
- Live updates between apps running netfox with NFX.sharedInstance.startServer() and netfox_mac application | ||
- Directory-like structure of requests | ||
- Conversion from JSON to Codable class | ||
- More to come.. ;) | ||
|
||
## Other | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,4 +19,7 @@ DESC | |
s.source_files = "netfox/Core/*.{swift,h,m}" | ||
s.ios.source_files = "netfox/iOS/*.swift" | ||
s.osx.source_files = "netfox/OSX/*.{swift,xib}" | ||
|
||
# s.dependency "Swifter" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we don't depend on Swifter, we can probably remove this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed. |
||
|
||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lol did you mean to include your playground?