Appium+python自動化(四十一)-Appium自動化測試框架綜合實踐 – 即將落下帷幕(超詳解)

1.簡介

  今天我們緊接着上一篇繼續分享Appium自動化測試框架綜合實踐 – 代碼實現。到今天為止,大功即將告成;框架所需要的代碼實現都基本完成。

2.data數據封裝

2.1使用背景

在實際項目過程中,我們的數據可能是存儲在一個數據文件中,如txt,excel、csv文件類型。我們可以封裝一些方法來讀取文件中的數據來實現數據驅動。

2.2案例

將測試賬號存儲在account.csv文件,內容如下:

account.csv

hg2018

hg2018

hg2019

zxw2019

666

222

參考代碼

2.3enumerate()簡介

enumerate()是python的內置函數

  • enumerate在字典上是枚舉、列舉的意思
  • 對於一個可迭代的(iterable)/可遍歷的對象(如列表、字符串),enumerate將其組成一個索引序列,利用它可以同時獲得索引和值
  • enumerate多用於在for循環中得到計數。

2.4enumerate()使用

如果對一個列表,既要遍歷索引又要遍曆元素時,首先可以這樣寫:

參考代碼
list = ["", "", "一個", "測試","數據"]

for i in range(len(list)):

    print(i,list[i])

上述方法有些累贅,利用enumerate()會更加直接和優美:

參考代碼
list1 = ["", "", "一個", "測試","數據"]

for index, item in enumerate(list1):

        print(index,item)

3.數據讀取方法封裝

  數據讀取方法也屬於公共方法,這裏我們首先實現一下,然後將其封裝到裡邊即可。

3.1數據讀取方法實現的參考代碼

import csv


     def get_csv_data(csv_file,line):

        with open(csv_file, 'r', encoding='utf-8-sig') as file:

            reader=csv.reader(file)

            for index, row in enumerate(reader,1):

                if index == line:

                    return row

 

    csv_file='../data/account.csv'

    data=get_csv_data(csv_file,3)

    print(data)

3.2封裝

將其封裝在公共方法中,在其他地方用到的時候,直接導入調用即可。

4.utf-8與utf-8-sig兩種編碼格式的區別

UTF-8以字節為編碼單元,它的字節順序在所有系統中都是一樣的,沒有字節序的問題,也因此它實際上並不需要BOM(“ByteOrder Mark”)。但是UTF-8 with BOM即utf-8-sig需要提供BOM。

5.config文件配置

各種配置文件都放在這個目錄下。

5.1日誌文件配置 

主要是一些日誌信息的配置。

log.config

 參考代碼
[loggers]
keys=root,infoLogger

[logger_root]
level=DEBUG
handlers=consoleHandler,fileHandler

[logger_infoLogger]
handlers=consoleHandler,fileHandler
qualname=infoLogger
propagate=0

[handlers]
keys=consoleHandler,fileHandler

[handler_consoleHandler]
class=StreamHandler
level=INFO
formatter=form02
args=(sys.stdout,)

[handler_fileHandler]
class=FileHandler
level=INFO
formatter=form01
args=('../logs/runlog.log', 'a')

[formatters]
keys=form01,form02

[formatter_form01]
format=%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s

[formatter_form02]
format=%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s

6.測試用例封裝

這裏宏哥舉例給小夥伴們演示:封裝註冊和登錄兩個測試用例。

6.1測試用例執行開始結束操作封裝

測試用例執行開始和結束的封裝,其他模塊用到直接導入,調用即可。

myunit.py

參考代碼
# coding=utf-8
# 1.先設置編碼,utf-8可支持中英文,如上,一般放在第一行

# 2.註釋:包括記錄創建時間,創建人,項目名稱。
'''
Created on 2019-11-20
@author: 北京-宏哥   QQ交流群:707699217
Project:Appium自動化測試框架綜合實踐 - 代碼實現
'''
# 3.導入模塊
import unittest
from kyb_testProject.common.desired_caps import appium_desired
import logging
from time import sleep

class StartEnd(unittest.TestCase):
    def setUp(self):
        logging.info('=====setUp====')
        self.driver=appium_desired()

    def tearDown(self):
        logging.info('====tearDown====')
        sleep(5)
        self.driver.close_app()

6.2註冊用例

開始註冊用例代碼邏輯的實現。

test_register.py

參考代碼
# coding=utf-8
# 1.先設置編碼,utf-8可支持中英文,如上,一般放在第一行

# 2.註釋:包括記錄創建時間,創建人,項目名稱。
'''
Created on 2019-11-20
@author: 北京-宏哥   QQ交流群:707699217
Project:Appium自動化測試框架綜合實踐 - 代碼實現
'''
# 3.導入模塊
from kyb_testProject.common.myunit import StartEnd
from kyb_testProject.businessView.registerView import RegisterView
import logging,random,unittest

class RegisterTest(StartEnd):
    def test_user_register(self):
        logging.info('======test_user_register======')
        r=RegisterView(self.driver)

        username = 'bjhg2019' + 'fly' + str(random.randint(1000, 9000))
        password = 'bjhg2020' + str(random.randint(1000, 9000))
        email = 'bjhg' + str(random.randint(1000, 9000)) + '@163.com'

        self.assertTrue(r.register_action(username,password,email))

if __name__ == '__main__':
    unittest.main()

6.3登錄用例

開始登錄用例代碼邏輯的實現。

test_login.py

參考代碼
# coding=utf-8
# 1.先設置編碼,utf-8可支持中英文,如上,一般放在第一行

# 2.註釋:包括記錄創建時間,創建人,項目名稱。
'''
Created on 2019-11-13
@author: 北京-宏哥   QQ交流群:707699217
Project:Appium自動化測試框架綜合實踐 - 代碼實現
'''
# 3.導入模塊
from kyb_testProject.common.myunit import StartEnd
from kyb_testProject.businessView.loginView import LoginView
import unittest
import logging

