Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into safeAreaObserving…
Browse files Browse the repository at this point in the history
…Branch
  • Loading branch information
iphone201988 committed Dec 12, 2022
2 parents f191068 + d4f250f commit 73dc554
Show file tree
Hide file tree
Showing 10 changed files with 296 additions and 12 deletions.
24 changes: 20 additions & 4 deletions ec3730.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
2E07168128FEC3F3009C3844 /* WhoisXmlContactsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E07168028FEC3F3009C3844 /* WhoisXmlContactsService.swift */; };
846CDA85291CF6A800DDB5AA /* ApiKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846CDA84291CF6A800DDB5AA /* ApiKeys.swift */; };
84A16C1D290A9FC800A7EBF4 /* Runestone in Frameworks */ = {isa = PBXBuildFile; productRef = 84A16C1C290A9FC800A7EBF4 /* Runestone */; };
84CECCCF29151BD300FB0F0D /* WhoIsXmlCategorizationSectionModel.json in Resources */ = {isa = PBXBuildFile; fileRef = 84CECCCE29151BD300FB0F0D /* WhoIsXmlCategorizationSectionModel.json */; };
84CECCD129151C0400FB0F0D /* WhoIsXmlCategorizationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CECCD029151C0400FB0F0D /* WhoIsXmlCategorizationResult.swift */; };
84CECCD329151C1D00FB0F0D /* WhoIsXmlCategorizationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CECCD229151C1D00FB0F0D /* WhoIsXmlCategorizationService.swift */; };
84CECCD5291521E500FB0F0D /* WhoIsXmlCategorizationSectionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CECCD4291521E500FB0F0D /* WhoIsXmlCategorizationSectionModel.swift */; };
AA1595D328B24AC2003819A1 /* DataUsageInfoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA1595D228B24AC2003819A1 /* DataUsageInfoModel.swift */; };
AA1595D528B24D2A003819A1 /* DataUsageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA1595D428B24D2A003819A1 /* DataUsageModel.swift */; };
AA8FBAB9283AA6A000280377 /* HostViewSectionContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA8FBAB8283AA6A000280377 /* HostViewSectionContent.swift */; };
Expand Down Expand Up @@ -213,6 +217,10 @@
2E07167E28FEB837009C3844 /* WhoIsXmlContactsSectionModel.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = WhoIsXmlContactsSectionModel.json; sourceTree = "<group>"; };
2E07168028FEC3F3009C3844 /* WhoisXmlContactsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WhoisXmlContactsService.swift; sourceTree = "<group>"; };
846CDA84291CF6A800DDB5AA /* ApiKeys.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApiKeys.swift; sourceTree = "<group>"; };
84CECCCE29151BD300FB0F0D /* WhoIsXmlCategorizationSectionModel.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = WhoIsXmlCategorizationSectionModel.json; sourceTree = "<group>"; };
84CECCD029151C0400FB0F0D /* WhoIsXmlCategorizationResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WhoIsXmlCategorizationResult.swift; sourceTree = "<group>"; };
84CECCD229151C1D00FB0F0D /* WhoIsXmlCategorizationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WhoIsXmlCategorizationService.swift; sourceTree = "<group>"; };
84CECCD4291521E500FB0F0D /* WhoIsXmlCategorizationSectionModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WhoIsXmlCategorizationSectionModel.swift; sourceTree = "<group>"; };
AA1595D228B24AC2003819A1 /* DataUsageInfoModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataUsageInfoModel.swift; sourceTree = "<group>"; };
AA1595D428B24D2A003819A1 /* DataUsageModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataUsageModel.swift; sourceTree = "<group>"; };
AA8FBAB8283AA6A000280377 /* HostViewSectionContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HostViewSectionContent.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -452,6 +460,7 @@
AAC727BD2843AD2A00482D73 /* GoogleWebRiskSectionModel.json */,
2E07167E28FEB837009C3844 /* WhoIsXmlContactsSectionModel.json */,
AAC727BE2843AD2A00482D73 /* WhoisXmlReputationSectionModel.json */,
84CECCCE29151BD300FB0F0D /* WhoIsXmlCategorizationSectionModel.json */,
AAC727BF2843AD2A00482D73 /* Utility.swift */,
);
path = DemoData;
Expand Down Expand Up @@ -503,6 +512,7 @@
F644A100279283E30061C98B /* WhoisXmlDnsSectionModel.swift */,
F65FDA6427AB03BC0024521B /* WhoisXmlReputationSectionModel.swift */,
2E07167228FEA629009C3844 /* WhoIsXmlContactsSectionModel.swift */,
84CECCD4291521E500FB0F0D /* WhoIsXmlCategorizationSectionModel.swift */,
);
path = Sections;
sourceTree = "<group>";
Expand Down Expand Up @@ -640,6 +650,8 @@
F6FDDFD7230B106200FBF75E /* WhoisXmlDnsCells.swift */,
2E07167428FEB055009C3844 /* WhoIsXmlContactsResult.swift */,
2E07168028FEC3F3009C3844 /* WhoisXmlContactsService.swift */,
84CECCD029151C0400FB0F0D /* WhoIsXmlCategorizationResult.swift */,
84CECCD229151C1D00FB0F0D /* WhoIsXmlCategorizationService.swift */,
);
path = WhoisXML;
sourceTree = "<group>";
Expand Down Expand Up @@ -977,6 +989,7 @@
F6C8D8B1212E5AEA00309373 /* LaunchScreen.storyboard in Resources */,
AAC727C12843AD2A00482D73 /* WhoisXmlWhoisSectionModel.json in Resources */,
AAC727C32843AD2A00482D73 /* GoogleWebRiskSectionModel.json in Resources */,
84CECCCF29151BD300FB0F0D /* WhoIsXmlCategorizationSectionModel.json in Resources */,
2E07167F28FEB837009C3844 /* WhoIsXmlContactsSectionModel.json in Resources */,
AAC727C42843AD2A00482D73 /* WhoisXmlReputationSectionModel.json in Resources */,
F6C8D8AE212E5AEA00309373 /* Assets.xcassets in Resources */,
Expand Down Expand Up @@ -1104,6 +1117,7 @@
F6C87452234FE8030069A57C /* DataFeedsTableViewController.swift in Sources */,
F6FDDFCA23048DEF00FBF75E /* UIView.swift in Sources */,
F6FDDFC623047EE300FBF75E /* DefaultsSwitch.swift in Sources */,
84CECCD329151C1D00FB0F0D /* WhoIsXmlCategorizationService.swift in Sources */,
F660FDD52868E9550027C759 /* DeviceInfoView.swift in Sources */,
F6C591BA235EC3A9009BA4B7 /* CenterTextTableViewCell.swift in Sources */,
F6659F1D287A4CF900038ECA /* SnappedDrawer.swift in Sources */,
Expand Down Expand Up @@ -1134,6 +1148,7 @@
F60506742134B23F00DDF8A4 /* UIViewController.swift in Sources */,
F691B09A2147449200BDE0F4 /* WhoisXml.swift in Sources */,
F6310279213366BB00F34E42 /* SourceViewController.swift in Sources */,
84CECCD129151C0400FB0F0D /* WhoIsXmlCategorizationResult.swift in Sources */,
F668EB4B2356AE3800EEB379 /* IAPFooterView.swift in Sources */,
F668EB3C23501FA200EEB379 /* DataFeedEndpoint.swift in Sources */,
F68CE56023021AC70068D104 /* CopyLabel.swift in Sources */,
Expand Down Expand Up @@ -1167,6 +1182,7 @@
F6E53FCB287024A50041A3DA /* InterfaceConnectionBarView.swift in Sources */,
F63102772130D76200F34E42 /* ReachabilityViewController.swift in Sources */,
F644A0F827925CF60061C98B /* HostModelWrapperView.swift in Sources */,
84CECCD5291521E500FB0F0D /* WhoIsXmlCategorizationSectionModel.swift in Sources */,
F6D4BB0A23583E6100FDAFF7 /* GoogleWebRiskRecord.swift in Sources */,
F69E364C235806720017296E /* WhoisXMLService.swift in Sources */,
F6FBB869236781AC00E023F2 /* UIDevice.swift in Sources */,
Expand Down Expand Up @@ -1357,7 +1373,7 @@
CODE_SIGN_ENTITLEMENTS = ec3730/ec3730.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 14;
CURRENT_PROJECT_VERSION = 15;
DEVELOPMENT_TEAM = C6L3992RFB;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
INFOPLIST_FILE = ec3730/Info.plist;
Expand All @@ -1366,7 +1382,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 2.7.1;
MARKETING_VERSION = 2.8.0;
PRODUCT_BUNDLE_IDENTIFIER = com.twodayslate.ec3730;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand All @@ -1385,7 +1401,7 @@
CODE_SIGN_ENTITLEMENTS = ec3730/ec3730.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 14;
CURRENT_PROJECT_VERSION = 15;
DEVELOPMENT_TEAM = C6L3992RFB;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
INFOPLIST_FILE = ec3730/Info.plist;
Expand All @@ -1394,7 +1410,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 2.7.1;
MARKETING_VERSION = 2.8.0;
PRODUCT_BUNDLE_IDENTIFIER = com.twodayslate.ec3730;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down
86 changes: 86 additions & 0 deletions ec3730/Data Feeds/WhoisXML/WhoIsXmlCategorizationResult.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import Foundation

