2017-09-05 69 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文件存放在服務器上,並使用經過身份驗證的訪問令牌獲取該文件。我提供的代碼可以修改以適應此。

我希望這已經指出你的代碼混淆的正確方向。