class TestLogin(StartEnd):
    csv_file='../data/account.csv'

    @unittest.skip('test_login_zxw2018')
    def test_login_zxw2018(self):
        logging.info('======test_login_zxw2018=====')
        l=LoginView(self.driver)
        data=l.get_csv_data(self.csv_file,2)

        l.login_action(data[0],data[1])
        self.assertTrue(l.check_loginStatus())

    # @unittest.skip('skip test_login_zxw2017')
    def test_login_zxw2017(self):
        logging.info('======test_login_zxw2017=====')
        l=LoginView(self.driver)
        data = l.get_csv_data(self.csv_file, 1)

        l.login_action(data[0], data[1])
        self.assertTrue(l.check_loginStatus())

    @unittest.skip('test_login_error')
    def test_login_error(self):
        logging.info('======test_login_error=====')
        l = LoginView(self.driver)
        data = l.get_csv_data(self.csv_file, 3)

        l.login_action(data[0], data[1])
        self.assertTrue(l.check_loginStatus(),msg='login fail!')

if __name__ == '__main__':
    unittest.main()

7.小結

到此,Appium自動化測試框架就差下一篇就全部完成了,聰明的你都懂了嗎???嘿嘿!慢慢地來吧。

下節預告

下一篇,講解執行測試用例,生成測試報告,以及自動化平台,請關注宏哥,敬請期待!!!

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

台灣海運大陸貨務運送流程

兩岸物流進出口一站式服務

保護黃石國家公園周遭灰熊 美法官出手

摘錄自2018年9月25日中央社報導

美國聯邦法官今天(25日)下令將棲息在黃石國家公園內部及周遭的灰熊,重新列入瀕臨滅絕物種保護法(ESA)保護名單,阻擋40年多來首度開放在這個地區獵捕灰熊的計畫。

美國蒙大拿州密蘇拉(Missoula)聯邦地區法官克里斯坦森(Dana Christensen)與環保人士及美國原住民站在同一陣線,駁回美國魚類暨野生動物管理局(U.S. Fish and Wildlife Service)將灰熊從瀕危物種名單除名的決定。

環保人士主張,根據瀕臨滅絕物種保護法,對這些灰熊與蒙大拿州和下48州(Lower 48)的其他灰熊族群採取差別待遇,是生物學上靠不住且非法行為,法官也同意這類說法。

環保人士說,儘管灰熊數量有所回升,倘若沒有受到聯邦持續保護,牠們的復育情況就會受到影響。此外,氣候變遷導致灰熊食物供給出現變化和人為死亡率高,也對灰熊生存構成威脅。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

台灣海運大陸貨務運送流程

兩岸物流進出口一站式服務

騰勢2016年年底前將在中國建650個專屬充電樁

4月25日,騰勢在北京車展發佈全新的騰勢新動生活解決方案,宣佈在2016年年底前在全國建設650個騰勢專屬公共充電樁。針對有長途出行的車主,騰勢還將提供50%的折扣價格租用梅賽德斯-賓士C級轎車的福利。

為解決車主充電難的問題,騰勢將進一步在北上廣深等城市的大型商場、酒店、寫字樓和機場等交通樞紐建設騰勢專屬公共充電樁,預計2016年年底前在全國建設650個騰勢專屬公共充電樁。與此同時,騰勢服務網路在2015年擴大到了9個城市13家銷售服務網點,未來將在重點城市開設更多服務網點。

在質保方面,騰勢將為動力電池及關鍵零部件提供8年或15萬公里的保修期,為消費者提供無憂的售後保障服務。另外,騰勢還將開放新技術升級服務,騰勢車主可以進行軟體升級或部件升級。在移動應用方面,騰勢專屬App將提供更為智慧貼心的遠端操控功能,可實現智慧充電控制、車內設備控制、車輛狀態查詢以及一鍵尋車等功能。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

台灣海運大陸貨務運送流程

兩岸物流進出口一站式服務

iOS:應用程序擴展開發之Today擴展(Today Extesnsion)

一、簡介

iOS應用程序擴展是蘋果在iOS8推出的一個新特性,可以將自定義的功能和內容擴展到應用程序之外,在之後又經過不斷地優化和更新,已經成為開發中不可或缺的功能之一。擴展也是一個Target項目,它運行在主機應用程序上,可以與主機應用程序實現資源共享,和宿主應用程序的Target項目是彼此獨立的。系統提供的擴展有很多,Toady擴展就是其中之一,也被成為應用程序插件,它的作用是將今日發生的簡單消息展示在系統的插件界面上。Toady擴展模板名稱為Today Extension。圖1是創建Today擴展,圖2是擴展显示在插件界面上(可以通過點擊Edit來添加或者移除擴展)。 

 

二、創建

按照上圖1的方式創建一個Today Extension的Target后,系統會默認幫我們生成一個TodayViewController控制器類、MainInterface.storyBoard故事板、plist序列化文件,文件結構圖如下:

上圖中紅色圈內和箭頭指向的配置就是系統通過MainInterface.storyBoard幫我們實現了一個基本的Toady插件UI布局,運行后可以直接显示在插件界面上。可是,有的時候開發者並不想使用系統的故事板來構建UI,系統支持自定義的,我們只需要修改plist配置即可。具體的配置是這樣的:

[1] 將NSExtensionMainStoryboard字段刪除;

[2] 添加NSExtensionPrincipalClass字段,修改value為控制器的類名。 

[3] 在TodayViewController中的ViewDidLoad中設置preferredContentSize屬性大小,用來調整widget界面UI的尺寸。

配置如下圖所示:

//設置尺寸
self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 300); 

  

三、分析

TodayViewController類比較簡單,就是一個VC類,它實現了系統提供的一個擴展協議<NCWidgetProviding>,可以在協議方法中實現對擴展的更新和狀態監控。

協議如下,都是可選的,開發者根據需要進行重寫。

//協議
@protocol NCWidgetProviding <NSObject>

@optional

//當數據更新時調用的方法,系統會定期更新擴展
- (void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult result))completionHandler;

