將要修改的全部都用類(lèi)然后調(diào)用的時(shí)候直接在manager里操作
如圖4個(gè)文件都是涉及到指標(biāo)的
class DHTechIndexManager: NSObject {
/// 供指標(biāo)庫(kù)讀取文件
/// - Parameter type: <#type description#>
static func loadXML(type: DJQuoteMarketInfo.BCTechIndexType?) {
if let targetPath = DHTechIndexPath.getTargetPath(for: type ?? .stock),
let sortTechIndexPath = DHTechIndexPath.getSortTechIndexPath(for: type ?? .stock) {
DHBaseTechIndexXmlEditor.loadXML(sortTechIndexPath: sortTechIndexPath, targetPath: targetPath) { str in
}
} else {
DZPrint("Invalid BCTechIndexType")
}
}
/// 保存常用指標(biāo)
/// - Parameters:
/// - type: <#type description#>
/// - saveData: <#saveData description#>
/// - finsehdHandler: <#finsehdHandler description#>
static func saveNormalTechIndexImpl(type:DJQuoteMarketInfo.BCTechIndexType?,
saveData: [BCTechIndexXMLTitleNode],
finsehdHandler: @escaping (() -> Void)) {
if let sortTechIndexPath = DHTechIndexPath.getSortTechIndexPath(for: type ?? .stock) {
DHBaseTechIndexXmlEditor.saveNormalTechIndex(sortTechIndexPath: sortTechIndexPath, saveData: saveData, finsehdHandler: finsehdHandler)
} else {
DZPrint("Invalid BCTechIndexType")
}
}
/// 獲取常用指標(biāo),優(yōu)先從文件中讀取,如果文件為空,則返回默認(rèn)指標(biāo)
/// - Parameters:
/// - type: <#type description#>
/// - finshedHandler: <#finshedHandler description#>
static func getNormalTechIndexImpl(type:DJQuoteMarketInfo.BCTechIndexType?,
finshedHandler: @escaping ([BCTechIndexXMLTitleNode])->Void) {
if let sortTechIndexPath = DHTechIndexPath.getSortTechIndexPath(for: type ?? .stock) {
DHBaseTechIndexXmlEditor.getNormalTechIndex(type: type, sortTechIndexPath: sortTechIndexPath, finshedHandler: finshedHandler)
} else {
DZPrint("Invalid BCTechIndexType")
}
}
/// 保存排序后的常用指(主副圖分組)
/// - Parameters:
/// - type: <#type description#>
/// - saveData: <#saveData description#>
/// - finsehdHandler: <#finsehdHandler description#>
static func saveNormalTechIndexGroup(type:DJQuoteMarketInfo.BCTechIndexType?, saveData:(master:[BCTechIndexXMLTitleNode],figure:[BCTechIndexXMLTitleNode]),
finsehdHandler:(()->Void)? = nil)
{
if let sortTechIndexPath = DHTechIndexPath.getSortTechIndexPath(for: type ?? .stock) {
DHBaseTechIndexXmlEditor.saveNormalTechIndexGroup(sortTechIndexPath: sortTechIndexPath, saveData: saveData ,finsehdHandler: finsehdHandler)
} else {
DZPrint("Invalid BCTechIndexType")
}
}
/// 獲取所有指標(biāo)(主圖附圖分組)
/// - Parameters:
/// - sortTechIndexPath: <#sortTechIndexPath description#>
/// - finshedHandler: <#finshedHandler description#>
static func getNormalTechIndexGroup(type:DJQuoteMarketInfo.BCTechIndexType?,
finshedHandler: @escaping ((master:[BCTechIndexXMLTitleNode],figure:[BCTechIndexXMLTitleNode]))->Void)
{
if let sortTechIndexPath = DHTechIndexPath.getSortTechIndexPath(for: type ?? .stock) {
DHBaseTechIndexXmlEditor.getNormalTechIndexGroup(sortTechIndexPath: sortTechIndexPath, finshedHandler: finshedHandler)
} else {
DZPrint("Invalid BCTechIndexType")
}
}
//MARK - 以下方法為老數(shù)據(jù)兼容方法
/// 獲取常用指標(biāo)
/// - Parameters:
/// - type: <#type description#>
/// - finshedHandler: <#finshedHandler description#>
static func getNormalTechIndex(type:DJQuoteMarketInfo.MarketType?,
finshedHandler: @escaping ([BCTechIndexXMLTitleNode])->Void) {
if type == .CNStock {
BCTechIndexXmlEditor.getNormalTechIndex { (obj) in
finshedHandler(obj)
}
} else {
BCTechIndexXmlEditor.Industry_getFilterTechIndex { (obj) in
finshedHandler(obj)
}
}
}
/// 獲取指標(biāo)數(shù)據(jù)(按指標(biāo)類(lèi)型分類(lèi))
/// - Parameters:
/// - type: <#type description#>
/// - finshedHandler: <#finshedHandler description#>
static func getAllXMLTechIndexGroup( _ type:DJQuoteMarketInfo.BCTechIndexType?,
finshedHandler : @escaping ([(groupName:String,indexData:[BCTechIndexXMLNodeItem])]?)->Void)
{
if type == .stock {
DHBaseTechIndexXmlEditor.getAllXMLTechIndexGroup { (obj) in
if var allContent = obj {
var updatedContent: [(groupName: String, indexData: [BCTechIndexXMLNodeItem])] = []
for content in allContent {
let groupName = content.groupName
var groupIndexData = content.indexData
//個(gè)股特色型不能有這3個(gè)特色指標(biāo)
if groupName == "特色型" {
let toRemove = ["情緒周期", "連板高度", "四季牛熊"]
groupIndexData = content.indexData.filter { !toRemove.contains($0.id) }
}
let updatedContentItem = (groupName: groupName, indexData: groupIndexData)
updatedContent.append(updatedContentItem)
}
allContent = updatedContent
finshedHandler(allContent)
}
}
} else {
DHBaseTechIndexXmlEditor.getAllXMLTechIndexGroup { (obj) in
finshedHandler(obj)
}
}
}
}
import UIKit
class DHTechIndexPath: NSObject {
static let paths: [DJQuoteMarketInfo.BCTechIndexType: (targetPath: String, sortTechIndexPath: String)] = [
.stock: (
targetPath: (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first as NSString?)?.appendingPathComponent("bctechIndexxml.xml") ?? "",
sortTechIndexPath: (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first as NSString?)?.appendingPathComponent("bcsortTechIndexPath.plist") ?? ""
),
.industry: (
targetPath: (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first as NSString?)?.appendingPathComponent("industry_bctechIndexxml.xml") ?? "",
sortTechIndexPath: (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first as NSString?)?.appendingPathComponent("industry_bcsortTechIndexPath.plist") ?? ""
),
.dpql: (
targetPath: (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first as NSString?)?.appendingPathComponent("QL_bctechIndexxml.xml") ?? "",
sortTechIndexPath: (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first as NSString?)?.appendingPathComponent("QL_bcsortTechIndexPath.plist") ?? ""
)
]
static func getTargetPath(for type: DJQuoteMarketInfo.BCTechIndexType) -> String? {
return DHTechIndexPath.paths[type]?.targetPath
}
static func getSortTechIndexPath(for type: DJQuoteMarketInfo.BCTechIndexType) -> String? {
return DHTechIndexPath.paths[type]?.sortTechIndexPath
}
}
import UIKit
class DHDefaultTechIndex: NSObject {
static let ownObj = DHDefaultTechIndex()
//默認(rèn)指標(biāo)
lazy var getDefaultTechIndex:[BCTechIndexXMLTitleNode] =
{
var retObj = [BCTechIndexXMLTitleNode]()
retObj.append(BCTechIndexXMLTitleNode(id:"主力操盤(pán)", desc: "主力操盤(pán)"))
retObj.append(BCTechIndexXMLTitleNode(id:"主力控盤(pán)", desc: "主力控盤(pán)"))
retObj.append(BCTechIndexXMLTitleNode(id:"主力吸籌", desc: "主力吸籌"))
// retObj.append(BCTechIndexXMLTitleNode(id:"超短擒龍主", desc: "超短擒龍主"))
// retObj.append(BCTechIndexXMLTitleNode(id:"超短擒龍副", desc: "超短擒龍副"))
retObj.append(BCTechIndexXMLTitleNode(id:"MA", desc: "MA"))
retObj.append(BCTechIndexXMLTitleNode(id:"MACD", desc: "MACD"))
retObj.append(BCTechIndexXMLTitleNode(id:"KDJ", desc: "KDJ"))
retObj.append(BCTechIndexXMLTitleNode(id:"BOLL", desc: "BOLL"))
retObj.append(BCTechIndexXMLTitleNode(id:"VOL", desc: "VOL"))
return retObj
}()
//板塊指標(biāo)
lazy var getIndustryTechIndex:[BCTechIndexXMLTitleNode] =
{
var retObj = [BCTechIndexXMLTitleNode]()
retObj.append(BCTechIndexXMLTitleNode(id:"主力操盤(pán)", desc: "主力操盤(pán)"))
retObj.append(BCTechIndexXMLTitleNode(id:"主力控盤(pán)", desc: "主力控盤(pán)"))
retObj.append(BCTechIndexXMLTitleNode(id:"主力吸籌", desc: "主力吸籌"))
// retObj.append(BCTechIndexXMLTitleNode(id:"超短擒龍主", desc: "超短擒龍主"))
// retObj.append(BCTechIndexXMLTitleNode(id:"超短擒龍副", desc: "超短擒龍副"))
retObj.append(BCTechIndexXMLTitleNode(id:"MA", desc: "MA"))
retObj.append(BCTechIndexXMLTitleNode(id:"MACD", desc: "MACD"))
retObj.append(BCTechIndexXMLTitleNode(id:"KDJ", desc: "KDJ"))
retObj.append(BCTechIndexXMLTitleNode(id:"BOLL", desc: "BOLL"))
retObj.append(BCTechIndexXMLTitleNode(id:"VOL", desc: "VOL"))
retObj.append(BCTechIndexXMLTitleNode(id:"四季牛熊", desc: "四季牛熊"))
retObj.append(BCTechIndexXMLTitleNode(id:"連板高度", desc: "連板高度"))
retObj.append(BCTechIndexXMLTitleNode(id:"情緒周期", desc: "情緒周期"))
return retObj
}()
//大盤(pán)擒龍指標(biāo)
lazy var getQLTechIndex:[BCTechIndexXMLTitleNode] =
{
var retObj = [BCTechIndexXMLTitleNode]()
// retObj.append(BCTechIndexXMLTitleNode(id:"四季牛熊", desc: "四季牛熊"))
//要判斷情緒周期指標(biāo)有沒(méi)有權(quán)限
//zb1_fkld
/*
let zb1_fkld = DJPrivilageBusiness.isHaveData(funcType: .zb1_fkld)
let ggQxzq = DJPrivilageBusiness.isHaveData(funcType: .ggQxzq)
if zb1_fkld && ggQxzq{
//兩個(gè)權(quán)限都有則一個(gè)都不顯示
}else if (zb1_fkld == true && ggQxzq == false){
//風(fēng)口輪動(dòng)還沒(méi)開(kāi)發(fā),也不添加
}else if (zb1_fkld == false && ggQxzq == true){
//只有情緒周期
}else{
//兩個(gè)權(quán)限都沒(méi)有
}
*/
let ggsjnx = DJPrivilageBusiness.isHaveData(funcType: .zb1_sjnx)
if ggsjnx == true{
retObj.append(BCTechIndexXMLTitleNode(id:"四季牛熊", desc: "四季牛熊"))
}
let ggQxzq = DJPrivilageBusiness.isHaveData(funcType: .ggQxzq)
if ggQxzq == true{
retObj.append(BCTechIndexXMLTitleNode(id:"情緒周期", desc: "情緒周期"))
}
let gglbgd = DJPrivilageBusiness.isHaveData(funcType: .zb1_lbgd)
if gglbgd == true{
retObj.append(BCTechIndexXMLTitleNode(id:"連板高度", desc: "連板高度"))
}
retObj.append(BCTechIndexXMLTitleNode(id:"MA", desc: "MA"))
retObj.append(BCTechIndexXMLTitleNode(id:"MACD", desc: "MACD"))
retObj.append(BCTechIndexXMLTitleNode(id:"KDJ", desc: "KDJ"))
retObj.append(BCTechIndexXMLTitleNode(id:"BOLL", desc: "BOLL"))
retObj.append(BCTechIndexXMLTitleNode(id:"VOL", desc: "VOL"))
return retObj
}()
}
import UIKit
class DHBaseTechIndexXmlEditor: NSObject {
static let ownObj = DHBaseTechIndexXmlEditor()
let loadXMLQueue = DispatchQueue(label: "DHBaseTechIndexXmlEditor.loadXMLQueue")
//分組后的Content
var techIndexContent:[(groupName:String,indexData:[BCTechIndexXMLNodeItem])]?
//未分組的無(wú)序的Content
var allTechIndexContent:[String:BCTechIndexXMLNodeItem]?
private var orignXMLData:String?
static var techIndexY = [String:[CGFloat?]?]()
/// 查找指標(biāo)數(shù)據(jù)
/// - Parameter techIndexID: <#techIndexID description#>
/// - Returns: <#description#>
static func findTechIndexData(techIndexID:String) -> BCTechIndexXMLNodeItem?
{
return ownObj.allTechIndexContent?[techIndexID]
}
/// 獲取指標(biāo)數(shù)據(jù)
/// - Parameters:
/// - techIndexID: <#techIndexID description#>
/// - handler: <#handler description#>
static func getTechIndexData(techIndexID:String, _ handler : @escaping (BCTechIndexXMLNodeItem?)->Void)
{
if let data = findTechIndexData(techIndexID: techIndexID)
{
DispatchQueue.main.async {
handler(data)
}
return
}
else
{
self.ownObj.loadXMLQueue.async {
if let data = self.ownObj.techIndexContent
{
for item in data
{
for subItem in item.indexData
{
if subItem.id == techIndexID
{
DispatchQueue.main.async {
handler(subItem)
}
return
}
}
}
}
else
{
DispatchQueue.main.async {
handler(nil)
}
}
}
}
}
//默認(rèn)指標(biāo)
lazy var getDefaultTechIndex:[BCTechIndexXMLTitleNode] =
{
return DHDefaultTechIndex.ownObj.getDefaultTechIndex
}()
//板塊指標(biāo)
lazy var getIndustryTechIndex:[BCTechIndexXMLTitleNode] =
{
return DHDefaultTechIndex.ownObj.getIndustryTechIndex
}()
//大盤(pán)擒龍指標(biāo)
func QL_getDefaultTechIndex() -> [BCTechIndexXMLTitleNode] {
return DHDefaultTechIndex.ownObj.getQLTechIndex
}
//修改XML參數(shù)
static func modifyXML(item:BCTechIndexXMLNodeItem, finshedHandler: @escaping ()->Void)
{
ownObj.loadXMLQueue.async
{
//修改緩存中techIndexContent的參數(shù)數(shù)據(jù)
if let index = ownObj.techIndexContent?.firstIndex(where: { (obj) -> Bool in
return obj.groupName == item.groupName
})
{
if let subIndex = ownObj.techIndexContent?[index].indexData.firstIndex(where: { (obj) -> Bool in
return item.id == obj.id
})
{
ownObj.techIndexContent?[index].indexData[subIndex] = item
}
}
//修改整個(gè)XML數(shù)據(jù)
if let xmlData = ownObj.orignXMLData
{
if let obj = try? GDataXMLDocument(xmlString: xmlData)
{
let domObj = obj.rootElement()
if let findNode = try? domObj?.nodes(forXPath: "http://group1/group2/index") as? [GDataXMLNode],let params = item.params
{
if let contentNode = findNode
{
for subItem in contentNode
{
if let id = try? subItem.firstNode(forXPath: "@id").stringValue()
{
if id == item.id
{
if let allElement = subItem.children()
{
//可以更改分量名稱(chēng)的指標(biāo),比如5日MA才睹,那么指標(biāo)描述名字為MA5,只是為了UI顯示直觀
let canModifyContentName = ["MA","EMA","SMA","PBX"].contains(id?.uppercased())
//刪除原始參數(shù)元素
for element in allElement
{
if element.name() == "param"
{
(subItem as? GDataXMLElement)?.removeChild(element)
}
}
//增加修改后的參數(shù)元素
var contentString = ""
for repaceItem in params
{
if let name = repaceItem.name, let max = repaceItem.max ,let min = repaceItem.min , let value = repaceItem.value
{
let newElement = GDataXMLElement.element(withName: "param")
let attributeName = GDataXMLNode.attribute(withName: "name", stringValue: name) as? GDataXMLNode
let attributeDesc = GDataXMLNode.attribute(withName: "desc", stringValue: "") as? GDataXMLNode
let attributeMin = GDataXMLNode.attribute(withName: "min", stringValue: min) as? GDataXMLNode
let attributeMax = GDataXMLNode.attribute(withName: "max", stringValue: max) as? GDataXMLNode
let attributeValue = GDataXMLNode.attribute(withName: "default", stringValue:value) as? GDataXMLNode
let attributeStep = GDataXMLNode.attribute(withName: "step", stringValue: "0") as? GDataXMLNode
newElement?.addAttribute(attributeName)
newElement?.addAttribute(attributeDesc)
newElement?.addAttribute(attributeMin)
newElement?.addAttribute(attributeMax)
newElement?.addAttribute(attributeValue)
newElement?.addAttribute(attributeStep)
(subItem as? GDataXMLElement)?.addChild(newElement)
//一些均線名字通過(guò)參數(shù)而定 比如5日MA朱沃,那么指標(biāo)描述名字為MA5
if let nameValue = Float(value)
{
if id == "MA"
{
contentString = contentString + "MA\(Int(nameValue)):MA(CLOSE,\(name));"
}
else if id == "EMA"
{
contentString = contentString + "EMA\(Int(nameValue)):EMA(CLOSE,\(name));"
}
else if id == "SMA"
{
contentString = contentString + "SMA\(Int(nameValue)):SMA(CLOSE,\(name),1);"
}
else if id == "PBX"
{
//PBX1:(EMA(CLOSE,M1)+MA(CLOSE,M1*2)+MA(CLOSE,M1*4))/3
contentString = contentString + "PBX\(Int(nameValue)):(EMA(CLOSE,\(name))+MA(CLOSE,\(name)*2)+MA(CLOSE,\(name)*4))/3;"
}
}
}
}
if canModifyContentName
{
//let newElement = GDataXMLElement.element(withName: "content")
if let contentAtr = try?subItem.firstNode(forXPath: "@content")
{
(subItem as? GDataXMLElement)?.removeChild(contentAtr)
}
(subItem as? GDataXMLElement)?.addChild(GDataXMLNode.attribute(withName: "content", stringValue: contentString) as? GDataXMLNode)
}
saveXMLModifyedXMLData(xmlData: obj.xmlData())
DispatchQueue.main.async {
finshedHandler()
}
break
}
}
}
}
}
}
}
}
}
}
}
//MARK: - 文件存儲(chǔ)相關(guān)
extension DHBaseTechIndexXmlEditor
{
//XML保存路徑
static let targetPath = (NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).first as NSString?)?.appendingPathComponent("bctechIndexxml.xml")
//XML初始路徑
static let initPath = Bundle.main.path(forResource: "sys_index", ofType: "xml")
static let initXMLXRC32Key = "initXMLXRC32Key"
//供指標(biāo)庫(kù)讀取文件
@objc static func loadXML(sortTechIndexPath: String,
targetPath: String?,
finshedHandler: @escaping (String?)->Void)
{
DHBaseTechIndexXmlEditor.ownObj.loadXMLQueue.async {
var retObj:String? = try? String(contentsOf: URL(fileURLWithPath: DHBaseTechIndexXmlEditor.initPath! ), encoding: .utf8)
let sysIndexXMLCRC32 = DataEncryAndDecry.icrc32(with: retObj ?? "")
let savedSysIndexXMLCRC32 = Int(UserDefaults.standard.object(forKey: DHBaseTechIndexXmlEditor.initXMLXRC32Key) as? String ?? "-1")!
if savedSysIndexXMLCRC32 != sysIndexXMLCRC32
{
//刪除本地保存的指標(biāo)
let fileManager = FileManager.default
if fileManager.fileExists(atPath: sortTechIndexPath ?? "")
{
if let _ = try? fileManager.removeItem(atPath: sortTechIndexPath) {}
}
UserDefaults.standard.set(String(sysIndexXMLCRC32), forKey: DHBaseTechIndexXmlEditor.initXMLXRC32Key)
UserDefaults.standard.synchronize()
}
else if let _targetPath = targetPath
{
if let retStr = try? String(contentsOf: URL(fileURLWithPath: _targetPath ), encoding: .utf8)
{
retObj = retStr
}
}
DHBaseTechIndexXmlEditor.ownObj.orignXMLData = retObj
DispatchQueue.main.async {
finshedHandler(retObj)
}
parseXMLData { _ in
}
// DispatchQueue.main.async {
//
// DHBaseTechIndexXmlEditor.ownObj.orignXMLData = retObj
//
// finshedHandler(retObj)
//
// DHBaseTechIndexXmlEditor.parseXMLData { _ in }
//
//
//
// }
}
}
/// 保存修改后的指標(biāo)
/// - Parameter xmlData: <#xmlData description#>
static func saveXMLModifyedXMLData(xmlData:Data)
{
guard let xmlString = String(data: xmlData, encoding: .utf8) else { return }
DispatchQueue.global().async {
BCTechIndexBusiness.updateIndexFormul(data: xmlString)
}
//更新數(shù)據(jù)
if let _ = try? xmlString.write(to: URL(fileURLWithPath:targetPath!), atomically: true, encoding: .utf8)
{
ownObj.orignXMLData = xmlString
parseXMLData { _ in
}
}
}
/// 解析指標(biāo)
/// - Parameter finshedHandler: <#finshedHandler description#>
static func parseXMLData( _ finshedHandler : @escaping ([(groupName:String,indexData:[BCTechIndexXMLNodeItem])]?)->Void)
{
ownObj.loadXMLQueue.async {
if let xmlData = ownObj.orignXMLData
{
if let obj = try? GDataXMLDocument(xmlString: xmlData)
{
let domObj = obj.rootElement()
if let findNode = try? domObj?.nodes(forXPath: "http://group1/group2") as? [GDataXMLNode]
{
if let groupNode = findNode
{
var techIndexContent = [(String,[BCTechIndexXMLNodeItem])]()
var allIndexConetent = [String:BCTechIndexXMLNodeItem]()
for item in groupNode
{
let groupName = try! item.firstNode(forXPath: "@name").stringValue()
BCTechIndexXmlEditor.convertToTraditionalString(simpleString: groupName)
var contentItem = (groupName!,[BCTechIndexXMLNodeItem]())
let allContentNode = try! item.nodes(forXPath: "index") as! [GDataXMLNode]
for contentNode in allContentNode
{
var item = BCTechIndexXMLNodeItem()
let indexID = try! contentNode.firstNode(forXPath: "@id").stringValue()
BCTechIndexXmlEditor.convertToTraditionalString(simpleString: indexID)
item.id = indexID
item.groupName = groupName
let inexName = try? contentNode.firstNode(forXPath: "@name").stringValue()
item.name = inexName ?? ""
BCTechIndexXmlEditor.convertToTraditionalString(simpleString: item.name)
if let indexDesc = try? contentNode.firstNode(forXPath: "@desc").stringValue()
{
item.desc = indexDesc
BCTechIndexXmlEditor.convertToTraditionalString(simpleString: item.desc)
}
if let help = try? contentNode.firstNode(forXPath: "@help").stringValue()
{
item.help = help
BCTechIndexXmlEditor.convertToTraditionalString(simpleString: item.help)
}
if let flag = try? contentNode.firstNode(forXPath: "@flag").stringValue() ?? "0"
{
item.isMaster = 0x00100000 & (Int(flag) ?? 0) != 0
}
if let content = try? contentNode.firstNode(forXPath: "@content").stringValue()
{
item.content = content
BCTechIndexXmlEditor.convertToTraditionalString(simpleString: item.content)
print("content = \(content?.description)\n")
// print("")
// item.help = help
// DHBaseTechIndexXmlEditor.convertToTraditionalString(simpleString: item.help)
}
//解析默認(rèn)參數(shù)
if let params = try? contentNode.nodes(forXPath: "defaultparam")
{
if params.count > 0
{
item.defaultparams = [(name:String?,value:String?,max:String?,min:String?)]()
for paramNode in params
{
if let paramName = try? (paramNode as? GDataXMLNode)?.firstNode(forXPath: "@name").stringValue() , let paramValue = try? (paramNode as? GDataXMLNode)?.firstNode(forXPath: "@default").stringValue(),let max = try? (paramNode as? GDataXMLNode)?.firstNode(forXPath: "@max").stringValue(),let min = try? (paramNode as? GDataXMLNode)?.firstNode(forXPath: "@min").stringValue()
{
item.defaultparams?.append((paramName,paramValue,max,min))
}
}
}
else
{
item.defaultparams = nil
}
}
//解析參數(shù)
if let params = try? contentNode.nodes(forXPath: "param")
{
item.params = [(name:String?,value:String?,max:String?,min:String?)]()
let bAddDefaultParam = item.defaultparams == nil
if bAddDefaultParam
{
item.defaultparams = [(name:String?,value:String?,max:String?,min:String?)]()
}
for paramNode in params
{
if let paramName = try? (paramNode as? GDataXMLNode)?.firstNode(forXPath: "@name").stringValue() , let paramValue = try? (paramNode as? GDataXMLNode)?.firstNode(forXPath: "@default").stringValue(),let max = try? (paramNode as? GDataXMLNode)?.firstNode(forXPath: "@max").stringValue(),let min = try? (paramNode as? GDataXMLNode)?.firstNode(forXPath: "@min").stringValue()
{
item.params?.append((paramName,paramValue,max,min))
if bAddDefaultParam
{
item.defaultparams?.append((paramName,paramValue,max,min))
}
}
}
}
//解析y
if let params = try? contentNode.nodes(forXPath: "line")
{
item.Y = [CGFloat?]()
for paramNode in params
{
if let y = try? (paramNode as? GDataXMLNode)?.firstNode(forXPath: "@y").stringValue()
{
if let _y = y
{
item.Y?.append(CGFloat(Double(_y)!))
}
}
}
}
contentItem.1.append(item)
techIndexY[item.id] = item.Y
allIndexConetent.updateValue(item, forKey: item.id)
}
techIndexContent.append(contentItem)
}
ownObj.techIndexContent = techIndexContent
ownObj.allTechIndexContent = allIndexConetent
finshedHandler(ownObj.techIndexContent)
}
}
}
}
}
}
/// 獲取指標(biāo)數(shù)據(jù)(按指標(biāo)類(lèi)型分類(lèi))
/// - Parameter finshedHandler: <#finshedHandler description#>
static func getAllXMLTechIndexGroup( _ finshedHandler : @escaping ([(groupName:String,indexData:[BCTechIndexXMLNodeItem])]?)->Void)
{
if ownObj.techIndexContent?.count != 0 && ownObj.techIndexContent != nil
{
finshedHandler(ownObj.techIndexContent)
}
else
{
parseXMLData { (obj) in
DispatchQueue.main.async {
finshedHandler(obj)
}
}
}
}
/// 保存排序后的常用指(主副圖分組)
/// - Parameters:
/// - sortTechIndexPath: <#sortTechIndexPath description#>
/// - saveData: <#saveData description#>
/// - finsehdHandler: <#finsehdHandler description#>
static func saveNormalTechIndexGroup(sortTechIndexPath:String,
saveData:(master:[BCTechIndexXMLTitleNode],figure:[BCTechIndexXMLTitleNode]),
finsehdHandler:(()->Void)? = nil)
{
DHBaseTechIndexXmlEditor.ownObj.loadXMLQueue.async {
let masterMap = saveData.master.map({ (obj) -> [String:String?] in
return [obj.id:obj.desc]
})
let figureMap = saveData.figure.map({ (obj) -> [String:String?] in
return [obj.id:obj.desc]
})
([masterMap,figureMap] as NSArray).write(to: URL(fileURLWithPath: sortTechIndexPath), atomically: true)
finsehdHandler?()
}
}
/// 保存常用指標(biāo)
/// - Parameters:
/// - sortTechIndexPath: <#sortTechIndexPath description#>
/// - saveData: <#saveData description#>
/// - finsehdHandler: <#finsehdHandler description#>
static func saveNormalTechIndex(sortTechIndexPath:String,
saveData:[BCTechIndexXMLTitleNode],
finsehdHandler:(()->Void)? = nil)
{
DHBaseTechIndexXmlEditor.ownObj.loadXMLQueue.async {
let masterMap = saveData.compactMap({ (obj) -> [String:String?] in
return [obj.id:obj.desc]
})
(masterMap as NSArray).write(to: URL(fileURLWithPath: sortTechIndexPath), atomically: true)
finsehdHandler?()
}
}
/// 獲取常用指標(biāo),優(yōu)先從文件中讀取培廓,如果文件為空罗晕,則返回默認(rèn)指標(biāo)
/// - Parameters:
/// - type: <#type description#>
/// - sortTechIndexPath: <#sortTechIndexPath description#>
/// - finshedHandler: <#finshedHandler description#>
static func getNormalTechIndex(type:DJQuoteMarketInfo.BCTechIndexType?,
sortTechIndexPath:String,
finshedHandler: @escaping ([BCTechIndexXMLTitleNode])->Void)
{
// DHBaseTechIndexXmlEditor.ownObj.loadXMLQueue.async
// {
var retObj = [BCTechIndexXMLTitleNode]()
//如果本地保存了就從本地拿
let arr = NSArray(contentsOf: URL(fileURLWithPath: sortTechIndexPath))
if (arr?.count ?? 0) != 0
{
if let data = arr as? [[String:String?]]
{
let _retObj = data.map({ obj -> BCTechIndexXMLTitleNode in
return BCTechIndexXMLTitleNode(id: obj.keys.first, desc: obj.values.first as? String)
})
retObj.append(contentsOf: _retObj)
}
finshedHandler(retObj)
return
}
if type == .stock {
retObj.append(contentsOf: DHBaseTechIndexXmlEditor.ownObj.getDefaultTechIndex)
} else if type == .dpql {
retObj.append(contentsOf: DHBaseTechIndexXmlEditor.ownObj.QL_getDefaultTechIndex())
} else if type == .industry {
retObj.append(contentsOf: DHBaseTechIndexXmlEditor.ownObj.getIndustryTechIndex)
}
//保存排序指標(biāo)
DHBaseTechIndexXmlEditor.saveNormalTechIndex(sortTechIndexPath: sortTechIndexPath, saveData: retObj)
//這里并生成
finshedHandler(retObj)
// }
}
/// 獲取所有指標(biāo)(主圖附圖分組)
/// - Parameters:
/// - sortTechIndexPath: <#sortTechIndexPath description#>
/// - finshedHandler: <#finshedHandler description#>
static func getNormalTechIndexGroup(sortTechIndexPath: String,
finshedHandler: @escaping((master:[BCTechIndexXMLTitleNode],figure:[BCTechIndexXMLTitleNode]))->Void)
{
ownObj.loadXMLQueue.async
{
var retObj:(master:[BCTechIndexXMLTitleNode],figure:[BCTechIndexXMLTitleNode]) = ([BCTechIndexXMLTitleNode](),[BCTechIndexXMLTitleNode]())
//如果本地保存了就從本地拿
let arr = NSArray(contentsOf: URL(fileURLWithPath: sortTechIndexPath))
if (arr?.count ?? 0) != 0
{
if let masrterData = arr?.firstObject as? [[String:String?]]
{
let _retObj = masrterData.map({ obj -> BCTechIndexXMLTitleNode in
return BCTechIndexXMLTitleNode(id: obj.keys.first, desc: obj.values.first as? String)
})
retObj.master.append(contentsOf: _retObj)
}
if let figureData = arr?.lastObject as? [[String:String?]]
{
let _retObj = figureData.map({ obj -> BCTechIndexXMLTitleNode in
return BCTechIndexXMLTitleNode(id: obj.keys.first, desc: obj.values.first as? String)
})
retObj.figure.append(contentsOf: _retObj)
}
finshedHandler(retObj)
return
}
//這里并生成
finshedHandler(retObj)
}
}
}
extension DJQuoteMarketInfo
{
enum BCTechIndexType: Int {
/// 未知類(lèi)型,初始值0
case unknown = 0
/// 個(gè)股
case stock = 1
/// 板塊
case industry = 2
/// 大盤(pán)擒龍
case dpql = 3
/// 所有類(lèi)型
case all = 4
}
}
DHTechIndexManager負(fù)責(zé)給外部調(diào)用脆贵,外部想要什么業(yè)務(wù),只需要傳類(lèi)型或數(shù)據(jù)即可
DHTechIndexPath 負(fù)責(zé)根據(jù)類(lèi)型去取本地的指標(biāo)緩存路徑
DHDefaultTechIndex 負(fù)責(zé)默認(rèn)的指標(biāo)名字
DHBaseTechIndexXmlEditor 負(fù)責(zé)指標(biāo)業(yè)務(wù)的具體實(shí)現(xiàn)
DJQuoteMarketInfo 負(fù)責(zé)指標(biāo)類(lèi)型
總的來(lái)說(shuō)就是將一系列功能拆分成一個(gè)個(gè)的模塊起暮,有點(diǎn)類(lèi)似于構(gòu)造者模式卖氨。改的話(huà)只需要改一個(gè)地方,不會(huì)影響到其他地方,做到了對(duì)外擴(kuò)展對(duì)修改關(guān)閉筒捺!