「这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战」
为什么需要埋点?
- 在业务的体量达到一定的程度的时候, 这些用户数据就很有分析和研究的必要性了, 可以挖掘出来很多潜在的价值.
- 就算业务是在初期的时候, 收集统计用户数据也会对业务的更新与迭代带来一些新的方向, 而不是盲目的扩展一些没必要的功能.
- 分析用户的行为, 对于程序上的提升也是有的, 比较埋点也是一门技术, 还是值得研究的.
埋点方案
-
代码埋点
代码埋点应该是程序员用的最多, 也是最简单的一种埋点方式, 这种方式就需要将埋点的代码写入业务逻辑之中, 这样的好处是埋点的代码有很高的自由度, 缺点是工作量会变的很大
-
全埋点
全埋点应该是也很流行的一种埋点方式了, 对技术的要求还是有一点的, 好处就是可以全局性的埋点, 省去了很多工作量, 缺点也很明显, 如果对某一块的功能需要很详细的统计, 那么就会很有局限性了
-
可视化埋点
可视化埋点也称作无码埋点, 简单来说就是运营人员通过后台管理页面上的操作, 来实现埋点功能, 这对技术来说有一定的挑战性, 好处就是简化埋点的逻辑性, 运营人员使用更便捷, 缺点和全埋点有点类似, 就是有一些需要APP动态的数据是统计不到的.
总结
三种埋点方式各有优劣, 在实际业务中更应该三种方式综合使用, 将各自的长处结合进行了互补, 这样对业务的提成更大, 当然在实现三方埋点方式的同时也会对自身技术有一定的提升, 当前我也在埋点工作进行中, 如果各位有好的想法, 请评论区告诉我, 不胜感激!
附件
#include <ifaddrs.h>
#include <sys/stat.h>
#include <sys/mount.h>
#import <sys/utsname.h>
#import <Security/Security.h>
/// 设备IP
+ (NSString *)ip {
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
NSMutableArray *ips = [NSMutableArray array];
int BUFFERSIZE = 4096;
struct ifconf ifc;
char buffer[BUFFERSIZE], *ptr, lastname[IFNAMSIZ], *cptr;
struct ifreq *ifr, ifrcopy;
ifc.ifc_len = BUFFERSIZE;
ifc.ifc_buf = buffer;
if (ioctl(sockfd, SIOCGIFCONF, &ifc) >= 0) {
for (ptr = buffer; ptr < buffer + ifc.ifc_len; ){
ifr = (struct ifreq *)ptr;
int len = sizeof(struct sockaddr);
if (ifr->ifr_addr.sa_len > len) {
len = ifr->ifr_addr.sa_len;
}
ptr += sizeof(ifr->ifr_name) + len;
if (ifr->ifr_addr.sa_family != AF_INET) continue;
if ((cptr = (char *)strchr(ifr->ifr_name, ':')) != NULL) *cptr = 0;
if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0) continue;
memcpy(lastname, ifr->ifr_name, IFNAMSIZ);
ifrcopy = *ifr;
ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy);
if ((ifrcopy.ifr_flags & IFF_UP) == 0) continue;
NSString *ip = [NSString stringWithFormat:@"%s", inet_ntoa(((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr)];
[ips addObject:ip];
}
}
close(sockfd);
NSString *deviceIP = @"";
for (int i = 0; i < ips.count; i++) {
if (ips.count > 0) {
deviceIP = [NSString stringWithFormat:@"%@",ips.lastObject];
}
}
return deviceIP;
}