//監聽显示模式(寬鬆型、緊奏型)和尺寸的改變,其中寬鬆和緊湊表示的是展開和摺疊狀態, iOS10開始才能使用
- (void)widgetActiveDisplayModeDidChange:(NCWidgetDisplayMode)activeDisplayMode withMaximumSize:(CGSize)maxSize __API_AVAILABLE(ios(10.0));

//設置擴展UI邊距,注意:使用StoryBoard時,若要所見即所得,則這個方法中需要返回UIEdgeInsetsZero; (iOS10 and later 不會再被調用,棄用了)
- (UIEdgeInsets)widgetMarginInsetsForProposedMarginInsets:(UIEdgeInsets)defaultMarginInsets __API_DEPRECATED("This method will not be called on widgets linked against iOS versions 10.0 and later.", ios(8.0, 10.0));

@end
//擴展,都是iOS10開始才能使用
@interface NSExtensionContext (NCWidgetAdditions)

//設置widget摺疊或展開狀態
@property (nonatomic, assign) NCWidgetDisplayMode widgetLargestAvailableDisplayMode __API_AVAILABLE(ios(10.0));

//只讀,widget狀態
@property (nonatomic, assign, readonly) NCWidgetDisplayMode widgetActiveDisplayMode __API_AVAILABLE(ios(10.0));

//獲取widget不同狀態的尺寸
- (CGSize)widgetMaximumSizeForDisplayMode:(NCWidgetDisplayMode)displayMode __API_AVAILABLE(ios(10.0));

@end

 

四、交互

Today擴展是寄宿於主機應用程序上的, TodayViewController又是一個UIViewController類,系統支持Today擴展對UIViewController進行切換。也就是說,蘋果在考慮提供給開發者在對UIViewController中添加各種展示控件這種便利的同時,也相應的提供給開發者通過Today擴展的widget從主機應用程序激活並打開宿主應用程序的機會。不過這個操作必須通過設置並調起scheme來實現。步驟如下:

[1] 配置宿主應用程序的scheme;

[2] 使用擴展的openURL打開宿主應用程序。

交互如下:

//擴展通過scheme打開主宿主應用程序
[self.extensionContext openURL:[NSURL URLWithString:@"MainApp://"] completionHandler:nil];

 

五、數據

既然Today擴展能與宿主應用程序進行交互,那麼肯定就存在數據通信的問題了。擴展與宿主目錄應用程序位於不同的目錄結構中,默認情況下,擴展與宿主應用程序的數據並不共享,代碼也不能復用。例如在宿主目錄應用程序中可能有網絡請求、數據持久化存儲等結構框架,在擴展中不可以直接使用,擴展需要提供自己的網絡請求框架、數據持久化框架等。這些問題蘋果都提供了解決方法,可以通過創建靜態庫的方式實現代碼共享,通過APP Group和Scheme跳轉實現數據共享。這裏主要講一下數據共享。注意:擴展和宿主應用程序的素材文件也是互相獨立的,必須將擴展中的素材添加到擴展Target。

方式一:通過配置scheme跳轉來實現數據共享。可以將傳遞的數據配置到URL中,然後宿主應用程序通過AppDeleagte的代理方法application:openURL:options:獲取數據,不過這個數據傳遞只能是單方向的。

 //打開主應用程序
-(void)openMainApp {
    
//共享數據
    NSString *schemeFormat = @"MainApp://action=openCarema?name=xiayuanquan";
    [self.extensionContext openURL:[NSURL URLWithString:schemeFormat] completionHandler:nil];
}
-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
    
    //從URL獲取共享數據,截取數據
    NSLog(@"---------url = %@---------",url);
    
    return YES;
}

方式二:給擴展的Target和宿主應用程序的Target項目都開啟APP Group,兩者配置相同的appgroupIndentifier標識,分別生成後綴名為.entitlements文件。然後對於小數據推薦使用偏好進行雙向傳遞共享數據,如圖所示。

//共享數據
//使用偏好設置
NSUserDefaults *defalut = [[NSUserDefaults alloc] initWithSuiteName:@"group.xiayuanquan"];
[defalut setObject:@"xiayuanquan" forKey:@"name"];
//從偏好設置獲取共享數據
NSUserDefaults *defalut = [[NSUserDefaults alloc] initWithSuiteName:@"group.xiayuanquan"];
NSString *name1 = [defalut objectForKey:@"name"];
NSLog(@"1------------name1=%@",name1);

方式三:配置跟方式二一樣,不過雙向傳遞共享數據使用文件目錄來實現。

//共享數據
//方式二:使用共享目錄
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *baseURL = [fileManager containerURLForSecurityApplicationGroupIdentifier:@"group.xiayuanquan"];
NSURL *filePath = [baseURL URLByAppendingPathComponent:@"file"];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:@"xiayuanquan" requiringSecureCoding:NO error:nil];
[data writeToURL:filePath atomically:YES];
//從共享目錄獲取共享數據
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *baseURL = [fileManager containerURLForSecurityApplicationGroupIdentifier:@"group.xiayuanquan"];
NSURL *filePath = [baseURL URLByAppendingPathComponent:@"file"];
NSData *data = [NSData dataWithContentsOfURL:filePath];
NSLog(@"2------------data=%@",data);

 

六、適配

從iOS10開始,蘋果提供了NCWidgetDisplayMode展示模式,通過設置該模式來支持對widget進行摺疊和展開。在這裏,preferredContentSize就用到了。這個是用來設置widget的尺寸的。蘋果對widget的尺寸有自己的標準,width為maxSize.width,height取值範圍[110, maxSize.height]。這個maxSize可以在擴展協議<NCWidgetProviding>的協議方法也即widgetActiveDisplayModeDidChange:withMaximumSize中獲取:,可以發現每一種機型maxSize不一樣。

// 6s模擬器下:
// NCWidgetDisplayModeCompact模式下:{359.000000, 110.000000}
// NCWidgetDisplayModeExpanded模式下:{359.000000, 528.000000}

