• The problem

    In business scenarios, files and pictures in mobile phones need to be transferred to other devices.

    It is not limited to the transmission of letters, information and so on

  • plan

    The most base method: add a cloud between devices, devices upload data to the cloud, cloud synchronization data to each device, suitable for multiple devices, this is not necessary

    If it is between two devices, ignore the server, what happens? Think of the WiFi book transfer in the book App, it seems that there is no cloud concept, how to do it?

  • serving

    • Using the framework GCDWebServer, introduced through CocoaPods
    Pod "GCDWebServer", "~ > 3.0"Copy the code
    • Set up the local receive directory, initialize the Server, and start it
    override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) if let filepath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first as NSString? { let path = filepath.appendingPathComponent("transfer") if ! FileManager.default.fileExists(atPath: path) { do { try FileManager.default.createDirectory(atPath: path, withIntermediateDirectories: false, attributes: nil) } catch { print(error) } } webServer = GCDWebUploader(uploadDirectory: path) webServer?.delegate = self webServer?.allowHiddenItems = true webServer?.allowedFileExtensions = ["doc", "docx", "xls", "xlsx", "txt", "pdf", "jpeg", Prologue = "Enjoy the WIFI management platform using the Epilogue tool" webServer?. Epilogue = "Epilogue" if webServer?.start() == true, let address = IPHelper.deviceIPAdress(), address.count > 0, let port = webServer?.port { ipLb.text = "1. Do not close the page \n3. please type the address \ NHTTP ://\(address):\(port)/"} else {iplb. text = "GCDWebServer not running!" }}}Copy the code
    • Obtain the LOCAL IP address from the LAN and set access links to other devices
    #import <ifaddrs.h> #import <arpa/inet.h> #import <net/if.h> @implementation IPHelper + (NSString *)deviceIPAdress { NSString *address = @""; struct ifaddrs *interfaces = NULL; struct ifaddrs *temp_addr = NULL; int success = 0; success = getifaddrs(&interfaces); If (success == 0) {temp_addr = interfaces; while (temp_addr ! = NULL) { if( temp_addr->ifa_addr->sa_family == AF_INET) { // Check if interface is en0 which is the wifi connection on the iPhone if ([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) { // Get NSString from C String address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)]; } } temp_addr = temp_addr->ifa_next; } } freeifaddrs(interfaces); return address; } #define IOS_CELLULAR @"pdp_ip0" #define IOS_WIFI @"en0" #define IOS_VPN @"utun0" #define IP_ADDR_IPv4 @"ipv4" #define IP_ADDR_IPv6 @"ipv6" #pragma mark - get the current network IP address of the device + (NSString *)getIPAddress:(BOOL)preferIPv4 {NSArray *searchArray = preferIPv4 ? @[ IOS_VPN @"/" IP_ADDR_IPv4, IOS_VPN @"/" IP_ADDR_IPv6, IOS_WIFI @"/" IP_ADDR_IPv4, IOS_WIFI @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6 ] : @[ IOS_VPN @"/" IP_ADDR_IPv6, IOS_VPN @"/" IP_ADDR_IPv4, IOS_WIFI @"/" IP_ADDR_IPv6, IOS_WIFI @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4 ] ; NSDictionary *addresses = [self getIPAddresses]; NSLog(@"addresses: %@", addresses); __block NSString *address; [searchArray enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL *stop) { address = addresses[key]; If ([self isValidatIP:address]) *stop = YES;}]; return address ? Address: @ "0.0.0.0"; } + (BOOL)isValidatIP:(NSString *)ipAddress { if (ipAddress.length == 0) { return NO; } NSString *urlRegEx = @"^([01]? \\d\\d? |2[0-4]\\d|25[0-5])\\." "([01]? \\d\\d? |2[0-4]\\d|25[0-5])\\." "([01]? \\d\\d? |2[0-4]\\d|25[0-5])\\." "([01]? \\d\\d? |2[0-4]\\d|25[0-5])$"; NSError *error; NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:urlRegEx options:0 error:&error]; if (regex ! = nil) { NSTextCheckingResult *firstMatch=[regex firstMatchInString:ipAddress options:0 range:NSMakeRange(0, [ipAddress length])]; if (firstMatch) { NSRange resultRange = [firstMatch rangeAtIndex:0]; NSString *result=[ipAddress substringWithRange:resultRange]; NSLog(@"%@",result); return YES; } } return NO; } + (NSDictionary *)getIPAddresses { NSMutableDictionary *addresses = [NSMutableDictionary dictionaryWithCapacity:8]; // retrieve the current interfaces - returns 0 on success struct ifaddrs *interfaces; if(! getifaddrs(&interfaces)) { // Loop through linked list of interfaces struct ifaddrs *interface; for(interface=interfaces; interface; interface=interface->ifa_next) { if(! (interface->ifa_flags & IFF_UP) /* || (interface->ifa_flags & IFF_LOOPBACK) */ ) { continue; // deeply nested code harder to read } const struct sockaddr_in *addr = (const struct sockaddr_in*)interface->ifa_addr; char addrBuf[ MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) ]; if(addr && (addr->sin_family==AF_INET || addr->sin_family==AF_INET6)) { NSString *name = [NSString stringWithUTF8String:interface->ifa_name]; NSString *type; if(addr->sin_family == AF_INET) { if(inet_ntop(AF_INET, &addr->sin_addr, addrBuf, INET_ADDRSTRLEN)) { type = IP_ADDR_IPv4; } } else { const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*)interface->ifa_addr; if(inet_ntop(AF_INET6, &addr6->sin6_addr, addrBuf, INET6_ADDRSTRLEN)) { type = IP_ADDR_IPv6; } } if(type) { NSString *key = [NSString stringWithFormat:@"%@/%@", name, type]; addresses[key] = [NSString stringWithUTF8String:addrBuf]; } } } // Free memory freeifaddrs(interfaces); } return [addresses count] ? addresses : nil; }Copy the code
    • You can access this address from another device
    let address = IPHelper.deviceIPAdress()
    let port = webServer?.port
    http://\(address):\(port)/
    Copy the code
    • Remark:
      • Ensure devices are on the same LAN
      • Do not close this page when uploading
  • Game Over

    On the LAN, the device serves as the server and other devices serve as clients. Files are uploaded to the server in simple HTTP mode. The initial configuration path is the path for storing the files received by the server