// MARK: - ActivityModelClass

struct WhoIsXmlCategorizationResult: Codable {
let categories: [CategoryResult]?
let domainName: String?
let websiteResponded: Bool?
}

extension WhoIsXmlCategorizationResult {
init(data: Data) throws {
self = try newJSONDecoder().decode(WhoIsXmlCategorizationResult.self, from: data)
}

init(_ json: String, using encoding: String.Encoding = .utf8) throws {
guard let data = json.data(using: encoding) else {
throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil)
}
try self.init(data: data)
}

init(fromURL url: URL) throws {
try self.init(data: try Data(contentsOf: url))
}

func with(categories: [CategoryResult]? = nil,
domainName: String? = nil,
websiteResponded: Bool? = nil) -> WhoIsXmlCategorizationResult {
WhoIsXmlCategorizationResult(categories: categories ?? self.categories,
domainName: domainName ?? self.domainName,
websiteResponded: websiteResponded ?? self.websiteResponded)
}

func jsonData() throws -> Data {
try newJSONEncoder().encode(self)
}

func jsonString(encoding: String.Encoding = .utf8) throws -> String? {
String(data: try jsonData(), encoding: encoding)
}
}

// MARK: - CategoryResult

struct CategoryResult: Codable {
let tier1: Tier?
let tier2: Tier?
}