// 8 plus模擬器下:
// NCWidgetDisplayModeCompact模式下:{304.000000, 110.000000}
// NCWidgetDisplayModeExpanded模式下:{304.000000, 616.000000}

摺疊狀態:widget的高為110,此時設置preferredContentSize無效; 

展開狀態:widget的高為開發者設置的preferredContentSize.height,但是如果preferredContentSize.height>maxSize.height,此時取值為maxSize.height。 

適配iOS10,默認支持展開,設置如下: 

//設置widget默認為可以展開,此時處於摺疊狀態
#ifdef __IPHONE_10_0 //適配iOS10
   self.extensionContext.widgetLargestAvailableDisplayMode = NCWidgetDisplayModeExpanded;
#endif

 

七、範例

【去掉MainInterface.storyBoard,採用純代碼實現】

1、宿主應用程序AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    
    //存儲共享數據
    //方式二:使用偏好設置
    NSUserDefaults *defalut = [[NSUserDefaults alloc] initWithSuiteName:@"group.xiayuanquan"];
    [defalut setObject:@"xiayuanquan" forKey:@"name"];
    
    //存儲共享數據
    //方式三:使用共享目錄
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSURL *baseURL = [fileManager containerURLForSecurityApplicationGroupIdentifier:@"group.xiayuanquan"];
    NSURL *filePath = [baseURL URLByAppendingPathComponent:@"file"];
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:@"xiayuanquan" requiringSecureCoding:NO error:nil];
    [data writeToURL:filePath atomically:YES];
    
    return YES;
}

-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
    
    //方式一:從URL獲取共享數據,例如參數
    NSLog(@"---------url = %@---------",url);
    
    return YES;
    
}

2、Widget擴展TodayViewController

//
//  TodayViewController.m
//  TodayExtension
//  Created by 夏遠全 on 2019/11/19.
//

#import "TodayViewController.h"
#import <NotificationCenter/NotificationCenter.h>

@interface TodayViewController () <NCWidgetProviding>

@end

@implementation TodayViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self config];
    [self createUI];
    [self fecthData];
}

//配置
-(void)config {
    
    self.view.backgroundColor = [UIColor lightGrayColor]; //widget背景色為灰色
    self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 300); //widget尺寸大小, 寬度實際取maxSize,width,高度[110, maxSize.height]
    
    //設置widget默認為可以展開,此時處於摺疊狀態
    #ifdef __IPHONE_10_0 //適配iOS10
        self.extensionContext.widgetLargestAvailableDisplayMode = NCWidgetDisplayModeExpanded;
    #endif
    
}

//創建UI
-(void)createUI {
    
    CGFloat width = self.view.frame.size.width;
    CGFloat btnWidth = 100;
    UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake((width-btnWidth)/2, 0, btnWidth, 40)];
    button.backgroundColor = [UIColor greenColor];
    [button setTitle:@"OpenAPP" forState:UIControlStateNormal];
    [button setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
    [button addTarget:self action:@selector(openMainApp) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button];
}

//打開主應用程序
-(void)openMainApp {
    
    //傳遞共享數據
    //方式一:參數傳遞
    NSString *schemeFormat = @"MainApp://action=openCarema?name=xiayuanquan";
    [self.extensionContext openURL:[NSURL URLWithString:schemeFormat] completionHandler:nil];
    
}

//獲取共享數據
-(void)fecthData {
    
    //方式二:從偏好設置獲取共享數據
    NSUserDefaults *defalut = [[NSUserDefaults alloc] initWithSuiteName:@"group.xiayuanquan"];
    NSString *name1 = [defalut objectForKey:@"name"];
    NSLog(@"1------------name1=%@",name1);
    
    //方式三:從共享目錄獲取共享數據
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSURL *baseURL = [fileManager containerURLForSecurityApplicationGroupIdentifier:@"group.xiayuanquan"];
    NSURL *filePath = [baseURL URLByAppendingPathComponent:@"file"];
    NSData *data = [NSData dataWithContentsOfURL:filePath];
    NSLog(@"2------------data=%@",data);
}

//當數據更新時調用的方法,系統會定期更新擴展
- (void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult))completionHandler {
    
    //獲取共享的數據,根據判斷回調對應的block
    //NCUpdateResultNewData,
    //NCUpdateResultNoData,
    //NCUpdateResultFailed
    
    completionHandler(NCUpdateResultNoData);
}


//監聽显示模式(寬鬆型、緊奏型)和尺寸的改變
//NCWidgetDisplayModeCompact :  摺疊
//NCWidgetDisplayModeExpanded : 展開
- (void)widgetActiveDisplayModeDidChange:(NCWidgetDisplayMode)activeDisplayMode withMaximumSize:(CGSize)maxSize {
    
    //maxSize:
    //雖說是最大的Size,但蘋果還是把Widget的高度範圍限制在了[110 ~ maxSize]之間
    //如果設置高度小於110,那麼default = 110;
    //如果設置高度大於開發者設置的preferredContentSize.Heiget,那麼default = maxSize;
    //摺疊狀態下,蘋果將高度固定為110,這個時候設置preferredContentSize屬性無效。
    NSLog(@"width = %lf-------height = %lf",maxSize.width,maxSize.height);
    
    //可以更改狀態
    if (activeDisplayMode == NCWidgetDisplayModeExpanded) {
        self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 300);
    }
    else{
        self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 100);
    }
}

//設置擴展UI邊距,注意:使用StoryBoard時,若要所見即所得,則這個方法中需要返回UIEdgeInsetsZero; (iOS10 and later 不會再被調用)
//- (UIEdgeInsets)widgetMarginInsetsForProposedMarginInsets:(UIEdgeInsets)defaultMarginInsets {
//    return UIEdgeInsetsZero;
//}

@end

3、打印和gif

