> For the complete documentation index, see [llms.txt](https://ryukiedev.gitbook.io/wiki/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ryukiedev.gitbook.io/wiki/swift/swift-qing-liang-ji-wang-luo-feng-zhuang-swiftyserviceprotocol-shi-yong-yu-hun-bian-huo-chun-swift-x.md).

# 21.Swift轻量级网络封装：SwiftyServiceProtocol（适用于混编或纯Swift项目）

## 一、前言

随着Swift越来越成熟，越来越多的项目也开始使用Swift了。很多朋友应该都有遇到和OC混编的情况。

我自己的话，纯Swift和混编的都做过。在爽过纯Swift后，在混编时经常会有被困住手脚的感觉。

尤其这两年的公司项目，很多老代码和必须依赖的基础库都是OC。特别是网络库（基于AFN），又不能不用公司的。

但是在使用过Swift的[Moya](https://github.com/Moya/Moya)框架后，对于在混编的Swift中不能写出很Swift的网络请求这件事尤为难受。

于是有了想解决这点痛苦的想法。就有了 `SwiftyServiceProtocol`

> 对`Swift` 的 `协议` `枚举` `泛型`等有一定了解的话会很便于理解

## 二、封装目标

1. 不依赖任何三方网络库
2. 便于更换底层网络库（AFN? Alamofire? 自研网络库？ 无痛切换。极端一点你甚至可以不同模块使用不同网络库)
3. 用起来很Moya很Swifty
4. 兼容多模块多域名
5. 轻量
6. 用于纯Swift项目或者混编项目（不考虑OC调用。原因：单纯的不喜欢）
7. 便于模块化处理

## 三、SwiftyServiceProtocol

源码在此：[GitHub*SwiftyServiceProtocol*喜欢的话点个小星星吧⭐️](https://github.com/RyukieSama/Swifty/blob/master/Swifty/Protocol/Service/Service.swift)

这个协议十分轻量，不算注释也就12行代码。

### 3.1 在项目中对 SwiftyServiceProtocol 进行拓展

```swift
public protocol MyServiceProtocol: SwiftyServiceProtocol where SwiftyServiceCallBackType == 你的网络库的回调 {

}

extension MyServiceProtocol {
    /// 如果你的项目只有一个域名，在这里写死就好。如果不同模块有不同的域名，那么在对应的Service中实现这个get就行，测试环境生产环境的逻辑也可以放在这里
    var base: String {
        return "你的域名"
    }

    var urlString: String {
        return base + "/" + path
    }

    func request(completion: SwiftyServiceCallBackType?) {
        switch method {
        case .GET:
            get(completion: completion)
        case .POST:
            post(completion: completion)
        }
    }

    // MARK: - Private
    private func post(completion: 你的网络库的回调?) {
        // 你的POST实现
    }

    private func get(completion: 你的网络库的回调?) {
        // 你的GET实现
    }
}
```

### 3.2 实际使用

> 这里以用户模块的一些请求为例

#### 定义相关Service

```swift
enum YourUserService { // 定义你需要的接口
    /// 获取用户信息
    case Info(uid: Int64)
    /// 关注某人
    case Follow(uid: Int64)
    /// 取消关注某人
    case UnFollow(uid: Int64)
}

extension YourUserService: MyServiceProtocol {
    // var base: String {
    //     return "如果这个模块有不同模块有不同的域名，在这里实现这个get就行"
    // }

    /// 接口参数
    var parameters: [AnyHashable : Any]? {
        switch self {
        case let .Info(uid):
            return ["uid" : uid]
        case .Follow(let uid):
            return ["id" : uid]
        case .UnFollow(let uid):
            return ["id" : uid]
        }
    }

    /// 接口路径
    var path: String {
        switch self {
        case .Info:
            return "info的path"
        case .Follow:
            return "follow的path"
        case .UnFollow:
            return "unfollow的path"
        }
    }

    /// 请求方法选择
    var method: SwiftyServiceMethod {
        switch self {
        case .Info:
            return .GET
        default:
            return .POST
        }
    }
}
```

### 调用场景

```swift
UserService
    .Info(yourUser.uid)
    .request { (response) in
        // 处理网络回调
    }
```

## 四、总结

这个协议我自己已经在两个混编项目中使用了，如果你也喜欢的话，欢迎来点个小星星⭐️[GitHub\_SwiftyServiceProtocol](https://github.com/RyukieSama/Swifty/blob/master/Swifty/Protocol/Service/Service.swift)

参考： [Moya](https://github.com/Moya/Moya)
