日期: 2021 年 6 月 11 日

ios获取ip信息

ios获取ip信息
#ios

#include <arpa/inet.h>
#include <dns.h>
#include <resolv.h>
#include <ifaddrs.h>

– (NSDictionary *)getIPAddressInfo:(NSString*)strInterface {
NSMutableDictionary *dicIPInfo = [[NSMutableDictionary alloc] init];
NSDictionary *dicConnectList;

struct ifaddrs *interfaces = NULL;
struct ifaddrs *temp_addr = NULL;
int success = 0;

// retrieve the current interfaces – returns 0 on success
success = getifaddrs(&interfaces);
if (success == 0){
// Loop through linked list of interfaces
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

char *interface_name = temp_addr->ifa_name;
if([[NSString stringWithUTF8String:interface_name] isEqualToString:strInterface]){
//接口名称
NSString *strInterfaceName = [NSString stringWithUTF8String:interface_name];

//ip地址
char *ip = inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr);
NSString *strIP = [NSString stringWithUTF8String:ip];

//子网掩码
char *submask = inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_netmask)->sin_addr);
NSString *strSubmask = [NSString stringWithUTF8String:submask];

//广播地址
char *dstaddr = inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_dstaddr)->sin_addr);
NSString *strDstaddr = [NSString stringWithUTF8String:dstaddr];

dicIPInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
strIP,@”ip”,
strSubmask,@”submask”,
strDstaddr,@”broadcast”,nil];

dicConnectList = [NSDictionary dictionaryWithObjectsAndKeys:
dicIPInfo,strInterfaceName,nil];

}
}

temp_addr = temp_addr->ifa_next;
}
}
// Free memory
freeifaddrs(interfaces);
return dicConnectList;
}

// 使用
NSDictionary *dic_en0 = [self getIPAddressInfo:@”en0″];
NSLog(@”en0: %@”,dic_en0);

NSDictionary *dic_pdp_ip0 = [self getIPAddressInfo:@”pdp_ip0″];
NSLog(@”cell: %@”,dic_pdp_ip0);

NSDictionary *dic_ppp0 = [self getIPAddressInfo:@”ppp0″];
NSLog(@”*: %@”,dic_ppp0);

iOS通用链接配置

现在微信、qq等各大平台都开始强制要求配置通用链接

配置通用链接主要的文档:(苹果官方文档)https://developer.apple.com/library/archive/documentation/General/Conceptual/AppSearch/UniversalLinks.html

qq互联平台配置:https://wiki.connect.qq.com/%E5%A1%AB%E5%86%99%E5%8F%8A%E6%A0%A1%E9%AA%8Cuniversallinks

开始准备工作:

首页打开项目配置

如果用户勾选了automatically会自动更新证书,不然的话没有配置的话会提示错误,这个时候就需要到苹果开发者证书后台配置

勾选以后,保存,在更新一下你的证书!(完成以后记得保存Prefix+bundleId,后面写文件的要用到)

完成上述步骤以后,开始配置通用链接:

创建一个apple-app-site-association包含有关您的应用程序可以处理的URL的JSON数据的文件。

将apple-app-site-association文件上传到您的HTTPS Web服务器。您可以将文件放置在服务器的根目录或.well-known子目录中。

准备您的应用程序以处理通用链接

1、创建json格式的一个空文件(取名必须为apple-app-site-association,并且没有后缀,隐藏后缀)