2019-11-20 16:22:31.074596+0800 TodayExtension[29668:1132736] 1------------name1=xiayuanquan
2019-11-20 16:22:31.234435+0800 TodayExtension[29668:1132736] 2------------data={length = 149, bytes = 0x62706c69 73743030 d4010203 04050607 ... 00000000 00000068 }
2019-11-20 16:22:31.234970+0800 TodayExtension[29668:1132736] maxSize.width = 359.000000-------maxSize.height = 110.000000 //摺疊
2019-11-20 16:22:38.117764+0800 TodayExtension[29668:1132736] maxSize.width = 359.000000-------maxSize.height = 528.000000 //展開

 

 

 

 

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

台灣海運大陸貨務運送流程

兩岸物流進出口一站式服務

特斯拉 Model 3 大賣,電動車朝向榮景仍逢瓶頸?

電動車大廠特斯拉(Tesla)新款房車 Model 3 的預購量超出預期,市場上開始有許多分析師發言,有的說電動車即將取代傳統的汽車;有人甚至認為應該忘掉正面臨創新瓶頸的 Apple 執行長 Tim Cook,將目光移向 Tesla 創辦人 Elon Musk,稱他是偉大夢想及實踐家,其能力傲視全球的企業家,然而事實真是如此嗎?   電動車大廠特斯拉(Tesla)新款房車 Model 3 於 2016 年 3 月展開全球預售,售價 3.5 萬美元(約新台幣 110 萬元),買主只需要預付 1,000 美元(約新台幣 3 萬元)就可以訂車,此舉立刻引起市場震撼,吸引大批車迷排隊預購,光是在一天內便湧入 11 萬筆訂單,首周預購就超過 32 萬筆。  
暗藏玄機的預購書   仔細看看 Tesla 的預購合約書(其實這算不上合約書只是預購同意書而已),就可以看出到底為什麼大家會一窩蜂的搶訂。Tesla 的預購條件很簡單,任何人想要訂購 Model 3,只需要支付 1,000 美元的訂金,而且任何時間如果後悔都可以全部退還,換句話說,對消費者而言沒有任何風險;同樣的,Tesla 在文件裡也沒有寫明交車時間,檯面上說 2017 年底是「預定」交車時間,但如果交不出來或延後到 2018 甚至 2020 年,也沒有任何罰則。   放眼望去,哪家車廠會訂出這種購車合約?這樣的操作 Tesla 的目的為何?   Tesla 成立於 2003 年,到現在已經超過 12 年了,它是第一家把電動車成功推到全球市場的公司,讓電動車與高級車畫上等號,吸引到高收入客戶。Tesla 帶給人們對於未來汽車的夢想,進而推升了它的高股價,甚至比大部分賺錢的公司還要高出十幾、二十倍。美國汽車在 2015 年銷售創下歷來最佳紀錄,但福特(Ford)和通用(GM)等汽車業者股票卻大跌,股價本益比僅 5~7 倍,而 Tesla 卻能在持續虧損下,過去 3 年漲了將近 400%,比標普 500 指數與其他傳統車商要好得多。   2013 年 Tesla 進軍中國,希望拿下繼美國之後第二個龐大的電動車市場,甚至 Musk 曾揚言「中國市場很快就超越美國成為 Tesla 電動車的第一大市場」。但是 Tesla 一直無法突破瓶頸,2015 第三季結束的交車總量只有 3,025 輛,不到全球交付量 50,580 輛的十分之一。目前看起來 Tesla 要搶下中國市場,還有一段很漫長的路要走,除了中國政策的問題,無補貼、高關稅、被排除在國家標準之外,各國車廠也紛紛摩拳擦掌,準備搶食中國電動車的市場大餅。   長期的虧損也讓華爾街的分析師對 Musk 的耐心慢慢消磨殆盡,除了進軍中國沒有交出漂亮的成績單,Tesla 還是延遲交貨的慣犯,從首款電動車 Roadster、次代 Model S 到電動休旅車 Model X,從未準時交貨,Model X 甚至還延遲超過一年半。  
先求資金到位以利發展   雖然 Model 3 被定位成平價車款,它的設計沒有其他現有車款 Model S 與 Model X 複雜,但是能不能準時交貨並不是 Tesla 說了算,還是得仰賴後端生產零件的供應商是否如期交貨。Tesla 也預見可能發生的狀況,已先幫自己找替代方案,在加州費利蒙〈Fremont〉的生產工廠自行製造所需零件。   另外電池材料來源與價格,也是必須考量的因素。電動車使用鋰電池做為動力來源,除了電池本身必須非常嚴謹安全,當需求量大增時也會推升鋰材料的價格,因此未必能夠因為數量大幅成長而使價格大幅下降。2015 年第四季開始,就發生鋰電池正極材料所需的碳酸鋰缺貨,導致鋰電池廠商無法擴產,碳酸鋰每噸的市場價格也從 2013 年 9 月的 5 萬人民幣上漲到 12 萬人民幣。Model 3 都還沒做出來碳酸鋰價格就開始上漲了!   大量的電動車充電需求也代表電力基礎建設必須更新,這也不是短時間內可以做到的事,而 Tesla 垂涎欲滴的中國市場,雖然計劃擴建充電站,卻只支援中國國內的電動車品牌。超級充電站不相容、充電難的問題將進一步加劇 Tesla 的困境。   Tesla 可以在一周內拿到超過 30 萬的消費者預購同意書,並不代表真的能做到這麼多生意,連 Musk 都對 2017 年是否能順利上市不太有信心,他在發表會上說「Model 3 不太可能如期交車」。而當 2017 年時間一到,如果交不出令人滿意的 Model 3,或是首購的客戶有了不好的評價,到時候退訂的浪潮也會很兇猛的。   因此 Tesla「不訂出逾期的賠償條款」,對消費者和他們而言可謂雙贏策略。對消費者來說沒有任何風險,還可以過過 Tesla 車主的癮,於是消費者瘋狂訂購;對 Tesla 來說,可以向華爾街的分析師與市場上的投資人證明 Tesla 的潛在客戶非常龐大,有利於向資本市場募資吸金,等於是先拿到了訂單,再回頭過來向市場募資,一箭雙鵰。  
交車不順恐不利後續發展   而 2017 年是否真的能交車呢?是否真的能賣到 3.5 萬美元這麼低的價格?那是以後的事了,只要資金到位,未來要怎麼做都好說;缺少了資金和市場信心,別談以後了,Tesla 可能就要面臨後勢不振的壓力了。   Musk 在資本市場上為投資人,也為新創公司建立一個遠大的夢想並沒有什麼不對,而且手法高明了許多,但 Musk 真的能把 Cook 比下嗎?蘋果一直以來都是腳踏實地在創新,東西真的做得好賣得好,而賺大錢富可敵國才讓股票大漲的,當然做得再好的產品也會遭遇瓶頸,但是這畢竟靠的是腳踏實地的「本益比」,而不是虛幻不實的「本夢比」。   在商場上投機的確是會成功的,有時候成功的機率還不低,但是如果我們過度推崇投機,把投機說成是偉大夢想及實踐能力傲視全球,那對腳踏實地在創新的 Steven Jobs 和 Cook 也太不公平了!   (首圖來源: CC BY 2.0)   (本文授權轉載自《》─〈〉)

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

