Framework的那些事

写在前面:
回想了一下这个项目,接手到现在也就是一个多月,真正难过的或许也只是理解Java代码并变成Swift,和后面联调的过程。多的不说,记录一下遇到的问题,争取能巩固,提高技术。


还需要一点点前奏:
现在Framework的制作方法真是,只要你想找,总有你要的。所以我挑了一个内容丰富一点的,供您参考。iOS 制作静态库 .a 文件 和 .framework 文件 以及解决第三方库冲突问题 (转载 mark 一下) - Luck_Developer的博客 - 博客频道 - CSDN.NET


进入正题:
那么现在,一个空的Framework应该已经被搭建完成并且编译通过了。其实本来我也只是想讲讲代码问题 :)。不得不说,关键在于,Swift严格的类型检查给我在调用C的Api的时候带来了不少小麻烦。


Q1.Java的[Byte]如何在Swift中实现?
A: Java的Byte数据类型,真身就是Int8。那么,我们只要:

typealias Byte = Int8

然后给String加一个扩展方法就可以啦

extension String
{
    func getBytes()->[Byte]
    {
        var byteArray = [Byte]()
        
        for char in utf8
        {
            byteArray.append(Byte(char))
        }
        
        return  byteArray
    }
}```
*****
Q2.Java字符串的```trim```方法如何在Swift中实现?
A:  同样只要给String加一个扩展方法

extension String
{
func trim()->String
{
return contains(" ") ? trimmingCharacters(in: CharacterSet(charactersIn: " ")) : self
}
}

*****
Q3.那么,有时候Swift会把C的Api中,Java的```Byte```类型,识别成```UInt8```,导致参数要求是```[Byte]```,实际必须传```[UInt8]```(Swift:没错,我说它是```UInt```,你就得传```UInt```!),怎么破?
A:  多的不说见代码。**不过,千万不要轻易尝试类似如下的代码:** 

let num1:Int8 = 0
let num2 = UInt8(num1)

__正确的⬇️⬇️__

func toInt8Array(arr:[UInt8])->[Int8]
{
var temp = Int8
for c in arr
{
temp.append(Int8(bitPattern: c))
}
return temp
}

func toUInt8Array(arr:[Int8])->[UInt8]
{
var temp = UInt8
for c in arr
{
temp.append(UInt8(bitPattern: c))
}
return temp
}


而且,我不会说我把好的东西都放在后面。

*****
Q4.Java中,arrayCopy这样的操作在Swift中如何实现?
A: 确实拿到手后纠结了一小会。多的不说你们自己看代码

func arrayCopy(src:Array,srcPos:Int,dest:Array,destPos:Int,length:Int)->Array
{
var temp = dest

for i in 0..

}

这里写了一个__泛型__函数,不知道什么是泛型以及在这个函数中作用的,请问问度娘,她会教你的:)
*****
__Q5.各种算法__
一直很赞同算法是一个好程序的灵魂。
**Base64---Encode:**

internal func base64Encode(array:[UInt8])->String
{
return Data.init(bytes: array, count: array.count).base64EncodedString(options: Data.Base64EncodingOptions.endLineWithLineFeed)
}
internal func base64Encode(array:[Int8])->String
{
return Data.init(bytes: array, count: array.count).base64EncodedString(options: Data.Base64EncodingOptions.endLineWithLineFeed)
}

By the way,```internal```关键字是因为我写在了一个单独的文件中,不熟悉的可以去查一下访问控制。这里写两个方法呢,也只是为了应付@Swift,(sad face)
**Base64---Decode:**

internal func base64Decode(base64String:String)->[UInt8]
{
let data = Data.init(base64Encoded: base64String, options: Data.Base64DecodingOptions.ignoreUnknownCharacters)!

var tempArr = [UInt8]()

for i in 0..

}

so,不要问我代码里为什么直接```!```,而不用```if let { }```或者```guard let else { throw }```,我相信你注意到了形参名是什么~

**SHA1**

internal func sha1(string: String) -> String
{
var Sha1Result = ""

if let data = string.data(using: String.Encoding.utf8)
{
    var digest = [UInt8](repeating: 0, count: Int(CC_SHA1_DIGEST_LENGTH))
    
    CC_SHA1((data as NSData).bytes, CC_LONG(data.count), &digest)

    
    for index in 0..

}

**CRC32**
�偷偷懒,拿个OC的凑合用吧,记得导入
  • (uint32_t)CRC32Value
    {
    uLong crc = crc32(0L, Z_NULL, 0);
    crc32(crc, self.bytes, self.length);
    return crc;
    }
*****
Q6.那么,序列化
A: 当我一开始知道,要将一个未知的模型转化成JSON的时候,其实我的心里是拒绝的。OC有MJExtension,Swift有Reflect了,拿来主义不就行了!但是在Framework里导入别人的框架不到万不得已,个人觉得还是不要这么干,原因有三,1.自己把握方法实现,出Bug了好查一点。2.还要做必要的配置工作,3.文件夹在明里会多3个文件。。好吧总结123就是,懒懒懒。
那么,希望你们碰到这样需求的时候不会苦逼的要抽方法,抽模型出来调试:

extension NSObject
{
func getProperty() throws ->[String:Any?]
{
struct getPropertyError: Error
{
var ErrorReason:String

        init(reason:String)
        {
            ErrorReason = reason
        }
    }
    
    var props = [String:Any?]()
    
    var outCount:UInt32 = 0
    
    if let properties = class_copyPropertyList(classForCoder, &outCount)
    {
        for i in 0..

}

*****
Q7. 最后的最后,网络部分。
A: 模型变字典,然后愉快的(~~并不~~)变成了JSON之后,我们要和服务器通讯了。Java�如果用流式传输,就是创建```Stream```对象然后用```read```or```write```方法给服务器传输数据,oh,no!To be frank,不习惯。怎么办?
我们有```URLSession```.

举个POST方法的例子吧。
First:定义一个```URLRequest```,设置

req.httpMethod = "POST"

然后把要上传的数据准备好,这个例子就讲完了。(完结撒花,此处有没有不重要)
*****

“Wait,URLSession方法是异步的呀,放在有返回值的方法里,回调还没执行,方法就return啦!”
“......”
 //创建信号量
 let semaphore = DispatchSemaphore(value: 0)  

 URLSession.shared.uploadTask(with: req, from: data, completionHandler: {
        (resData, response, error) in            
        /*do something */

        //�终于等到你 还好我没放弃
        semaphore.signal()
    }).resume()
     
    //如果要给等待加一个期限 我希望是永远  
    _ = semaphore.wait(timeout: DispatchTime.distantFuture)
*****
到这里基本上所有的大坑都踩完了。剩下的整理整理想一想遗漏的再更新啦,谢谢看到这里的人,希望你们喜欢,也希望对你们有帮助。
如果觉得写的入得了各位看官老爷的法眼,请不要吝啬点个赞,Thank u very much!
*****
**最后感谢**[@xiaoheng](http://www.jianshu.com/users/bafc9a0f5df2/timeline),[@瑾瑾小泉](http://www.jianshu.com/users/d7ffbe4ce951)两位在闲暇时刻的讨论支持:)

你可能感兴趣的:(Framework的那些事)