{ “applinks”: {
“apps”: [],
“details”: [ {
“appID”: “9JA89QQLNQ.com.apple.wwdc”,
“paths”: [ “/wwdc/news/”, “/videos/wwdc/2015*”, “/qq_conn/222222/*” ]
}, {
“appID”:”ABCD1234.com.apple.wwdc”,
“paths”: [ “*”, “/qq_conn/222222/*” ]
} ] }
}
这里的appID是指:TeamID+BundleId的组成(例:9JA89QQLNQ.com.apple.test)(TeamID可以在开发者账号里面查看,BundleId是项目的Bundle Identifier)。
这里的paths是指:是设置允许的路径列表,可以是一个也可以是多个,*简单的方式是使用“*”,通配符,表示允许该域名下的任意路径。(注意:paths中的大小写是敏感的,一定要一一对应)
2、开始上传到服务器(放在根目录下),且服务器必须配置了HTTPS,上传成功后通过输入域名+文件名检查是否能上传成功,并且能够访问:例如上传到了https:www.xxxx.com,那么上传成功之后打开浏览器访问https:www.xxxx.com/apple-app-site-association

3、成功以后配置项目中的通用链接:

注意事项
Associated Domains 配置必须以applinks: 开头

例如:上传的服务器为https:www.xxxx.com,那这里就填写applinks:www.xxxx.com

开始验证
在iOS设备中的备忘录中输入App能识别的链接,然后直接点击此链接,就会直接跳转到你的app了。或是长按,在出现的弹出菜单中第二项是在’XXX’中打开,这也代表着成功:

 

或是你将要测试的网址在safari中打开,在出现的网页上方下滑,可以看到有在”XX”应用中打开:

出现菜单:

 

 

在微信的网页浏览器中也是可以的,虽然微信屏蔽了所有的scheme方式跳转到其它app,但是Universal Links是由系统直接处理的,微信屏蔽不了,这也就实现了从微信跳转到我们的app。

苹果为了方便开发者,提供了一个网页来验证我们编写的这个apple-app-site-association是否合法有效,进入验证网址进行验证:

进入app后的处理

现在用户点击某个链接,直接可以进我们的app了,但是我们的目的是要能够获取到用户进来的链接,根据链接来展示给用户相应的内容。
我们需要在工程里的 AppDelegate 里实现方法

 

 

– (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler

{

if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb])

{

NSURL *url = userActivity.webpageURL;

if (url是我们希望处理的)

{

//进行我们的处理

}

else

{

[[UIApplication sharedApplication] openURL:url];

}

}

 

return YES;

}

注意

前端开发经常面临跨域问题,必须要求跨域,如果不跨域,就不行。
只有当前webview的url域名,与跳转目标url域名不一致时,Universal Link 才生效。

*后
在各大平台配置通用链接的时候一定要按照官方文档的配置,尤其的是qq的,不明白可以多查阅qq互联的文档

iOS获取设备IP地址

一.导入头文件

//首先导入头文件信息
#include <ifaddrs.h>
#include <arpa/inet.h>
#include <net/if.h>

#define IOS_CELLULAR @”pdp_ip0″
//有些分配的地址为en0 有些分配的en1
#define IOS_WIFI2 @”en2″
#define IOS_WIFI1 @”en1″
#define IOS_WIFI @”en0″
//#define IOS_* @”utun0″ *很少用到可以注释
#define IP_ADDR_IPv4 @”ipv4″
#define IP_ADDR_IPv6 @”ipv6″
二.方法实现

//获取设备当前网络IP地址(是获取IPv4 还是 IPv6)
– (NSString *)getIPAddress:(BOOL)preferIPv4
{
//从字典中按顺序查询 查询到不为空即停止(顺序为4G(3G)、Wi-Fi、局域网)
NSArray *searchArray = preferIPv4 ?
@[ /*IOS_* @”/” IP_ADDR_IPv4, IOS_* @”/” IP_ADDR_IPv6,*/ IOS_CELLULAR @”/” IP_ADDR_IPv4, IOS_WIFI2 @”/” IP_ADDR_IPv4, IOS_WIFI1 @”/” IP_ADDR_IPv4, IOS_WIFI @”/” IP_ADDR_IPv4] :
@[ /*IOS_* @”/” IP_ADDR_IPv6, IOS_* @”/” IP_ADDR_IPv4,*/ IOS_CELLULAR @”/” IP_ADDR_IPv6, IOS_WIFI2 @”/” IP_ADDR_IPv6, IOS_WIFI1 @”/” IP_ADDR_IPv6, IOS_WIFI @”/” IP_ADDR_IPv6] ;

NSDictionary *addresses = [self getIPAddresses];
NSLog(@”addresses: %@”, addresses);

__block NSString *address;
[searchArray enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL *stop)
{
address = addresses[key];
if(address) *stop = YES;
} ];
return address ? address : @”0.0.0.0″;
}

//获取所有相关IP信息
– (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;
}
//lo0         本地ip, 127.0.0.1

//en0        局域网ip, 192.168.1.23

//pdp_ip0    WWAN地址,即3G ip,

//bridge0    桥接、热点ip,172.20.10.1

77. 组合(JS实现)

77. 组合(JS实现)

1 题目
给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。

示例:

输入: n = 4, k = 2
输出:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]

2 思路
这道题的思路主要深度优先构造一棵树,由于生成的组合无关顺序,因此每层循环的初始值都是父节点的值+1

3代码
/**
* @param {number} n
* @param {number} k
* @return {number[][]}
*/
var combine = function(n, k) {
if (k === 0) return [];

const result = [];

for (let i = 1; i <= n; i++) {
d([i], k – 1, i);
}

function d(arr, depth, begin) {
if (depth === 0) {
result.push(arr);
return;
}

for (let i = begin + 1; i <= n; i++) {
let temp = arr.slice();
temp.push(i);
d(temp, depth – 1, i);
}
}

return result;
};

9. 单词搜索(JS实现)

9. 单词搜索(JS实现)

1 题目
给定一个二维网格和一个单词,找出该单词是否存在于网格中。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用
示例:
board =
[
[‘A’,‘B’,‘C’,‘E’],
[‘S’,‘F’,‘C’,‘S’],
[‘A’,‘D’,‘E’,‘E’]
]
给定 word = “ABCCED”, 返回 true
给定 word = “SEE”, 返回 true
给定 word = “ABCB”, 返回 false
提示:
board 和 word 中只包含大写和小写英文字母。
1 <= board.length <= 200
1 <= board[i].length <= 200
1 <= word.length <= 10^3

2 思路
这道题的思路主要还是考察深度优先遍历 + 回溯, 主要思路就是遍历二维数组每个元素,当发现元素和目标单词的首字母相同时,就进入递归,沿该元素的四个方向进行依次查找,用一个散列表标记已经访问过的位置,在递归过程中,若找到则返回true,若未找到,则递归回来时,要重置散列表状态

3代码
/**
* @param {character[][]} board
* @param {string} word
* @return {boolean}
*/
var exist = function(board, word) {

let m = board.length;
let n = board[0].length;

if (m * n < word.length) return false;

let map = {};

for (let i=0; i<m; i++) {
for (let j=0; j<n; j++) {
if (board[i][j] === word[0]) {
if (search(i,j,0)) return true;
}
}
}

return false;

function search(i, j, nextIndex) {
//单词已遍历完,则表明已经找到了
if (nextIndex === word.length) {
return true;
};

let key = `${i}-${j}`;
//数组越界、已经访问过、对应字母不相等时直接返回false
if (i < 0 || j < 0 || i >= m || j >=n || map[key] || board[i][j] !== word[nextIndex]) {
return false;
}

map[key] = true;

let success = search(i+1, j, nextIndex + 1) //沿4个方向寻找
|| search(i-1, j, nextIndex + 1)
|| search(i, j+1, nextIndex + 1)
|| search(i, j-1, nextIndex + 1);

map[key] = success; //失败时要重置位置状态

return success;
}
};

81. 搜索旋转排序数组 II(JS实现)

81. 搜索旋转排序数组 II(JS实现)

1 题目
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [0,0,1,2,2,5,6] 可能变为 [2,5,6,0,0,1,2] )。
编写一个函数来判断给定的目标值是否存在于数组中。若存在返回 true,否则返回 false。
示例 1:
输入: nums = [2,5,6,0,0,1,2], target = 0
输出: true
示例 2:
输入: nums = [2,5,6,0,0,1,2], target = 3
输出: false

