
目标是将序列化和网络请求做成单独的framework并且可以替换.
所有公用的东西都放在公共库Common中.
workspace 'AppDemo.xcworkspace'
platform :ios, '13.0'
use_frameworks!
load './Api/api_v1.rb'
target :Common do
project 'Common/Common.xcodeproj'
pod 'Alamofire'
end
target :AppDemo do
project 'App/AppDemo/AppDemo.xcodeproj'
pod 'Common', :path => './Common/'
load_api_pods
end
target :ApiModelSerialize do
project 'Api/ApiModelSerialize/ApiModelSerialize.xcodeproj'
pod 'Common', :path => './Common/'
pod 'SwiftyJSON'
end
target :ApiNetwork do
project 'Api/ApiNetwork/ApiNetwork.xcodeproj'
pod 'Common', :path => './Common/'
pod 'Alamofire'
end
load_api_pods是一个单独.rb文件, 想替换framework的话就修改这个文件.
def load_api_pods
pod 'ApiModelSerialize', :path => './Api/ApiModelSerialize/'
pod 'ApiNetwork', :path => './Api/ApiNetwork/'
end
在ApiModelSerialize这个framework中声明一个protocol
protocol ISwiftyJson {
init()
mutating func dFromJSON(json: JSON)
func dToJSON() -> JSON
}
再为一些基本类型扩展遵循一下这个protocol
extension Int: ISwiftyJson {
mutating func dFromJSON(json: JSON) {
self = json.intValue
}
func dToJSON() -> JSON {
var json = JSON()
json.intValue = self
return json
}
}
需要序列化的Model也需要扩展遵循一下这个protocol
extension Member: ISwiftyJson {
public func dFromJSON(json: JSON) {
Id = json["Id"].intValue
}
public func dToJSON() -> JSON {
var json = JSON()
json["Id"].intValue = Id
return json;
}
}
现在序列化这个是基本上算是实现了, 但是还需要封装一下.
Common中声明一个protocol
public protocol IApiModelSerialize {
mutating func aLoadFromJSONString<T>(model: T, str: String)
func aToJSONString<T>(model: T) -> String
func aConvertJSONStringToArray<T>(type: T.Type, str: String) -> [T] where T: ServerModel
}
ApiModelSerialize中遵循一下这个protocol
public class PApiModelSerialize: IApiModelSerialize {
public init() {
}
public func aLoadFromJSONString<T>(model: T, str: String) {
if var m = model as? ISwiftyJson {
m.dFromJSON(json: JSON(parseJSON: str))
}
}
public func aToJSONString<T>(model: T) -> String {
if let m = model as? ISwiftyJson {
return m.dToJSON().rawString()!
}
fatalError("Can't deSerialize")
}
public func aConvertJSONStringToArray<T>(type: T.Type, str: String) -> [T] where T : IServerModel {
let arrayValue = JSON(parseJSON: str)
var array = [T]()
for j in arrayValue {
if let jsonString = j.1.rawString() {
var t = T()
t.aLoadFromJSONString(str: jsonString)
array.append(t)
}
}
return array
}
}
Common中声明一个protocol
public protocol IServerModel {
init()
mutating func aLoadFromJSONString(str: String)
func aToJSONString() -> String
}
ServerModel作为所有Model的父类遵循这个protocol
open class ServerModel: IServerModel {
public required init() {
}
open func aLoadFromJSONString(str: String) {
Api.pModelSerialize.aLoadFromJSONString(model: self, str: str)
}
open func aToJSONString() -> String {
return Api.pModelSerialize.aToJSONString(model: self)
}
}
Model序列化的时候调用aLoadFromJSONString这个方法就可以了.
Common中声明一个protocol
public protocol IApiNetwork {
func aRequest<T>(_ params: ServerParam, handler: IServerRequestHandler<T>?) where T: IServerModel
}
ApiNetwork中遵循一下这个protocol
public class PApiNetwork: IApiNetwork {
public init() {
}
public func aRequest<T>(_ params: ServerParam, handler: IServerRequestHandler<T>?) where T : IServerModel {
ServerUtil_Alamofire.fRequest(params, handler: handler)
}
}
实际使用中调用一下就可以了
open class ServerUtil_Account {
private static let c_Controller = "Account"
public static func Login(loginParam: LoginParam, handler: IServerRequestHandler<MyProfile>?) {
let param = ServerParam(post: true)
.controller(c_Controller)
.action("Login")
.add(value: loginParam)
Api.pNetwork.aRequest(param, handler: handler)
}
}
ApiModelSerialize和ApiNetwork声明在Common中, 实现在具体framework中, 在App中需要将他们关联起来.
class AppConfigImpl {
init() {
}
func connect() {
Api.pModelSerialize = PApiModelSerialize()
Api.pNetwork = PApiNetwork()
}
}
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
AppConfigImpl().connect()
return true
}
}
最后用登录功能做一下验证
ServerUtil_Account.Login(loginParam: loginParam, handler: IServerRequestHandler<MyProfile>({data in
print(data.Member?.NickName)
}, fail: { (failInfo) in
}))
代码放在github, 有需要自取.
https://github.com/drenhart/AppDemo.git
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or
我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie
我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c
我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的
当我在我的Rails应用程序根目录中运行rakedoc:app时,API文档是使用/doc/README_FOR_APP作为主页生成的。我想向该文件添加.rdoc扩展名,以便它在GitHub上正确呈现。更好的是,我想将它移动到应用程序根目录(/README.rdoc)。有没有办法通过修改包含的rake/rdoctask任务在我的Rakefile中执行此操作?是否有某个地方可以查找可以修改的主页文件的名称?还是我必须编写一个新的Rake任务?额外的问题:Rails应用程序的两个单独文件/README和/doc/README_FOR_APP背后的逻辑是什么?为什么不只有一个?
我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co
我正在使用Postgres.app在OSX(10.8.3)上。我已经修改了我的PATH,以便应用程序的bin文件夹位于所有其他文件夹之前。Rammy:~phrogz$whichpg_config/Applications/Postgres.app/Contents/MacOS/bin/pg_config我已经安装了rvm并且可以毫无错误地安装pggem,但是当我需要它时我得到一个错误:Rammy:~phrogz$gem-v1.8.25Rammy:~phrogz$geminstallpgFetching:pg-0.15.1.gem(100%)Buildingnativeextension