‘功能性’Swift#5:JSON提取和解析

在前面的部分(1、2、3、4)中,我们已经看到了如何将一系列保护语句重写为简单的函数链,并将其扩展为返回Result类型。

在本文中,我们将使用相同的技术(使用可选版本)来获取和解析JSON文件。

首先,我们需要JSON:

  [ 
{
“ title”:“ Title1”,
“字幕”:“ Subtitle1”
},
{
“ title”:“ Title2”,
“字幕”:“ Subtitle2”
}
]

…以及解析为…的类型

 结构项:可编码 
{
var标题:字符串
var副标题:字串
}

请注意,该结构被标记为符合Swift 4 Codable协议。

现在,让我们为文件路径提供一个帮助程序类型(并非绝对必要,但我认为它使我们正在处理的类型更加明确):

 结构文件路径 
{
private(set)var值:字符串
  init?(在捆绑包中:Bundle = .main, 
ofType fileExt:字符串=“ json”,
命名名称:字符串?)
{
守卫让路径= bundle.path(forResource:name,
ofType:fileExt)
否则{return nil}

self.value =路径
}
}

现在我们可以构建我们的展开函数:

 结构展开 
{
typealias StringToData =(字符串)->数据?
typealias PathToString =(文件路径)->字符串?
 静态函数fMap (_ fnc:@转义(T)-> U?)->(T?)-> U? 
{
返回{$ 0.flatMap(fnc)}
}
 静态让stringToData:StringToData = {$ 0.data(使用:.utf8)} 
 静态让pathToString:PathToString = { 
尝试? 字符串(contentsOfFile:$ 0.value,编码:.utf8)
}
 静态函数解码JSON ()->(数据)-> T? 
{
返回{试试? JSONDecoder()。decode(T.self,from:$ 0)}
}
}

就像在第2部分中一样,我们定义了一个fMap函数来包装我们的处理函数,以及几个简单的函数-一个用于从FilePath中获取内容作为字符串 ,另一个用于将String展开为Data? 。 我们还定义了一个通用的encodeJSON函数,该函数接受Data并尝试根据推断的类型对其进行解码。

完成所有这些操作后,我们就可以构建我们的组合函数了。

 扩展名展开 
{
静态函数jsonData (在捆绑包中:Bundle = .main,
命名名称:字符串)-> T?
{
返回Filepath(in:bundle,ofType:“ json”,命名:name)
|> fMap(pathToString)
>>> fMap(stringToData)
>>> fMap(decodeJSON())
}
}

同样,该函数是通用的,可以推断已解析的JSON类型,并构造
文件路径值类型
应用(|>) pathToString
由(>>>) stringToData组成
由(>>>) encodeJSON组成

现在,我们有一个函数,它可以使用任何名称/包,并根据推断的类型返回完全解析的JSON; 例如:

 让物品:[物品]?  = Unwrap.jsonData(名称:“测试”) 
items?.forEach {print($ 0)}
  //项目(标题:“ Title1”,字幕:“ Subtitle1”) 
// Item(标题:“ Title2”,字幕:“ Subtitle2”)

非常好! 很容易看出我们如何添加一个新的函数(重用一些现有的处理函数并添加新的,可重用的处理函数)…

url字符串 |> url >>> url的 字符串内容 >>> data >>> 解析的json

在第3部分中,我们可以将ResultMap替换为fMap

在不知不觉中,一次添加几个处理功能,就可以得出一些非常复杂的流程的构建基块,最重要的是,由于它们都具有相同的形式,因此很容易推断出什么是贯穿整个过程 那一定是胜利!

整个示例的要点。