2 思路
这道题思路还是主要判断mid和nums[0]的大小,来确定数组的哪部分是有序数组,再判断target是在有序数组内,还是外部,进行范围的逐步缩小,值得注意的是,若有重复元素,例如[1,3,1,1,1],此时mid=2时,其与num[0]大小相等,无法直接判断mid在左边的有序数组还是右边的有序数组,此时就需要遍历mid后面的数,若发现有任何与nums[0]不相等的数,那么mid就在左边

3代码
/**
* @param {number[]} nums
* @param {number} target
* @return {boolean}
*/
var search = function(nums, target) {
if (nums.length === 0) return false;
if (nums[0] === target || nums[nums.length – 1] === target) return true;

let low = 0;
let high = nums.length – 1;

while (low <= high) {
let mid = Math.floor((low + high) / 2);

if (nums[mid] === target) {
return true;
}

if (nums[mid] > nums[0]) {
if (target < nums[mid] && target > nums[0]) {
high = mid – 1;
} else {
low = mid + 1;
}
} else if (nums[mid] < nums[0]) {
if (target > nums[mid] && target < nums[0]) {
low = mid + 1;
} else {
high = mid – 1;
}
} else { //当无法直接判断mid位置时,遍历mid后面的数
let tempIndex = mid + 1;
let isLeft = false;
while (tempIndex < nums.length) {
if (nums[tempIndex++] !== nums[0]) { //发现不等于nums[0]的数,则mid一定在左边
isLeft = true;
}
}

if (isLeft) {
low = mid + 1;
} else {
high = mid – 1;
}
}
}

return false;
};