台灣海運大陸貨務運送流程

兩岸物流進出口一站式服務

除了獲取 MAC 地址還能幹啥

        以前寫過一篇《》的文章,文章的地址是:https://www.cnblogs.com/tosser/p/9022187.html,我當時使用 OCX 來實現,可是 OCX 只支持 IE 瀏覽器,後來在往上找了一個 Chrome 的擴展,也解決了該問題。不過,總覺得無論使用 OCX 還是使用 Chrome 的擴展,都是瀏覽器相關的,並不通用。後來,使用 Socket 寫了一個簡單的 DEMO,用來模擬 HTTP 服務器,然後使用 Ajax 進行通信,問題解決了。也不再是瀏覽器相關了。

 

Web 頁面獲取 MAC 地址的設計思路

        Web 頁面獲取 MAC 地址的設計思路是比較簡單的,只需要在本地模擬一個 HTTP 服務器,然後讓 Web 頁面通過 Ajax 來請求 HTTP 服務器,HTTP 服務器直接返回本機的 MAC 地址就可以了。

        具體流程如下圖:

 

        流程圖非常的清楚,主要就是 HostServer 和 Ajax 的通信,這樣就可以得到 MAC 地址,然後通過 DOM 操作,即可把 MAC 地址寫入到 input 框中。這樣,就可以和用戶名、密碼一起提交給服務器進行驗證了。

 

 

 

除了獲取 MAC 地址還能幹啥

 

       之前做過一個物流提貨的項目,涉及到一些硬件設備,包括:小票打印機、刷卡器(身份證、銀聯卡)、進幣器、密碼数字鍵盤等。這些設備、電腦主機和显示器在一個類似 ATM 機那樣的機櫃中(其實就是 ATM 機的設備,本身這套東西就是銀行提供的)。

 

       操作這些硬件的接口廠家提供了一個 OCX,而整個項目是 B/S 架構的。那麼,在客戶端想要操作這些硬件,就要調用 OCX,而 OCX 只能在 IE 瀏覽器下使用(Chrome、FireFox 是不支持 OCX 的)。眾所周知,IE 對 Web 並不友好,但是如何又能在不使用 IE 的情況下,又去調用 OCX 來完成操作硬件的功能呢?那麼就是我們上面的方法了。

 

       簡單的描述一下,就不貼圖了。

 

       在終端上放一個 HostServer 用來接受頁面中 Ajax 的請求,並根據請求去調用 OCX 中相應的功能,把 OCX 的返回信息,再以 Json 的格式返回給 Ajax 即可。

 

       這樣,把 瀏覽器 和 OCX 文件進行了分離,中間加入了一個 HostServer,頁面 和 OCX 的通信通過了 HostServer,那麼以後如果接口是 DLL 文件,也可以通過 HostServer 來進行完成,當然,還可以完成更多的功能。

 

 

 

總結

        其實整個獲取 MAC 地址的功能,對於登錄頁面而言是一個服務端,它在本地是一個可執行的程序,那麼它和普通的 EXE 文件是沒有區別的,那麼它能完成的功能其實遠遠不是獲取一個 MAC 地址的功能,對於上面的例子來說,把服務的提供者和使用者進行了分離,而且針對於本機的擴展也十分的方便了。當然,如果你願意的話,可以讓 HostServer 充當客戶端直接和後端的服務器進行通信而不通過瀏覽器,這樣是不是還能做一些讓用戶沒有感知的事情?

 

 

我的微信公眾號:“碼農UP2U”

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

台灣海運大陸貨務運送流程

兩岸物流進出口一站式服務

asp.net core 自定義 Policy 替換 AllowAnonymous 的行為

asp.net core 自定義 Policy 替換 AllowAnonymous 的行為

Intro

最近對我們的服務進行了改造,原本內部服務在內部可以匿名調用,現在增加了限制,通過 identity server 來管理 api 和 client,網關和需要訪問api的客戶端或api服務相互調用通過 client_credencial 的方式來調用,這樣一來我們可以清晰知道哪些 api 服務會被哪些 api/client 所調用,而且安全性來說更好。
為了保持後端服務的代碼更好的兼容性,希望能夠實現相同的代碼通過在 Startup 里不同的配置實現不同的 Authorization 邏輯,原來我們的服務的 Authorize 都是以 Authorize("policyName") 的形式來寫的,這樣一來我們只需要修改這個 Policy 的授權配置就可以了。對於 AllowAnonymous 就希望可以通過一種類似的方式來實現,通過自定義一個 Policy 來實現自己的邏輯

實現方式

將 action 上的 AllowAnonymous 替換為 Authorize("policyName"),在沒有設置 Authorize 的 controller 上增加 Authorize("policyName")