extension CategoryResult {
init(data: Data) throws {
self = try newJSONDecoder().decode(CategoryResult.self, from: data)
}

init(_ json: String, using encoding: String.Encoding = .utf8) throws {
guard let data = json.data(using: encoding) else {
throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil)
}
try self.init(data: data)
}

init(fromURL url: URL) throws {
try self.init(data: try Data(contentsOf: url))
}

func with(tier1: Tier? = nil,
tier2: Tier? = nil) -> CategoryResult {
CategoryResult(tier1: tier1 ?? self.tier1, tier2: tier2 ?? self.tier2)
}

func jsonData() throws -> Data {
try newJSONEncoder().encode(self)
}

func jsonString(encoding: String.Encoding = .utf8) throws -> String? {
String(data: try jsonData(), encoding: encoding)
}
}

// MARK: - Tier

struct Tier: Codable {
let confidence: Double?
let id, name: String?
}
29 changes: 29 additions & 0 deletions ec3730/Data Feeds/WhoisXML/WhoIsXmlCategorizationService.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// WhoIsXmlCategorizationService.swift
// ec3730
//
// Created by admin on 04/11/22.
// Copyright © 2022 Zachary Gorak. All rights reserved.
//

import Foundation
import UIKit

class WhoIsXmlCategorizationService: WhoisXMLService {
override func endpoint(_ userData: [String: Any?]?) -> DataFeedEndpoint? {
guard let userData = userData, let userInput = userData["domain"] as? String, let domain = userInput.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) else {
return nil
}

var params = [URLQueryItem(name: "domainName", value: domain),
URLQueryItem(name: "outputFormat", value: "JSON"),
URLQueryItem(name: "type", value: "_all"),
URLQueryItem(name: "api", value: "whoisXmlWebsiteCategorization"),
URLQueryItem(name: "identifierForVendor", value: UIDevice.current.identifierForVendor?.uuidString),
URLQueryItem(name: "bundleIdentifier", value: Bundle.main.bundleIdentifier)]
if let key = WhoisXml.current.userKey {
params.append(URLQueryItem(name: "apiKey", value: key))
}
return WhoisXml.Endpoint(host: "api.netutils.workers.dev", path: "/api/v2", queryItems: params)
}
}
7 changes: 6 additions & 1 deletion ec3730/Data Feeds/WhoisXML/WhoisXml.swift
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,14 @@ extension WhoisXml: DataFeedService {
description: "Our hosted domain contact information lookup includes company name, direct-dial phone numbers, email addresses, and social media links.",
id: "29"
)
static var CategorizationService: WhoisXMLService = WhoIsXmlCategorizationService(
name: "Website Categorization",
description: "Our hosted lookup uses a machine learning (ML) engine to scan a website’s content and meta tags to classify the site.",
id: "21"
)

var services: [Service] {
[WhoisXml.whoisService, WhoisXml.dnsService, WhoisXml.reputationService, WhoisXml.contactsService]
[WhoisXml.whoisService, WhoisXml.dnsService, WhoisXml.reputationService, WhoisXml.contactsService, WhoisXml.CategorizationService]
}
}