82. 删除排序链表中的重复元素 II(JS实现)

82. 删除排序链表中的重复元素 II(JS实现)

1 题目
给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。
示例 1:
输入: 1->2->3->3->4->4->5
输出: 1->2->5
示例 2:
输入: 1->1->1->2->3
输出: 2->3

2 思路
这道题的思路主要思路还是双指针,prev指针上一个元素,head指针遍历每个元素,当prev和head指向的元素值不同时,两者同时向后移动,当prev和head指向的元素值相同时,此时说明出现重复元素,那么prev指针不动,head指针继续向后搜索直到找到不同的元素,然后修改指针指向,将重复元素段移除。

3代码
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var deleteDuplicates = function(head) {
if (!head || !head.next) return head;

let linkHead = head;
let prev = head;
head.prev = null;
let flag = false;

while (head.next) {
head.next.prev = head;
head = head.next;
if (head.val === prev.val) {
if (!flag) {
flag = true; //打开开关,开始寻找下一个值不同的元素
};
} else {
if (flag) { //找到不同值的元素,修改指针
if (!prev.prev) { //如果重复的是列表头元素
linkHead = head;
head.prev = null;
} else { //如果重复的元素位于列表中间
prev.prev.next = head;
head.prev = prev.prev;
}
flag = false; //关闭开关,继续寻找相同的元素
}
prev = head;
}
}

if (flag) { //如果重复元素段在链表尾部
if (!prev.prev) {
linkHead = null;
} else {
prev.prev.next = null;
}
}

return linkHead;
};

88. 合并两个有序数组(JS实现)

88. 合并两个有序数组(JS实现)

1 题目
给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组
说明:
初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。
你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
示例:
输入:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3
输出: [1,2,2,3,5,6]

2 思路
这道题思路主要是考察如何用O(1)的存储空间完成替换,我的代码是O(n)的,看了题解,才知道,我们可以从尾部向前逐渐填充,从大到小进行填充

3代码
/**
* @param {number[]} nums1
* @param {number} m
* @param {number[]} nums2
* @param {number} n
* @return {void} Do not return anything, modify nums1 in-place instead.
*/
var merge = function(nums1, m, nums2, n) {
if (n === 0) return nums1;
const result = [];
let i=0, j=0;
while (j < n || i < m) {
if (i < m && nums1[i] <= nums2[j] || j >= n) {
result.push(nums1[i]);
i++;
} else {
result.push(nums2[j]);
j++
}
}

let len = m + n;

for (let i=0; i<len;i++) {
nums1[i] = result[i];
}
};

86. 分隔链表(JS实现)

86. 分隔链表(JS实现)

1 题目
给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。
你应当保留两个分区中每个节点的初始相对位置。
示例:
输入: head = 1->4->3->2->5->2, x = 3
输出: 1->2->2->4->3->5

2 思路
这道题思路主要是新建两个列表,将大于或等于目标的元素、以及小于目标的元素分开,然后再将两个列表连接起来

3代码
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @param {number} x
* @return {ListNode}
*/
var partition = function(head, x) {
if (!head || !head.next) return head;

let smallLink; //小于target的元素列表头
let bigLink; //比大于或等于target的元素列表头
let bigHead;
let prev;

while(head) {
if (head.val >= x) {
if (!bigLink) {
bigLink = head;
} else {
bigHead.next = head;
}
bigHead = head;
} else {
if (prev) {
prev.next = head;
} else {
smallLink = head;
}
prev = head;
}
head = head.next;
}

if (!prev) return bigLink; //全部元素都大于或相等target
if (!bigLink) return smallLink; //全部元素都小于target
prev.next = bigLink; //将大于列表接在小于列表后面
bigHead.next = null;
return smallLink;
};

友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速