public class AllowAnonymousPolicyTransformer : IApplicationModelConvention
{
    private readonly string _policyName;

    public AllowAnonymousPolicyTransformer() : this("anonymous")
    {
    }

    public AllowAnonymousPolicyTransformer(string policyName) => _policyName = policyName;

    public void Apply(ApplicationModel application)
    {
        foreach (var controllerModel in application.Controllers)
        {
            if (controllerModel.Filters.Any(_ => _.GetType() == typeof(AuthorizeFilter)))
            {
                foreach (var actionModel in controllerModel.Actions)
                {
                    if (actionModel.Filters.Any(_ => _.GetType() == typeof(AllowAnonymousFilter)))
                    {
                        var allowAnonymousFilter = actionModel.Filters.First(_ => _.GetType() == typeof(AllowAnonymousFilter));
                        actionModel.Filters.Remove(allowAnonymousFilter);
                        actionModel.Filters.Add(new AuthorizeFilter(_policyName));
                    }
                }
            }
            else
            {
                if (controllerModel.Filters.Any(_ => _.GetType() == typeof(AllowAnonymousFilter)))
                {
                    var allowAnonymousFilter = controllerModel.Filters.First(_ => _.GetType() == typeof(AllowAnonymousFilter));
                    controllerModel.Filters.Remove(allowAnonymousFilter);
                }
                controllerModel.Filters.Add(new AuthorizeFilter(_policyName));
            }
        }
    }
}

public static class MvcBuilderExtensions
{
    public static IMvcBuilder AddAnonymousPolicyTransformer(this IMvcBuilder builder)
    {
        builder.Services.Configure<MvcOptions>(options =>
        {
            options.Conventions.Insert(0, new AllowAnonymousPolicyTransformer());
        });
        return builder;
    }

    public static IMvcBuilder AddAnonymousPolicyTransformer(this IMvcBuilder builder, string policyName)
    {
        builder.Services.Configure<MvcOptions>(options =>
        {
            options.Conventions.Insert(0, new AllowAnonymousPolicyTransformer(policyName));
        });
        return builder;
    }
}

controller 中的代碼:

[Route("api/[controller]")]
public class ValuesController : Controller
{
    private readonly ILogger _logger;

    public ValuesController(ILogger<ValuesController> logger)
    {
        _logger = logger;
    }

    // GET api/values
    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
        var msg = $"IsAuthenticated: {User.Identity.IsAuthenticated} ,UserName: {User.Identity.Name}";
        _logger.LogInformation(msg);
        return new string[] { msg };
    }

    // GET api/values/5
    [Authorize]
    [HttpGet("{id:int}")]
    public ActionResult<string> Get(int id)
    {
        return "value";
    }
    // ...
}

Startup 中 ConfigureServices 配置:

var anonymousPolicyName = "anonymous";

services.AddAuthorization(options =>
{
    options.AddPolicy(anonymousPolicyName, builder => builder.RequireAssertion(context => context.User.Identity.IsAuthenticated));

    options.DefaultPolicy = new AuthorizationPolicyBuilder(HeaderAuthenticationDefaults.AuthenticationSchema)
        .RequireAuthenticatedUser()
        .RequireAssertion(context => context.User.GetUserId<int>() > 0)
        .Build();
});

services.AddMvc(options =>
    {
        options.Conventions.Add(new ApiControllerVersionConvention());
    })
    .AddAnonymousPolicyTransformer(anonymousPolicyName)
    ;

實現效果

訪問原來的匿名接口

userId 為0訪問原來的匿名接口

userId 大於0訪問原來的匿名接口

userId 為0訪問需要登錄的接口

userId 大於0訪問需要登錄的接口

More

注:按照上面的做法已經可以做到自定義 policy 代替 AllowAnonymous 的行為,但是原來返回的401,現在可能返回到就是 403 了

Reference

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

台灣海運大陸貨務運送流程

兩岸物流進出口一站式服務

挪威擬修法禁售汽油車

做為全球電動車市佔率最高的國家,挪威政府對於推行採用電動車不遺餘力。外媒報導,挪威打算進一步修法,目標是在2025年時達成全面禁售汽油車。

挪威目前有24%的汽車屬電動車,去年登記在案的電動車超過五萬輛,且首都奧斯陸是全球電動車密度最高的城市。據外媒《獨立報》、《Dagens Naeringsliv》等媒體報導,挪威朝野四大黨的國會議員已達成立法共識,計畫在2025年前全面禁售或者大量減產汽油車;若計畫順利,挪威將成為全球第一個全面改用電動車的國家。

但由於挪威高度依賴石油產業,此決議是否成行、若成行後會對國家產業帶來何種衝擊,仍在評估當中。

對於這項提案,特斯拉(Tesla)執行長Elon Musk在推特上表示:「這國家太讚了!」若挪威正式通過這項法案,將在國際間產生示範效果,再次推高電動車的接受度。

Just heard that Norway will ban new sales of fuel cars in 2025. What an amazingly awesome country. You guys rock!!

— Elon Musk (@elonmusk)

 

(首頁圖片來源:)

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

台灣海運大陸貨務運送流程

兩岸物流進出口一站式服務

車用顯示及光學技術研討會 – 2016 台北光電周展場直擊

在光電協會(PIDA)所舉辦的一系列車IOT與車用光電的研討會當中。針對了車用顯示以及光學技術領域。PIDA邀請了幾位業界專家與與會者分享最新的技術動態。   成立於2014年的及至微電機公司,在本次研討會由陳明舜處長為我們分享的主題是雷射掃描在車用電子系統的應用。及至微以MEMS Mirror為核心技術, 整合光學、機械、電子、軟體技術, 以雙軸的MEMS Scanner,搭配RGB 雷射光源,提供雷射投影模組汽車的HUD應用當中。   陳明舜處長分享了未來汽車顯示器的技術走向,包括Tesla等汽車都已經把儀表板的訊息整合到車用面板了,未來有機會用光學投影的方式來呈現出更多行車資訊。其中用雷射投影的方式,其原理是利用RGB雷射光束將畫面掃描出來,對比度高,且沒有對焦問題,可以投影在任何的曲面的物體上面。儘管雷射投影模組的價格昂貴,目前都還要USD 200元/組,其中雷射光源佔了主要的成本結構比重非常高,但隨著各家雷射光源廠商技術有所突破以及大量生產,價格有機會下降。

