原理
CocoaHTTPServer框架能夠在iOS上建立起一個(gè)本地服務(wù)器恬涧,只要電腦和移動(dòng)設(shè)備連入同一熱點(diǎn),即可使用電腦訪問iOS服務(wù)器的頁面搜立,利用POST實(shí)現(xiàn)文件的上傳昆淡。
實(shí)現(xiàn)
CocoaHTTPServer沒有現(xiàn)成的向iOS設(shè)備傳輸?shù)腟ample,我通過學(xué)習(xí)OS X端的Sample實(shí)現(xiàn)了iOS端的文件傳輸盒件,按照下面的步驟配置即可。
1.下載CocoaHTTPServer
2.解壓后舱禽,將CocoaHTTPServer-master目錄下的Core導(dǎo)入工程炒刁。
3.打開Samples/SimpleFileUploadServer,將其中的MyHTTPConnection類文件誊稚、web文件夾導(dǎo)入工程翔始。
4.打開Vendor罗心,將其中的CocoaAsyncSocket、CocoaLumberjack文件夾導(dǎo)入城瞎。
5.打開工程渤闷,打開MyHTTPConnection.m,根據(jù)標(biāo)記#pragma mark multipart form data parser delegate跳轉(zhuǎn)或者直接找到139行脖镀,- (void) processStartOfPartWithHeader:(MultipartMessageHeader*) header方法飒箭,將其中filePath的值修改為iOS的某個(gè)目錄,這個(gè)路徑是上傳的文件存儲(chǔ)的路徑蜒灰,這里以Caches為例:
// NSString* uploadDirPath = [[config documentRoot] stringByAppendingPathComponent:@"upload"];
NSString *uploadDirPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
6 例子如下
var localHttpServer:HTTPServer!
func setupLocalHttpServer() {
// setupLocalHttpServer()\
localHttpServer = HTTPServer.init()
localHttpServer.setType("_http.tcp")
let fileM = FileManager.init()
// YalaaUpload
if let webPath = Bundle.main.path(forResource: "web", ofType: nil) {
if fileM.fileExists(atPath: webPath) {
print("web \(webPath)")
localHttpServer.setDocumentRoot(webPath)
localHttpServer.setConnectionClass(MyHTTPConnection.classForCoder())
// [httpServer setConnectionClass:[MyHTTPConnection class]];
self.startServer()
}
}
}
func startServer() {
do {
try localHttpServer.start()
let port = localHttpServer.listeningPort()
print("port \(port)")
if let ip = self.getWifiIP() {
print("address http://\(ip):\(port)")
}
} catch let err {
print("error \(err)")
}
}
//獲取本機(jī)無線局域網(wǎng)ip
func getWifiIP() -> String? {
var address: String?
var ifaddr: UnsafeMutablePointer<ifaddrs>? = nil
guard getifaddrs(&ifaddr) == 0 else {
return nil
}
guard let firstAddr = ifaddr else {
return nil
}
for ifptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) {
let interface = ifptr.pointee
// Check for IPV4 or IPV6 interface
let addrFamily = interface.ifa_addr.pointee.sa_family
if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) {
// Check interface name
let name = String(cString: interface.ifa_name)
if name == "en0" {
// Convert interface address to a human readable string
var addr = interface.ifa_addr.pointee
var hostName = [CChar](repeating: 0, count: Int(NI_MAXHOST))
getnameinfo(&addr,socklen_t(interface.ifa_addr.pointee.sa_len), &hostName, socklen_t(hostName.count), nil, socklen_t(0), NI_NUMERICHOST)
address = String(cString: hostName)
}
}
}
freeifaddrs(ifaddr)
return address
}
注意事項(xiàng)如果沒有網(wǎng)絡(luò)請(qǐng)求的情況下弦蹂,您的app 是無法獲取到網(wǎng)絡(luò)權(quán)限的,獲取不到網(wǎng)絡(luò)權(quán)限强窖,您的app 就無法使用局域網(wǎng)傳輸文件建議您在設(shè)置之前凸椿,這樣加句代碼
import Alamofire
enum ApiUrl:String {
case baidu = "https://www.cnblogs.com/ybw123321/p/5359911.html"
}
extension ApiUrl: URLConvertible {
/// Returns a `URL` if `self` can be used to initialize a `URL` instance, otherwise throws.
///
/// - Returns: The `URL` initialized with `self`.
/// - Throws: An `AFError.invalidURL` instance.
public func asURL() throws -> URL {
guard let url = URL(string: self.rawValue) else { throw AFError.invalidURL(url: self) }
return url
}
}
let re = Alamofire.AF.request(ApiUrl.baidu, method: HTTPMethod.get)
re.response { res in
let mm = res.result
switch mm {
case .success(let data):
print("data \(data)")
case .failure(let error):
print("error \(error)")
}
}