IOS realizes WIFI transfer book

  • problem

    In the business scenario, there is a need to transfer the files and pictures in the mobile phone to other devices.

    Not only limited to the transfer of books, materials, etc., can be transferred

  • Program

    The most basic method: add a cloud between devices, upload data to the cloud, and synchronize data to each device. It is suitable for multiple devices. This is not necessary.

    If it is between two devices and ignore the server, what should I do? Reminiscent of the WiFi transfer in the Books App, it seems that there is no concept of cloud, how can it be done?

  • Serve

    • Using the framework GCDWebServer, introduced through CocoaPods
    pod "GCDWebServer", "~> 3.0"
    • Set the local receiving directory, initialize the Server and start
    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", "jpg"]
            webServer?.title = "善斋工具"
            webServer?.prologue = "欢饮使用善斋工具的WIFI管理平台"
            webServer?.epilogue = "善斋书屋制作"
    
            if webServer?.start() == true, let address = IPHelper.deviceIPAdress(), address.count > 0, let port = webServer?.port {
                ipLb.text = "1.确保设备在同一局域网 \n2.上传时勿关闭该页面 \n3.请网页中输入该地址 \nhttp://\(address):\(port)/"
            } else {
                ipLb.text = "GCDWebServer not running!"
            }
        }
    }
    • Obtain the ip address of the machine in the local area network, and set access links for 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) { // 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_***         @"utun0"
    #define IP_ADDR_IPv4    @"ipv4"
    #define IP_ADDR_IPv6    @"ipv6"
    
    #pragma mark - 获取设备当前网络IP地址
    + (NSString *)getIPAddress:(BOOL)preferIPv4 {
        NSArray *searchArray = preferIPv4 ?
        @[ IOS_*** @"/" IP_ADDR_IPv4, IOS_*** @"/" IP_ADDR_IPv6, IOS_WIFI @"/" IP_ADDR_IPv4, IOS_WIFI @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6 ] :
        @[ IOS_*** @"/" IP_ADDR_IPv6, IOS_*** @"/" 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];
             //筛选出IP地址格式
             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;
    }
    
    • Just visit the address in other devices
    let address = IPHelper.deviceIPAdress()
    let port = webServer?.port
    http://\(address):\(port)/
    • Remarks:
      • Make sure the devices are in the same local area network
      • Do not close this page while uploading
  • Game Over

    In the local area network, the device acts as a server, and other devices act as clients. Simply upload files to the server via HTTP. The initial configuration path is the path where the file is stored after the server receives it.

Guess you like

Origin blog.51cto.com/15070994/2640585