▲及至微的雷射投影系統   而怡利電子的陳儒賢經理則是分享了車用抬頭顯示器的技術發展趨勢。目前的HUD大致上可以分為下列三種:   Windshield HUD: 部分的BMW車種搭載了 Windshield HUD。透過HUD系統將車速,導航訊息利用投影的方式,將虛像投影至前擋玻璃前方2.5M的距離。其原理主要透過反射方式將光線投影至眼睛中,因此前擋玻璃也需要經過特殊處理。包括讓想要呈現的虛像能更折射到眼睛,該前擋玻璃又能夠看到前方的車況。因此該玻璃需有不同厚度與特殊角度,來消除掉重疊影像。因此該套系統的成本十分高昂,另外駕駛座前方也需要保留很大的空間來安裝這套HUD系統。   HUD Combiner: 由於前述提到的Windshield HUD成本過於高昂,因此各家車廠想盡辦法降低成本。而折衷的方式,就是另外做一個經過特殊處理的前擋玻璃,與投射系統整合成整套模組。但因為模組沒有辦法懸空,因此該玻璃的位置與眼睛無法呈現水平。光路較短,虛擬影像距離縮短,僅1~2M。   LED/TFT reflector: 這是較為常見的系統,且大量應用在後裝市場的系統。利用LED矩陣式投影或者是TFT面板反射影像在汽車的前擋玻璃的膜片上。因此眼睛看到的是實像。而LED矩陣能夠顯示的信息較為有限,最多僅能顯示數字與符號。至於TFT面板反射投影雖然能夠提供較多的影像信息,但是在戶外陽光充足的環境下,TFT面板的亮度需要達到一萬nits以上,影像才不會被陽光干擾。

 
▲怡利電子   合盈光電的許玄岳董事長則是介紹了全球車用攝影機的發展趨勢。在自動駕駛時代來臨下,每台汽車至少需要裝配6-7個攝影機。而這些攝影機的鏡頭如何在戶外的環境下,能夠不被雨水干擾影像,或是沙塵刮傷鏡頭都是需要處理的課題。合盈光電目前除了針對車用鏡頭的材料開發方面做了許多努力之外,也開發出結合倒車影像以及紅外線雷射距離偵測系統。許董事長提到,2018年全美所有車子都需要裝配倒車影像攝影機。若可以將倒車影像攝影機以及距離偵測功能整合在一起,就不需要再多一個倒車雷達了,以目前汽車每年的銷售數量約九千萬台,一台倒車雷達約US$100元,車廠一年可以省下90億美金。   許董事長強調,合盈光電在車用光電的發展方向會將電子,光學,材料,軟體,MEMS等各種技術做整合。而台灣的優勢在於電子產業供應鏈相當完整,方圓一百公里內都可以找到各種供應商。但對於發展汽車電子產業最大挑戰在於台灣的市場太小,沒有龐大的汽車品牌以及汽車工業支持。許多技術都還是要去接觸德國,日本等汽車原廠才有機會導入。加上電子業者對於車規不了解,將是發展汽車電子產業的最大障礙。

▲合盈光電 (本文內容由授權使用)  

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

台灣海運大陸貨務運送流程

兩岸物流進出口一站式服務

Gogoro獲全球首張電動機車用電池UL 2271認證

全球安全科學檢驗實驗室Underwriters Laboratories (UL) 宣布台灣電動機車品牌Gogoro 所研發的智慧電池通過UL 2271測試認證。UL 2271是全球第一本針對輕型電動機車電池推出的安全標準,而Gogoro的車用鋰電池則獲得了全球首張認證書。

Gogoro除拔得頭籌取得UL 2271認證外,也是前全球唯一同時取得UL、IEC、CNS三項標準核可的廠商,將可讓Gogoro在站穩台灣電動機車市場龍頭之餘,進一步跨入歐洲、北美等國際市場。

UL 能源系統與電動交通產業全球工程總監Francisco Martinez 表示,台灣有成為全球電動機車發展重鎮的實力,而UL 2271則聚焦於電動機車之鋰電池安全性的檢測與審查,且格外重視特殊使用條件與環境氣候的測試,以考驗安全性問題。

根據定義,UL 2271 標準係針對輕型電動車電池產品,評估其在一般道路與越野特定道路環境下的使用情況。該標準不僅完整考量實際使用可能發生的危險,並會進行特殊的測試要求,例如震動、衝擊、擠壓、翻轉和水浸測試等,再加上軟硬體的功能性安全評估。

Martinez表示:「Gogoro 智慧電池取得UL 認證,證明Gogoro 製造的產品已達到世界級的安全水準,其將減少消費者對於電動機車電池安全的疑慮,更有助於Gogoro 邁向國際。」

Gogoro 執行長暨共同創辦人陸學森對此回應:「目前Gogoro 有超過8,000 位車主,每日平均創造近2,500 人次的電池交換,智慧電池在今日得到世界安全權威UL 認證,除了代表業界給予我們高標準的肯定外,也象徵Gogoro 對消費者安全承諾的實踐。」

除了頒發認證給Gogoro之外,UL期待未來在能源與電動機車服務方面,包括電動車、電動機車產品與電池、能源系統標準的開發,以及歐洲電動車、電動機車及儲能系統之標準研發方面與Gogoro 有更多深度探討與交流;Gogoro 於未來亦將尋求參與UL STP 標準技術小組的機會,提供產業觀點,以更廣闊的國際視野,共同守護消費者安全。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

台灣海運大陸貨務運送流程

兩岸物流進出口一站式服務