2017-09-05 35 views
12

我想发布一个可可触摸框架,其中包含一些包含逻辑的json文件,我不想让框架用户看到;不幸的是在.framework文件里面还有可见的json。当包含在可可触摸框架中时隐藏.json文件

我想到了,包括它在一个迅速文件:

struct JsonProvider { 
    static let json = "..." 
} 

但我的JSON是,大的文件无法使用了。我没有找到命令行编译的解决方案,然后包含它。

是否有两个问题,一个解决方案,即

  • 隐藏框架内的JSON或
  • 预编译迅速文件,然后将其添加到框架?
+0

把它放到一个文件,但编码,例如使用XOR编码。它不会被随机用户阅读 – Sulthan

+0

@Sulthan你能解释一下这一点吗?什么样的文件,我如何编码/解码呢? – swalkner

+1

你想要的是混淆。有数千种混淆数据的方法。您甚至可以对其进行加密并将加密密钥放入您的代码中。也不会阻止真正想要读取数据并知道如何反编译的人,但会阻止随机好奇的用户。 – Sulthan

回答

-1

您可以将json文件内容作为base64编码的字符串添加到源中。

struct JSONFiles { 
    internal static let fileOneBase64String = "iVBORw0KGgoAAAANSUhEUgAAAMEAAADLCAYAAADX..." 
    static var fileOneJSON: [String: Any] { 
     let data = Data(base64Encoded: fileOneBase64String)! 
     return try! JSONSerialization.jsonObject(with: data, options: []) as! [String: Any] 
    } 
} 

你可以在你的框架使用它以后在任何地方通过

print(JSONFiles.fileOneJSON) 

希望它能帮助你

UPDATE: 为什么作为base64编码字符串?

主要好处base64编码字符串 - 你不需要逃避包含在JSON字符串的特殊符号。在添加到swift源文件之前,不需要从json字符串中删除新的行符号/ intendation符号。 见例如

let string: String = "{ \"name\":\"John\", \"email\": \"[email protected]\" \"age\":30, \"car\":null }" 

但是,如果JSON是更复杂?如果它包含10个嵌套级别,数组,字典?

您可以通过该值包含在fileOneBase64String可以解码JSON对象

import XCTest 
@testable import MyAwesomeFramework 

class FrameworkTests: XCTestCase { 

    func testThatBase64EncodedJSONStringCanBeDecoded() { 
     let data = Data(base64Encoded: JSONFiles.fileOneBase64String) 
     XCTAssertNotNil(data, "Unable to convert base64 string to Data") 
     do { 
      _ = try JSONSerialization.jsonObject(with: data, options: []) 
     } catch { 
      XCTFail("Expected decoded JSON ") 
     } 
    } 
} 
+1

这是一个改进,只是将json存储在字符串中? Base64甚至更长,对吧? – swalkner

+0

您不需要转义特殊符号的主要好处。这个解决方案允许存储任何文件类型 –

+0

如果你将在json字符串中转义符号,那么新字符串将会比原始json字符串更大。 –

0

单元测试覆盖所以我创建了一个JSONEncoder结构如下:

public struct JSONEncoder { 

    private static var JSON = "" 
    public static var JSONData = [UInt8]() 
    private static var cipher = [UInt8]() 
    public static var encryptedJSONData = [UInt8]() 
    public static var decryptedJSONData = [UInt8]() 
    private static var decryptedJSON = "" 

    public static func JSONFileToString() {   
    guard let JSONFilePath = Bundle.main.url(forResource: "JSONFile", withExtension:"json"), let cipherFilePath = Bundle.main.url(forResource: "JSONCipher", withExtension:"txt") else { 
     return 
    } 

    do { 
     let text = try String(contentsOf: cipherFilePath, encoding: String.Encoding.utf8)   
     cipher = [UInt8](text.utf8) 
     let data = try Data(contentsOf:JSONFilePath) 

     if let JSON = String(data: data, encoding: String.Encoding.utf8) { 
     self.JSON = JSON 
     JSONData = [UInt8](JSON.utf8) 
     //print("data read: \(JSON)") 
     } else { 
     print("Data to string conversion failed") 
     } 
    } catch { 
     print(error.localizedDescription) 
    } 
    } 

    public static func encodeJSON() { 
    // encrypt bytes 
    for t in JSONData.enumerated() { 
     encryptedJSONData.append(t.element^cipher[t.offset]) 
    } 
    print(encryptedJSONData) 
    } 

    public static func decodeJSON() { 
    for t in encryptedJSONData.enumerated() { 
     decryptedJSONData.append(t.element^cipher[t.offset]) 
    } 
    decryptedJSON = String(bytes: decryptedJSONData, encoding: String.Encoding.utf8)! 
    //print(decryptedJSON) 
    } 

} 

要这样设置你需要添加一个包含要编码的JSON的JSONFile.json文件。将其添加到复制束资源。对密文文件JSONCipher.txt重复此操作。确保这个文件不包含语音标记,因为这会带来错误,并且它足够大以至于不能编码JSON。不要让它太大,否则你会得到记忆警告。

你可以玩这个,编码与XOR一个JSON文件,使用

JSONEncoder.JSONFileToString() 
JSONEncoder.encodeJSON() 

然后,这将打印到控制台,您可以将此代码复制到连接到您的架构一个txt文件。

用于解密该文件,你可以测试如下:

JSONEncoder.decodeJSON() 

(在JSONEncoder结构取消对print声明decodeJSON,可以测试这个工程)

如果你的JSON文件过大对于这个程序,你可以使用这个工具:https://www.browserling.com/tools/xor-encrypt,以及相同域中的类似XOR Decrypter。然后,您可以使用此编码器的输出将加密的JSON文件添加到您的框架。只要确保在解码json时使用相同的密钥!

请注意,这会将您的文本文件存储在实际项目中:这可能不安全。可能将JSONCipher.txt文件存放在服务器上,并使用经过身份验证的访问令牌获取该文件。我提供的代码可以修改以适应此。

我希望这已经指出你的代码混淆的正确方向。