Expand Down
49 changes: 49 additions & 0 deletions ec3730/DemoData/WhoIsXmlCategorizationSectionModel.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"categories": [{
"tier1": {
"confidence": 0.9750956680990432,
"id": "IAB-596",
"name": "Technology & Computing"
},
"tier2": {
"confidence": 0.9242695836674197,
"id": "IAB-619",
"name": "Internet"
}
}, {
"tier1": {
"confidence": 0.9750956680990432,
"id": "IAB-52",
"name": "Business and Finance"
},
"tier2": {
"confidence": 0.9242695836674197,
"id": "IAB-99",
"name": "Information Services Industry"
}
}, {
"tier1": {
"confidence": 0.9750956680990432,
"id": "IAB-52",
"name": "Business and Finance"
},
"tier2": {
"confidence": 0.9242695836674197,
"id": "IAB-115",
"name": "Technology Industry"
}
}, {
"tier1": {
"confidence": 0.9750956680990432,
"id": "IAB-52",
"name": "Business and Finance"
},
"tier2": {
"confidence": 0.9242695836674197,
"id": "IAB-116",
"name": "Telecommunications Industry"
}
}],
"domainName": "google.com",
"websiteResponded": true
}
1 change: 1 addition & 0 deletions ec3730/Models/HostSectionModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class HostSectionModel: ObservableObject, Equatable, Identifiable, Hashable {
WhoisXmlDnsSectionModel(),
WhoisXmlReputationSectionModel(),
WhoIsXmlContactsSectionModel(),
WhoIsXmlCategorizationSectionModel(),
GoogleWebRiskSectionModel(),
]

Expand Down
1 change: 1 addition & 0 deletions ec3730/Models/HostViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class HostViewModel: ObservableObject {
WhoisXmlDnsSectionModel(),
WhoisXmlReputationSectionModel(),
WhoIsXmlContactsSectionModel(),
WhoIsXmlCategorizationSectionModel(),
GoogleWebRiskSectionModel(),
]
all_sections.removeAll(where: { self.hidden.contains($0.service.name) })
Expand Down
85 changes: 85 additions & 0 deletions ec3730/Models/Sections/WhoIsXmlCategorizationSectionModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import Cache
import Foundation

@MainActor
class WhoIsXmlCategorizationSectionModel: HostSectionModel {
required convenience init() {
self.init(WhoisXml.current, service: WhoisXml.CategorizationService, storeModel: StoreKitModel.categorization)
}

@MainActor
override func configure(with data: Data) throws -> Data? {
reset()

let result = try JSONDecoder().decode(WhoIsXmlCategorizationResult.self, from: data)

return try configure(with: result)
}

@MainActor
func configure(with records: WhoIsXmlCategorizationResult) throws -> Data {
reset()

let copyData = try JSONEncoder().encode(records)
latestData = copyData
dataToCopy = String(data: copyData, encoding: .utf8)

if let categories = records.categories {
for (index, category) in categories.enumerated() {
var rows = [CopyCellRow]()
if let tier1 = category.tier1 {
let name = tier1.name ?? ""
let confidence = tier1.confidence ?? 0.0
let id = tier1.id ?? ""

rows.append(CopyCellRow(title: "Tier1", content: "Name - \(name)\n Id - \(id)\n Confidence - \(confidence)"))
}

if let tier2 = category.tier2 {
let name = tier2.name ?? ""
let confidence = tier2.confidence ?? 0.0
let id = tier2.id ?? ""
rows.append(CopyCellRow(title: "Tier2", content: "Name - \(name)\n Id - \(id)\n Confidence - \(confidence)"))
}

if !rows.isEmpty {
content.append(CopyCellView(title: "Category \(index + 1)", rows: rows))
}
}
}

return copyData
}

private let cache = MemoryStorage<String, WhoIsXmlCategorizationResult>(config: .init(expiry: .seconds(15), countLimit: 3, totalCostLimit: 0))

@discardableResult
override func query(url: URL? = nil) async throws -> Data {
reset()

guard let host = url?.host else {
throw URLError(.badURL)
}
latestQueriedUrl = url
latestQueryDate = .now

if let record = try? cache.object(forKey: host) {
return try configure(with: record)
}

guard dataFeed.userKey != nil || storeModel?.owned ?? false else {
throw MoreStoreKitError.NotPurchased
}

let response: WhoIsXmlCategorizationResult = try await WhoisXml.CategorizationService.query(
[
"domain": host,
"minimumBalance": 25,
]
)

cache.setObject(response, forKey: host)

return try configure(with: response)
}
}
Loading

0 comments on commit 73dc554

Please sign in to comment.