UI layouting done
This commit is contained in:
parent
8486978860
commit
4062b0ed9c
@ -8,12 +8,13 @@
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
E2218C9B1EF2D345004298F6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2218C9A1EF2D345004298F6 /* AppDelegate.swift */; };
|
||||
E2218C9D1EF2D345004298F6 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2218C9C1EF2D345004298F6 /* ViewController.swift */; };
|
||||
E2218CA91EF2D37B004298F6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E2218CA81EF2D37B004298F6 /* Assets.xcassets */; };
|
||||
E2218CDE1EF2D461004298F6 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = E2218CDC1EF2D461004298F6 /* MainMenu.xib */; };
|
||||
E2218CDF1EF2D461004298F6 /* SettingsWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = E2218CDD1EF2D461004298F6 /* SettingsWindowController.xib */; };
|
||||
E2218CE31EF2D54A004298F6 /* buildnum.ver in Resources */ = {isa = PBXBuildFile; fileRef = E2218CE11EF2D54A004298F6 /* buildnum.ver */; };
|
||||
E2218CE41EF2D54A004298F6 /* BumpBuildNumber.py in Resources */ = {isa = PBXBuildFile; fileRef = E2218CE21EF2D54A004298F6 /* BumpBuildNumber.py */; };
|
||||
E2218D0D1EF2D68F004298F6 /* XMLDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = E2218D0A1EF2D68F004298F6 /* XMLDictionary.m */; };
|
||||
E2218D111EF2D6F1004298F6 /* SettingsWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2218D101EF2D6F1004298F6 /* SettingsWindowController.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@ -29,13 +30,16 @@
|
||||
/* Begin PBXFileReference section */
|
||||
E2218C981EF2D345004298F6 /* Logger4.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Logger4.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E2218C9A1EF2D345004298F6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
E2218C9C1EF2D345004298F6 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
|
||||
E2218CA31EF2D345004298F6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
E2218CA81EF2D37B004298F6 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
E2218CDC1EF2D461004298F6 /* MainMenu.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MainMenu.xib; sourceTree = "<group>"; };
|
||||
E2218CDD1EF2D461004298F6 /* SettingsWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SettingsWindowController.xib; sourceTree = "<group>"; };
|
||||
E2218CE11EF2D54A004298F6 /* buildnum.ver */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = buildnum.ver; sourceTree = "<group>"; };
|
||||
E2218CE21EF2D54A004298F6 /* BumpBuildNumber.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = BumpBuildNumber.py; sourceTree = "<group>"; };
|
||||
E2218D051EF2D68F004298F6 /* Logger4-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Logger4-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
E2218D081EF2D68F004298F6 /* XMLDictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMLDictionary.h; sourceTree = "<group>"; };
|
||||
E2218D0A1EF2D68F004298F6 /* XMLDictionary.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XMLDictionary.m; sourceTree = "<group>"; };
|
||||
E2218D101EF2D6F1004298F6 /* SettingsWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsWindowController.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@ -69,10 +73,8 @@
|
||||
E2218C991EF2D345004298F6 /* Logger4 */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E2218CEB1EF2D648004298F6 /* Swift */,
|
||||
E2218CDA1EF2D43A004298F6 /* Support Files */,
|
||||
E2218C9A1EF2D345004298F6 /* AppDelegate.swift */,
|
||||
E2218C9C1EF2D345004298F6 /* ViewController.swift */,
|
||||
E2218CA31EF2D345004298F6 /* Info.plist */,
|
||||
);
|
||||
path = Logger4;
|
||||
sourceTree = "<group>";
|
||||
@ -81,6 +83,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E2218CA81EF2D37B004298F6 /* Assets.xcassets */,
|
||||
E2218D041EF2D67B004298F6 /* Obj-C */,
|
||||
);
|
||||
name = "Shared Resources";
|
||||
sourceTree = "<group>";
|
||||
@ -88,8 +91,9 @@
|
||||
E2218CDA1EF2D43A004298F6 /* Support Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E2218CE01EF2D53D004298F6 /* Versioning */,
|
||||
E2218CA31EF2D345004298F6 /* Info.plist */,
|
||||
E2218CDB1EF2D443004298F6 /* UI */,
|
||||
E2218CE01EF2D53D004298F6 /* Versioning */,
|
||||
);
|
||||
name = "Support Files";
|
||||
sourceTree = "<group>";
|
||||
@ -112,12 +116,47 @@
|
||||
name = Versioning;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E2218CEB1EF2D648004298F6 /* Swift */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E2218D121EF2D754004298F6 /* Delegates */,
|
||||
E2218D0F1EF2D6E5004298F6 /* Views */,
|
||||
);
|
||||
name = Swift;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E2218D041EF2D67B004298F6 /* Obj-C */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E2218D081EF2D68F004298F6 /* XMLDictionary.h */,
|
||||
E2218D0A1EF2D68F004298F6 /* XMLDictionary.m */,
|
||||
E2218D051EF2D68F004298F6 /* Logger4-Bridging-Header.h */,
|
||||
);
|
||||
name = "Obj-C";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E2218D0F1EF2D6E5004298F6 /* Views */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E2218D101EF2D6F1004298F6 /* SettingsWindowController.swift */,
|
||||
);
|
||||
name = Views;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E2218D121EF2D754004298F6 /* Delegates */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E2218C9A1EF2D345004298F6 /* AppDelegate.swift */,
|
||||
);
|
||||
name = Delegates;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXLegacyTarget section */
|
||||
E2218CE51EF2D577004298F6 /* Bump Logger4 */ = {
|
||||
isa = PBXLegacyTarget;
|
||||
buildArgumentsString = "$PROJECT_DIR/Logger4/BumpBuildNumber.py $PROJECT_DIR/Logger4/buildnum.ver $PROJECT_DIR/Logger3/Info.plist";
|
||||
buildArgumentsString = "$PROJECT_DIR/Logger4/BumpBuildNumber.py $PROJECT_DIR/Logger4/buildnum.ver $PROJECT_DIR/Logger4/Info.plist";
|
||||
buildConfigurationList = E2218CE61EF2D577004298F6 /* Build configuration list for PBXLegacyTarget "Bump Logger4" */;
|
||||
buildPhases = (
|
||||
);
|
||||
@ -163,6 +202,7 @@
|
||||
E2218C971EF2D345004298F6 = {
|
||||
CreatedOnToolsVersion = 8.3.3;
|
||||
DevelopmentTeam = 795KPDV76S;
|
||||
LastSwiftMigration = 0830;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
E2218CE51EF2D577004298F6 = {
|
||||
@ -211,7 +251,8 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E2218C9D1EF2D345004298F6 /* ViewController.swift in Sources */,
|
||||
E2218D0D1EF2D68F004298F6 /* XMLDictionary.m in Sources */,
|
||||
E2218D111EF2D6F1004298F6 /* SettingsWindowController.swift in Sources */,
|
||||
E2218C9B1EF2D345004298F6 /* AppDelegate.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@ -323,6 +364,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-L4";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "Mac Developer";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DEVELOPMENT_TEAM = 795KPDV76S;
|
||||
@ -331,6 +373,8 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.weebly.alikja.Logger4;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Logger4-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 3.0;
|
||||
};
|
||||
name = Debug;
|
||||
@ -339,6 +383,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-L4";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "Mac Developer";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DEVELOPMENT_TEAM = 795KPDV76S;
|
||||
@ -347,6 +392,7 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.weebly.alikja.Logger4;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Logger4-Bridging-Header.h";
|
||||
SWIFT_VERSION = 3.0;
|
||||
};
|
||||
name = Release;
|
||||
|
||||
6
Logger4-Bridging-Header.h
Normal file
6
Logger4-Bridging-Header.h
Normal file
@ -0,0 +1,6 @@
|
||||
//
|
||||
// Use this file to import your target's public headers that you would like to
|
||||
// expose to Swift.
|
||||
//
|
||||
|
||||
#import "XMLDictionary.h"
|
||||
@ -11,16 +11,110 @@ import Cocoa
|
||||
@NSApplicationMain
|
||||
class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
|
||||
// MARK: - Things that have to be kept alive for the application lifetime
|
||||
// Status Item
|
||||
var statusItem: NSStatusItem = NSStatusItem()
|
||||
// URL Session for DOCSIS data and Internet check
|
||||
let urlSession: URLSession = URLSession(configuration: .default)
|
||||
// Preferences
|
||||
let pref: NSWindowController = NSWindowController(windowNibName: "SettingsWindowController")
|
||||
// Timers
|
||||
var timerFreqs: Timer = Timer()
|
||||
var timerFails: Timer = Timer()
|
||||
// Document content list
|
||||
var content: NSMutableDictionary = NSMutableDictionary()
|
||||
|
||||
|
||||
// MARK: - Application Lifecycle
|
||||
|
||||
func applicationDidFinishLaunching(_ aNotification: Notification) {
|
||||
// Insert code here to initialize your application
|
||||
// Show Preferneces if defaults are empty
|
||||
UserDefaults.standard.register(defaults: ["upstream" : "", "downstream" : ""])
|
||||
if UserDefaults.standard.string(forKey: "upstream") == nil || UserDefaults.standard.string(forKey: "downstream") == nil {
|
||||
pref.showWindow(nil)
|
||||
}
|
||||
|
||||
// Set status item
|
||||
statusItem = NSStatusBar.system().statusItem(withLength: -2)
|
||||
statusItem.title = "AL"
|
||||
// Create status item menu
|
||||
let menu: NSMenu = NSMenu.init()
|
||||
menu.autoenablesItems = false
|
||||
let menuAbout: NSMenuItem = NSMenuItem(title: "About Logger", action: #selector(NSApp.orderFrontStandardAboutPanel(_:)), keyEquivalent: "")
|
||||
let menuQuit: NSMenuItem = NSMenuItem.init(title: "Quit", action: #selector(NSApp.terminate(_:)), keyEquivalent: "q")
|
||||
let menuPref: NSMenuItem = NSMenuItem(title: "Preferences", action: #selector(self.preferences(_:)), keyEquivalent: "")
|
||||
menuPref.image = NSImage(named: NSImageNameActionTemplate)
|
||||
// Layout menu
|
||||
menu.addItem(menuAbout)
|
||||
menu.addItem(NSMenuItem.separator())
|
||||
menu.addItem(menuPref)
|
||||
menu.addItem(NSMenuItem.separator())
|
||||
menu.addItem(menuQuit)
|
||||
// Add menu
|
||||
statusItem.menu = menu
|
||||
|
||||
// Check if directory exists, creat or exit
|
||||
let fileManager = FileManager.default
|
||||
var directory: ObjCBool = ObjCBool(false)
|
||||
let exists: Bool = fileManager.fileExists(atPath: ("~/KDLog" as NSString).expandingTildeInPath, isDirectory: &directory)
|
||||
if exists && directory.boolValue {
|
||||
} else if exists {
|
||||
NSLog("FILE WITH NAME KDLog EXISTS, REMOVE IT")
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
do {
|
||||
try fileManager.createDirectory(atPath: ("~/KDLog" as NSString).expandingTildeInPath, withIntermediateDirectories: false, attributes: nil)
|
||||
}
|
||||
catch let error as NSError {
|
||||
NSLog("ERROR ON DIRECTORY CREATION: \(error.localizedDescription)")
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Init timers
|
||||
if UserDefaults.standard.string(forKey: "upstream") != nil || UserDefaults.standard.string(forKey: "downstream") != nil {
|
||||
initTimers()
|
||||
}
|
||||
}
|
||||
|
||||
func applicationWillTerminate(_ aNotification: Notification) {
|
||||
// Insert code here to tear down your application
|
||||
func applicationShouldTerminate(_ sender: NSApplication) -> NSApplicationTerminateReply {
|
||||
urlSession.invalidateAndCancel()
|
||||
return .terminateNow
|
||||
}
|
||||
|
||||
// MARK: - Logging Functions
|
||||
|
||||
func logFreqs(_: Timer) {
|
||||
// let frequencyOperation: FrequencyOperation = FrequencyOperation()
|
||||
// OperationQueue.main.addOperation(frequencyOperation)
|
||||
}
|
||||
|
||||
func logFails(_: Timer) {
|
||||
// let connectionLossOperation: ConnectionLossOperation = ConnectionLossOperation()
|
||||
// OperationQueue.main.addOperation(connectionLossOperation)
|
||||
}
|
||||
|
||||
// MARK: - General functions
|
||||
|
||||
func preferences(_ sender: NSMenuItem) {
|
||||
timerFreqs.invalidate()
|
||||
timerFails.invalidate()
|
||||
|
||||
pref.showWindow(sender)
|
||||
pref.window?.makeKeyAndOrderFront(self)
|
||||
}
|
||||
|
||||
func initTimers() {
|
||||
timerFreqs.invalidate()
|
||||
timerFails.invalidate()
|
||||
|
||||
timerFreqs = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(logFreqs), userInfo: nil, repeats: true)
|
||||
timerFails = Timer.scheduledTimer(timeInterval: 60, target: self, selector: #selector(logFails), userInfo: nil, repeats: true)
|
||||
}
|
||||
|
||||
@IBAction func close(_ sender: NSButton){
|
||||
initTimers()
|
||||
sender.superview?.window?.close()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -15,9 +15,9 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<string>4.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<string>6</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<key>LSUIElement</key>
|
||||
|
||||
19
Logger4/SettingsWindowController.swift
Normal file
19
Logger4/SettingsWindowController.swift
Normal file
@ -0,0 +1,19 @@
|
||||
//
|
||||
// SettingsWindowController.swift
|
||||
// Logger3
|
||||
//
|
||||
// Created by Kilian Hofmann on 15.08.16.
|
||||
// Copyright © 2016 Kilian Hofmann. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
|
||||
class SettingsWindowController: NSWindowController {
|
||||
|
||||
override func windowDidLoad() {
|
||||
super.windowDidLoad()
|
||||
|
||||
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,11 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11185.3" systemVersion="16A286a" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="12121" systemVersion="16G16b" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11185.3"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="12121"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="SettingsWindowController" customModule="Logger3" customModuleProvider="target">
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="SettingsWindowController" customModule="Logger4" customModuleProvider="target">
|
||||
<connections>
|
||||
<outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
|
||||
</connections>
|
||||
@ -15,14 +16,14 @@
|
||||
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" animationBehavior="default" id="F0z-JX-Cv5">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="196" y="240" width="480" height="148"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1280" height="777"/>
|
||||
<rect key="contentRect" x="196" y="240" width="480" height="123"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1280" height="800"/>
|
||||
<view key="contentView" wantsLayer="YES" id="se5-gp-TjO">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="148"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="123"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ANt-3h-Oyk">
|
||||
<rect key="frame" x="157" y="106" width="303" height="22"/>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ANt-3h-Oyk">
|
||||
<rect key="frame" x="157" y="81" width="303" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="ZEi-Jt-cuo">
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -33,8 +34,8 @@
|
||||
<binding destination="aHP-ZZ-xCK" name="value" keyPath="values.upstream" id="fxN-Gy-Szs"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Ycn-ts-JLP">
|
||||
<rect key="frame" x="18" y="106" width="116" height="17"/>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ycn-ts-JLP">
|
||||
<rect key="frame" x="18" y="81" width="116" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Modem Upstream:" id="lAx-c4-sWO">
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -42,8 +43,8 @@
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="d4L-qo-4wS">
|
||||
<rect key="frame" x="18" y="74" width="133" height="17"/>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="NO" translatesAutoresizingMaskIntoConstraints="NO" id="d4L-qo-4wS">
|
||||
<rect key="frame" x="18" y="49" width="133" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Modem Downstream:" id="oeh-xU-Gg6">
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -51,8 +52,8 @@
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9gP-wv-Svk">
|
||||
<rect key="frame" x="157" y="74" width="303" height="22"/>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9gP-wv-Svk">
|
||||
<rect key="frame" x="157" y="49" width="303" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="rGM-TE-sjl">
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -63,40 +64,8 @@
|
||||
<binding destination="aHP-ZZ-xCK" name="value" keyPath="values.downstream" id="9uX-kn-Xc2"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="QL3-SH-xov">
|
||||
<rect key="frame" x="18" y="42" width="34" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Port:" id="olU-sy-AtO">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="x6I-cX-Bo8">
|
||||
<rect key="frame" x="157" y="42" width="49" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="crU-qU-FJL">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<binding destination="aHP-ZZ-xCK" name="value" keyPath="values.port" id="RKt-4G-WHW"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9I9-2a-L2r">
|
||||
<rect key="frame" x="18" y="18" width="122" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Autostart Server" bezelStyle="regularSquare" imagePosition="left" inset="2" id="r84-bO-IHn">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<binding destination="aHP-ZZ-xCK" name="value" keyPath="values.autostart" id="bbv-6s-vsL"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="vGB-sa-cDA">
|
||||
<rect key="frame" x="397" y="13" width="57" height="32"/>
|
||||
<rect key="frame" x="409" y="13" width="57" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Ok" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="cDR-9m-MtM">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
@ -106,23 +75,14 @@
|
||||
<action selector="close:" target="Lb6-Mc-rfv" id="Asm-ec-kwu"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="YLU-XV-sDy">
|
||||
<rect key="frame" x="214" y="42" width="144" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Requires Server restart" id="EYY-im-3b0">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="139" y="100"/>
|
||||
<point key="canvasLocation" x="139" y="87.5"/>
|
||||
</window>
|
||||
<customObject id="Lb6-Mc-rfv" customClass="AppDelegate" customModule="Logger3" customModuleProvider="target"/>
|
||||
<customObject id="Lb6-Mc-rfv" customClass="AppDelegate" customModule="Logger4" customModuleProvider="target"/>
|
||||
<userDefaultsController representsSharedInstance="YES" id="aHP-ZZ-xCK"/>
|
||||
</objects>
|
||||
</document>
|
||||
|
||||
@ -1,27 +0,0 @@
|
||||
//
|
||||
// ViewController.swift
|
||||
// Logger4
|
||||
//
|
||||
// Created by Kilian Hofmann on 15.06.17.
|
||||
// Copyright © 2017 Kilian Hofmann. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
|
||||
class ViewController: NSViewController {
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
// Do any additional setup after loading the view.
|
||||
}
|
||||
|
||||
override var representedObject: Any? {
|
||||
didSet {
|
||||
// Update the view, if already loaded.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
version 4.0
|
||||
build 1
|
||||
build 6
|
||||
|
||||
103
XMLDictionary.h
Executable file
103
XMLDictionary.h
Executable file
@ -0,0 +1,103 @@
|
||||
//
|
||||
// XMLDictionary.h
|
||||
//
|
||||
// Version 1.4
|
||||
//
|
||||
// Created by Nick Lockwood on 15/11/2010.
|
||||
// Copyright 2010 Charcoal Design. All rights reserved.
|
||||
//
|
||||
// Get the latest version of XMLDictionary from here:
|
||||
//
|
||||
// https://github.com/nicklockwood/XMLDictionary
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wobjc-missing-property-synthesis"
|
||||
|
||||
typedef NS_ENUM(NSInteger, XMLDictionaryAttributesMode) {
|
||||
XMLDictionaryAttributesModePrefixed = 0, // default
|
||||
XMLDictionaryAttributesModeDictionary,
|
||||
XMLDictionaryAttributesModeUnprefixed,
|
||||
XMLDictionaryAttributesModeDiscard
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSInteger, XMLDictionaryNodeNameMode) {
|
||||
XMLDictionaryNodeNameModeRootOnly = 0, // default
|
||||
XMLDictionaryNodeNameModeAlways,
|
||||
XMLDictionaryNodeNameModeNever
|
||||
};
|
||||
|
||||
static NSString *const XMLDictionaryAttributesKey = @"__attributes";
|
||||
static NSString *const XMLDictionaryCommentsKey = @"__comments";
|
||||
static NSString *const XMLDictionaryTextKey = @"__text";
|
||||
static NSString *const XMLDictionaryNodeNameKey = @"__name";
|
||||
static NSString *const XMLDictionaryAttributePrefix = @"_";
|
||||
|
||||
@interface XMLDictionaryParser : NSObject <NSCopying>
|
||||
|
||||
+ (XMLDictionaryParser *)sharedInstance;
|
||||
|
||||
@property(nonatomic, assign) BOOL collapseTextNodes; // defaults to YES
|
||||
@property(nonatomic, assign) BOOL stripEmptyNodes; // defaults to YES
|
||||
@property(nonatomic, assign) BOOL trimWhiteSpace; // defaults to YES
|
||||
@property(nonatomic, assign) BOOL alwaysUseArrays; // defaults to NO
|
||||
@property(nonatomic, assign) BOOL preserveComments; // defaults to NO
|
||||
@property(nonatomic, assign) BOOL wrapRootNode; // defaults to NO
|
||||
|
||||
@property(nonatomic, assign) XMLDictionaryAttributesMode attributesMode;
|
||||
@property(nonatomic, assign) XMLDictionaryNodeNameMode nodeNameMode;
|
||||
|
||||
- (NSDictionary *)dictionaryWithParser:(NSXMLParser *)parser;
|
||||
- (NSDictionary *)dictionaryWithData:(NSData *)data;
|
||||
- (NSDictionary *)dictionaryWithString:(NSString *)string;
|
||||
- (NSDictionary *)dictionaryWithFile:(NSString *)path;
|
||||
|
||||
@end
|
||||
|
||||
@interface NSDictionary (XMLDictionary)
|
||||
|
||||
+ (NSDictionary *)dictionaryWithXMLParser:(NSXMLParser *)parser;
|
||||
+ (NSDictionary *)dictionaryWithXMLData:(NSData *)data;
|
||||
+ (NSDictionary *)dictionaryWithXMLString:(NSString *)string;
|
||||
+ (NSDictionary *)dictionaryWithXMLFile:(NSString *)path;
|
||||
|
||||
- (NSDictionary *)attributes;
|
||||
- (NSDictionary *)childNodes;
|
||||
- (NSArray *)comments;
|
||||
- (NSString *)nodeName;
|
||||
- (NSString *)innerText;
|
||||
- (NSString *)innerXML;
|
||||
- (NSString *)XMLString;
|
||||
|
||||
- (NSArray *)arrayValueForKeyPath:(NSString *)keyPath;
|
||||
- (NSString *)stringValueForKeyPath:(NSString *)keyPath;
|
||||
- (NSDictionary *)dictionaryValueForKeyPath:(NSString *)keyPath;
|
||||
|
||||
@end
|
||||
|
||||
@interface NSString (XMLDictionary)
|
||||
|
||||
- (NSString *)XMLEncodedString;
|
||||
|
||||
@end
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
485
XMLDictionary.m
Executable file
485
XMLDictionary.m
Executable file
@ -0,0 +1,485 @@
|
||||
//
|
||||
// XMLDictionary.m
|
||||
//
|
||||
// Version 1.4
|
||||
//
|
||||
// Created by Nick Lockwood on 15/11/2010.
|
||||
// Copyright 2010 Charcoal Design. All rights reserved.
|
||||
//
|
||||
// Get the latest version of XMLDictionary from here:
|
||||
//
|
||||
// https://github.com/nicklockwood/XMLDictionary
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#import "XMLDictionary.h"
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wobjc-missing-property-synthesis"
|
||||
#pragma GCC diagnostic ignored "-Wdirect-ivar-access"
|
||||
#pragma GCC diagnostic ignored "-Wformat-non-iso"
|
||||
#pragma GCC diagnostic ignored "-Wgnu"
|
||||
|
||||
#import <Availability.h>
|
||||
#if !__has_feature(objc_arc)
|
||||
#error This class requires automatic reference counting
|
||||
#endif
|
||||
|
||||
@interface XMLDictionaryParser () <NSXMLParserDelegate>
|
||||
|
||||
@property(nonatomic, strong) NSMutableDictionary *root;
|
||||
@property(nonatomic, strong) NSMutableArray *stack;
|
||||
@property(nonatomic, strong) NSMutableString *text;
|
||||
|
||||
@end
|
||||
|
||||
@implementation XMLDictionaryParser
|
||||
|
||||
+ (XMLDictionaryParser *)sharedInstance {
|
||||
static dispatch_once_t once;
|
||||
static XMLDictionaryParser *sharedInstance;
|
||||
dispatch_once(&once, ^{
|
||||
|
||||
sharedInstance = [[XMLDictionaryParser alloc] init];
|
||||
});
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
- (id)init {
|
||||
if ((self = [super init])) {
|
||||
_collapseTextNodes = YES;
|
||||
_stripEmptyNodes = YES;
|
||||
_trimWhiteSpace = YES;
|
||||
_alwaysUseArrays = NO;
|
||||
_preserveComments = NO;
|
||||
_wrapRootNode = NO;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone {
|
||||
XMLDictionaryParser *copy = [[[self class] allocWithZone:zone] init];
|
||||
copy.collapseTextNodes = _collapseTextNodes;
|
||||
copy.stripEmptyNodes = _stripEmptyNodes;
|
||||
copy.trimWhiteSpace = _trimWhiteSpace;
|
||||
copy.alwaysUseArrays = _alwaysUseArrays;
|
||||
copy.preserveComments = _preserveComments;
|
||||
copy.attributesMode = _attributesMode;
|
||||
copy.nodeNameMode = _nodeNameMode;
|
||||
copy.wrapRootNode = _wrapRootNode;
|
||||
return copy;
|
||||
}
|
||||
|
||||
- (NSDictionary *)dictionaryWithParser:(NSXMLParser *)parser {
|
||||
[parser setDelegate:self];
|
||||
[parser parse];
|
||||
id result = _root;
|
||||
_root = nil;
|
||||
_stack = nil;
|
||||
_text = nil;
|
||||
return result;
|
||||
}
|
||||
|
||||
- (NSDictionary *)dictionaryWithData:(NSData *)data {
|
||||
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
|
||||
return [self dictionaryWithParser:parser];
|
||||
}
|
||||
|
||||
- (NSDictionary *)dictionaryWithString:(NSString *)string {
|
||||
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
|
||||
return [self dictionaryWithData:data];
|
||||
}
|
||||
|
||||
- (NSDictionary *)dictionaryWithFile:(NSString *)path {
|
||||
NSData *data = [NSData dataWithContentsOfFile:path];
|
||||
return [self dictionaryWithData:data];
|
||||
}
|
||||
|
||||
+ (NSString *)XMLStringForNode:(id)node withNodeName:(NSString *)nodeName {
|
||||
if ([node isKindOfClass:[NSArray class]]) {
|
||||
NSMutableArray *nodes = [NSMutableArray arrayWithCapacity:[node count]];
|
||||
for (id individualNode in node) {
|
||||
[nodes addObject:[self XMLStringForNode:individualNode
|
||||
withNodeName:nodeName]];
|
||||
}
|
||||
return [nodes componentsJoinedByString:@"\n"];
|
||||
} else if ([node isKindOfClass:[NSDictionary class]]) {
|
||||
NSDictionary *attributes = [(NSDictionary *)node attributes];
|
||||
NSMutableString *attributeString = [NSMutableString string];
|
||||
for (NSString *key in [attributes allKeys]) {
|
||||
[attributeString
|
||||
appendFormat:@" %@=\"%@\"",
|
||||
[[key description] XMLEncodedString],
|
||||
[[attributes[key] description] XMLEncodedString]];
|
||||
}
|
||||
|
||||
NSString *innerXML = [node innerXML];
|
||||
if ([innerXML length]) {
|
||||
return
|
||||
[NSString stringWithFormat:@"<%1$@%2$@>%3$@</%1$@>", nodeName,
|
||||
attributeString, innerXML];
|
||||
} else {
|
||||
return [NSString
|
||||
stringWithFormat:@"<%@%@/>", nodeName, attributeString];
|
||||
}
|
||||
} else {
|
||||
return
|
||||
[NSString stringWithFormat:@"<%1$@>%2$@</%1$@>", nodeName,
|
||||
[[node description] XMLEncodedString]];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)endText {
|
||||
if (_trimWhiteSpace) {
|
||||
_text = [[_text stringByTrimmingCharactersInSet:
|
||||
[NSCharacterSet whitespaceAndNewlineCharacterSet]]
|
||||
mutableCopy];
|
||||
}
|
||||
if ([_text length]) {
|
||||
NSMutableDictionary *top = [_stack lastObject];
|
||||
id existing = top[XMLDictionaryTextKey];
|
||||
if ([existing isKindOfClass:[NSArray class]]) {
|
||||
[existing addObject:_text];
|
||||
} else if (existing) {
|
||||
top[XMLDictionaryTextKey] = [@[ existing, _text ] mutableCopy];
|
||||
} else {
|
||||
top[XMLDictionaryTextKey] = _text;
|
||||
}
|
||||
}
|
||||
_text = nil;
|
||||
}
|
||||
|
||||
- (void)addText:(NSString *)text {
|
||||
if (!_text) {
|
||||
_text = [NSMutableString stringWithString:text];
|
||||
} else {
|
||||
[_text appendString:text];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)parser:(__unused NSXMLParser *)parser
|
||||
didStartElement:(NSString *)elementName
|
||||
namespaceURI:(__unused NSString *)namespaceURI
|
||||
qualifiedName:(__unused NSString *)qName
|
||||
attributes:(NSDictionary *)attributeDict {
|
||||
[self endText];
|
||||
|
||||
NSMutableDictionary *node = [NSMutableDictionary dictionary];
|
||||
switch (_nodeNameMode) {
|
||||
case XMLDictionaryNodeNameModeRootOnly: {
|
||||
if (!_root) {
|
||||
node[XMLDictionaryNodeNameKey] = elementName;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XMLDictionaryNodeNameModeAlways: {
|
||||
node[XMLDictionaryNodeNameKey] = elementName;
|
||||
break;
|
||||
}
|
||||
case XMLDictionaryNodeNameModeNever: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ([attributeDict count]) {
|
||||
switch (_attributesMode) {
|
||||
case XMLDictionaryAttributesModePrefixed: {
|
||||
for (NSString *key in [attributeDict allKeys]) {
|
||||
node[[XMLDictionaryAttributePrefix
|
||||
stringByAppendingString:key]] = attributeDict[key];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XMLDictionaryAttributesModeDictionary: {
|
||||
node[XMLDictionaryAttributesKey] = attributeDict;
|
||||
break;
|
||||
}
|
||||
case XMLDictionaryAttributesModeUnprefixed: {
|
||||
[node addEntriesFromDictionary:attributeDict];
|
||||
break;
|
||||
}
|
||||
case XMLDictionaryAttributesModeDiscard: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!_root) {
|
||||
_root = node;
|
||||
_stack = [NSMutableArray arrayWithObject:node];
|
||||
if (_wrapRootNode) {
|
||||
_root = [NSMutableDictionary dictionaryWithObject:_root
|
||||
forKey:elementName];
|
||||
[_stack insertObject:_root atIndex:0];
|
||||
}
|
||||
} else {
|
||||
NSMutableDictionary *top = [_stack lastObject];
|
||||
id existing = top[elementName];
|
||||
if ([existing isKindOfClass:[NSArray class]]) {
|
||||
[existing addObject:node];
|
||||
} else if (existing) {
|
||||
top[elementName] = [@[ existing, node ] mutableCopy];
|
||||
} else if (_alwaysUseArrays) {
|
||||
top[elementName] = [NSMutableArray arrayWithObject:node];
|
||||
} else {
|
||||
top[elementName] = node;
|
||||
}
|
||||
[_stack addObject:node];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)nameForNode:(NSDictionary *)node
|
||||
inDictionary:(NSDictionary *)dict {
|
||||
if (node.nodeName) {
|
||||
return node.nodeName;
|
||||
} else {
|
||||
for (NSString *name in dict) {
|
||||
id object = dict[name];
|
||||
if (object == node) {
|
||||
return name;
|
||||
} else if ([object isKindOfClass:[NSArray class]] &&
|
||||
[object containsObject:node]) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)parser:(__unused NSXMLParser *)parser
|
||||
didEndElement:(__unused NSString *)elementName
|
||||
namespaceURI:(__unused NSString *)namespaceURI
|
||||
qualifiedName:(__unused NSString *)qName {
|
||||
[self endText];
|
||||
|
||||
NSMutableDictionary *top = [_stack lastObject];
|
||||
[_stack removeLastObject];
|
||||
|
||||
if (!top.attributes && !top.childNodes && !top.comments) {
|
||||
NSMutableDictionary *newTop = [_stack lastObject];
|
||||
NSString *nodeName = [self nameForNode:top inDictionary:newTop];
|
||||
if (nodeName) {
|
||||
id parentNode = newTop[nodeName];
|
||||
if (top.innerText && _collapseTextNodes) {
|
||||
if ([parentNode isKindOfClass:[NSArray class]]) {
|
||||
parentNode[[parentNode count] - 1] = top.innerText;
|
||||
} else {
|
||||
newTop[nodeName] = top.innerText;
|
||||
}
|
||||
} else if (!top.innerText && _stripEmptyNodes) {
|
||||
if ([parentNode isKindOfClass:[NSArray class]]) {
|
||||
[parentNode removeLastObject];
|
||||
} else {
|
||||
[newTop removeObjectForKey:nodeName];
|
||||
}
|
||||
} else if (!top.innerText && !_collapseTextNodes &&
|
||||
!_stripEmptyNodes) {
|
||||
top[XMLDictionaryTextKey] = @"";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)parser:(__unused NSXMLParser *)parser
|
||||
foundCharacters:(NSString *)string {
|
||||
[self addText:string];
|
||||
}
|
||||
|
||||
- (void)parser:(__unused NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock {
|
||||
[self addText:[[NSString alloc] initWithData:CDATABlock
|
||||
encoding:NSUTF8StringEncoding]];
|
||||
}
|
||||
|
||||
- (void)parser:(__unused NSXMLParser *)parser foundComment:(NSString *)comment {
|
||||
if (_preserveComments) {
|
||||
NSMutableDictionary *top = [_stack lastObject];
|
||||
NSMutableArray *comments = top[XMLDictionaryCommentsKey];
|
||||
if (!comments) {
|
||||
comments = [@[ comment ] mutableCopy];
|
||||
top[XMLDictionaryCommentsKey] = comments;
|
||||
} else {
|
||||
[comments addObject:comment];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSDictionary (XMLDictionary)
|
||||
|
||||
+ (NSDictionary *)dictionaryWithXMLParser:(NSXMLParser *)parser {
|
||||
return [[[XMLDictionaryParser sharedInstance] copy]
|
||||
dictionaryWithParser:parser];
|
||||
}
|
||||
|
||||
+ (NSDictionary *)dictionaryWithXMLData:(NSData *)data {
|
||||
return
|
||||
[[[XMLDictionaryParser sharedInstance] copy] dictionaryWithData:data];
|
||||
}
|
||||
|
||||
+ (NSDictionary *)dictionaryWithXMLString:(NSString *)string {
|
||||
return [[[XMLDictionaryParser sharedInstance] copy]
|
||||
dictionaryWithString:string];
|
||||
}
|
||||
|
||||
+ (NSDictionary *)dictionaryWithXMLFile:(NSString *)path {
|
||||
return
|
||||
[[[XMLDictionaryParser sharedInstance] copy] dictionaryWithFile:path];
|
||||
}
|
||||
|
||||
- (NSDictionary *)attributes {
|
||||
NSDictionary *attributes = self[XMLDictionaryAttributesKey];
|
||||
if (attributes) {
|
||||
return [attributes count] ? attributes : nil;
|
||||
} else {
|
||||
NSMutableDictionary *filteredDict =
|
||||
[NSMutableDictionary dictionaryWithDictionary:self];
|
||||
[filteredDict removeObjectsForKeys:@[
|
||||
XMLDictionaryCommentsKey,
|
||||
XMLDictionaryTextKey,
|
||||
XMLDictionaryNodeNameKey
|
||||
]];
|
||||
for (NSString *key in [filteredDict allKeys]) {
|
||||
[filteredDict removeObjectForKey:key];
|
||||
if ([key hasPrefix:XMLDictionaryAttributePrefix]) {
|
||||
filteredDict[[key
|
||||
substringFromIndex:[XMLDictionaryAttributePrefix length]]] =
|
||||
self[key];
|
||||
}
|
||||
}
|
||||
return [filteredDict count] ? filteredDict : nil;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSDictionary *)childNodes {
|
||||
NSMutableDictionary *filteredDict = [self mutableCopy];
|
||||
[filteredDict removeObjectsForKeys:@[
|
||||
XMLDictionaryAttributesKey,
|
||||
XMLDictionaryCommentsKey,
|
||||
XMLDictionaryTextKey,
|
||||
XMLDictionaryNodeNameKey
|
||||
]];
|
||||
for (NSString *key in [filteredDict allKeys]) {
|
||||
if ([key hasPrefix:XMLDictionaryAttributePrefix]) {
|
||||
[filteredDict removeObjectForKey:key];
|
||||
}
|
||||
}
|
||||
return [filteredDict count] ? filteredDict : nil;
|
||||
}
|
||||
|
||||
- (NSArray *)comments {
|
||||
return self[XMLDictionaryCommentsKey];
|
||||
}
|
||||
|
||||
- (NSString *)nodeName {
|
||||
return self[XMLDictionaryNodeNameKey];
|
||||
}
|
||||
|
||||
- (id)innerText {
|
||||
id text = self[XMLDictionaryTextKey];
|
||||
if ([text isKindOfClass:[NSArray class]]) {
|
||||
return [text componentsJoinedByString:@"\n"];
|
||||
} else {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)innerXML {
|
||||
NSMutableArray *nodes = [NSMutableArray array];
|
||||
|
||||
for (NSString *comment in [self comments]) {
|
||||
[nodes
|
||||
addObject:[NSString stringWithFormat:@"<!--%@-->",
|
||||
[comment XMLEncodedString]]];
|
||||
}
|
||||
|
||||
NSDictionary *childNodes = [self childNodes];
|
||||
for (NSString *key in childNodes) {
|
||||
[nodes addObject:[XMLDictionaryParser XMLStringForNode:childNodes[key]
|
||||
withNodeName:key]];
|
||||
}
|
||||
|
||||
NSString *text = [self innerText];
|
||||
if (text) {
|
||||
[nodes addObject:[text XMLEncodedString]];
|
||||
}
|
||||
|
||||
return [nodes componentsJoinedByString:@"\n"];
|
||||
}
|
||||
|
||||
- (NSString *)XMLString {
|
||||
if ([self count] == 1 && ![self nodeName]) {
|
||||
// ignore outermost dictionary
|
||||
return [self innerXML];
|
||||
} else {
|
||||
return
|
||||
[XMLDictionaryParser XMLStringForNode:self
|
||||
withNodeName:[self nodeName] ?: @"root"];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray *)arrayValueForKeyPath:(NSString *)keyPath {
|
||||
id value = [self valueForKeyPath:keyPath];
|
||||
if (value && ![value isKindOfClass:[NSArray class]]) {
|
||||
return @[ value ];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
- (NSString *)stringValueForKeyPath:(NSString *)keyPath {
|
||||
id value = [self valueForKeyPath:keyPath];
|
||||
if ([value isKindOfClass:[NSArray class]]) {
|
||||
value = [value count] ? value[0] : nil;
|
||||
}
|
||||
if ([value isKindOfClass:[NSDictionary class]]) {
|
||||
return [(NSDictionary *)value innerText];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
- (NSDictionary *)dictionaryValueForKeyPath:(NSString *)keyPath {
|
||||
id value = [self valueForKeyPath:keyPath];
|
||||
if ([value isKindOfClass:[NSArray class]]) {
|
||||
value = [value count] ? value[0] : nil;
|
||||
}
|
||||
if ([value isKindOfClass:[NSString class]]) {
|
||||
return @{XMLDictionaryTextKey : value};
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSString (XMLDictionary)
|
||||
|
||||
- (NSString *)XMLEncodedString {
|
||||
return
|
||||
[[[[[self stringByReplacingOccurrencesOfString:@"&" withString:@"&"]
|
||||
stringByReplacingOccurrencesOfString:@"<"
|
||||
withString:@"<"]
|
||||
stringByReplacingOccurrencesOfString:@">"
|
||||
withString:@">"]
|
||||
stringByReplacingOccurrencesOfString:@"\""
|
||||
withString:@"""]
|
||||
stringByReplacingOccurrencesOfString:@"\'"
|
||||
withString:@"'"];
|
||||
}
|
||||
|
||||
@end
|
||||
Loading…
x
Reference in New Issue
Block a user