Skip to content

Commit

Permalink
Finish Release-5.5.0-20240909
Browse files Browse the repository at this point in the history
  • Loading branch information
lszzy committed Sep 9, 2024
2 parents b46db01 + 2fbd530 commit 6bb0518
Show file tree
Hide file tree
Showing 37 changed files with 478 additions and 67 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## [5.5.0] - 2024-09-09

### Added
* Web debugging server adds the function of generating QR code images from URL
* Browse object interface supports adding custom entry function
* Synchronize the latest trunk code of FLEX

## [5.4.3] - 2024-08-27

### Added
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG_CN.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# 更新日志

## [5.5.0] - 2024-09-09

### Added
* Web调试服务器新增URL生成二维码图片功能
* 浏览对象界面支持新增自定义入口功能
* 同步FLEX最新主干代码

## [5.4.3] - 2024-08-27

### Added
Expand Down
2 changes: 1 addition & 1 deletion Example/Example/ObjectivecController.m
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ - (void)onWebView {
WKWebView *webView = [[WKWebView alloc] initWithFrame:webController.view.bounds];
webView.allowsBackForwardNavigationGestures = YES;
[webController.view addSubview:webView];
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.wuyong.site/"]]];
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.wuyong.site/"]]];

UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:webController];
navController.modalPresentationStyle = UIModalPresentationFullScreen;
Expand Down
42 changes: 38 additions & 4 deletions Example/Example/SwiftController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,31 +63,54 @@ import CoreLocation
chooseFileButton.frame = CGRect(x: self.view.frame.size.width / 2 - 100, y: 120, width: 200, height: 30)
self.view.addSubview(chooseFileButton)

let requestImageButton = UIButton(type: .system)
requestImageButton.setTitle("Request Image", for: .normal)
requestImageButton.addTarget(self, action: #selector(onRequestImage), for: .touchUpInside)
requestImageButton.frame = CGRect(x: self.view.frame.size.width / 2 - 100, y: 170, width: 200, height: 30)
self.view.addSubview(requestImageButton)

let crashButton = UIButton(type: .system)
crashButton.setTitle("Crash", for: .normal)
crashButton.addTarget(self, action: #selector(onCrash), for: .touchUpInside)
crashButton.frame = CGRect(x: self.view.frame.size.width / 2 - 100, y: 170, width: 200, height: 30)
crashButton.frame = CGRect(x: self.view.frame.size.width / 2 - 100, y: 220, width: 200, height: 30)
self.view.addSubview(crashButton)

let nslogButton = UIButton(type: .system)
nslogButton.setTitle("NSLog", for: .normal)
nslogButton.addTarget(self, action: #selector(onNSLog), for: .touchUpInside)
nslogButton.frame = CGRect(x: self.view.frame.size.width / 2 - 100, y: 220, width: 200, height: 30)
nslogButton.frame = CGRect(x: self.view.frame.size.width / 2 - 100, y: 270, width: 200, height: 30)
self.view.addSubview(nslogButton)

let oslogButton = UIButton(type: .system)
oslogButton.setTitle("OSLog", for: .normal)
oslogButton.addTarget(self, action: #selector(onOSLog), for: .touchUpInside)
oslogButton.frame = CGRect(x: self.view.frame.size.width / 2 - 100, y: 270, width: 200, height: 30)
oslogButton.frame = CGRect(x: self.view.frame.size.width / 2 - 100, y: 320, width: 200, height: 30)
self.view.addSubview(oslogButton)

let imageView = UIImageView()
self.imageView = imageView
imageView.contentMode = .scaleAspectFit
imageView.frame = CGRect(x: self.view.frame.size.width / 2 - 50, y: 320, width: 100, height: 100)
imageView.frame = CGRect(x: self.view.frame.size.width / 2 - 50, y: 370, width: 100, height: 100)
self.view.addSubview(imageView)
}

// MARK: - Public
public static func registerCustomEntry() {
FWDebugManager.sharedInstance().registerEntry("📱 Custom Entry") { vc in
vc.dismiss(animated: true) {
print("Custom Entry clicked")
}
}

FWDebugManager.sharedInstance().registerObjectEntry("Custom Entry", title: "Custom") { object in
return object is UIViewController
} actionBlock: { vc, object in
vc.dismiss(animated: true) {
print("Custom Entry clicked")
}
}
}

// MARK: - CLLocationManagerDelegate
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
//if let location = locations.last {
Expand Down Expand Up @@ -144,6 +167,17 @@ import CoreLocation
}
}

func onRequestImage() {
let urlRequest = URLRequest(url: URL(string: "http://kvm.wuyong.site/images/images/progressive.jpg")!)
let dataTask = URLSession.shared.dataTask(with: urlRequest) { [weak self] data, _, _ in
guard let data = data else { return }
DispatchQueue.main.async { [weak self] in
self?.imageView?.image = UIImage(data: data)
}
}
dataTask.resume()
}

func onClose() {
dismiss(animated: true)
}
Expand Down
1 change: 1 addition & 0 deletions Example/Example/ViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ @implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];

[SwiftController registerCustomEntry];
self.title = @"Example";
self.edgesForExtendedLayout = UIRectEdgeNone;
self.view.backgroundColor = [UIColor whiteColor];
Expand Down
2 changes: 1 addition & 1 deletion FWDebug.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "FWDebug"
s.version = "5.4.3"
s.version = "5.5.0"
s.summary = "ios debug library"
s.homepage = "http://wuyong.site"
s.license = "MIT"
Expand Down
28 changes: 28 additions & 0 deletions FWDebug/Assets/GCDWebUploader.bundle/Contents/Resources/js/url.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,16 @@ function _openUrl() {
});
}

function _qrcodeUrl() {
var text = $("#input-url").val().trim();
var url = "qrcode?text=" + encodeURIComponent(text);

$("#image-title").text("Qrcode");
$("#image-view").attr("src", url);
$("#copy-textarea").val(text);
$("#image-modal").modal("show");
}

$(document).ready(function() {

$("#share-confirm").click(function(event) {
Expand All @@ -157,6 +167,19 @@ $(document).ready(function() {
event.preventDefault();
});

$("#image-confirm").click(function(event) {
$("#image-modal").modal("hide");
_copyText();
event.preventDefault();
});

$("#image-open").click(function(event) {
$("#image-modal").modal("hide");
var url = $("#image-view").attr("src");
window.open(url + "&size=", "_blank");
event.preventDefault();
});

$("#reload").click(function(event) {
_reload(_path);
event.preventDefault();
Expand Down Expand Up @@ -270,6 +293,11 @@ $(document).ready(function() {
_openUrl();
event.preventDefault();
});

$("#qrcode-url").click(function(event) {
_qrcodeUrl();
event.preventDefault();
});

$("#select-type").val(_inputType);
if (_inputType == "") {
Expand Down
22 changes: 22 additions & 0 deletions FWDebug/Assets/GCDWebUploader.bundle/Contents/Resources/url.html
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ <h1>%header%</h1>
<button type="button" class="btn btn-default" id="submit-url">
<span class="glyphicon glyphicon-phone"></span> Open
</button>
<button type="button" class="btn btn-default" id="qrcode-url">
<span class="glyphicon glyphicon-qrcode"></span> Qrcode
</button>
</div>

<div class="panel panel-default">
Expand Down Expand Up @@ -146,6 +149,25 @@ <h4 class="modal-title" id="share-title">%name%</h4>
</div>
</div>

<div class="modal fade" id="image-modal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h4 class="modal-title" id="image-title"></h4>
</div>
<div class="modal-body">
<img src="" class="img-responsive center-block" id="image-view">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-default" id="image-open">Full Screen</button>
<button type="button" class="btn btn-primary" id="image-confirm">Copy</button>
</div>
</div>
</div>
</div>

<script type="text/x-tmpl" id="template-listing">
<tr class="row-line">
<td class="column-icon">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,16 @@

#import "FLEXObjectExplorerViewController.h"

NS_ASSUME_NONNULL_BEGIN

@interface FLEXObjectExplorerViewController (FWDebug)

+ (void)fwDebugLoad;

+ (void)fwDebugRegisterEntry:(NSString *)entryName title:(NSString *)title filter:(nullable BOOL (^)(id object))filter actionBlock:(void (^)(__kindof UIViewController *viewController, id object))actionBlock;

+ (void)fwDebugRemoveEntry:(NSString *)entryName;

@end

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,21 @@
#import "FBRetainCycleDetector+FWDebug.h"
#import <malloc/malloc.h>

static NSMutableArray *fwDebugCustomObjectEntries = nil;

@interface FWDebugCustomObjectEntry : NSObject

@property (nonatomic, copy) NSString *entryName;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) BOOL (^filter)(id object);
@property (nonatomic, copy) void (^actionBlock)(__kindof UIViewController *viewController, id object);

@end

@implementation FWDebugCustomObjectEntry

@end

@interface FLEXObjectExplorerViewController ()

@property (nonatomic, readonly) FLEXSingleRowSection *descriptionSection;
Expand Down Expand Up @@ -49,6 +64,33 @@ + (void)fwDebugLoad
}];
}

+ (void)fwDebugRegisterEntry:(NSString *)entryName title:(NSString *)title filter:(BOOL (^)(id _Nonnull))filter actionBlock:(void (^)(__kindof UIViewController * _Nonnull, id _Nonnull))actionBlock
{
FWDebugCustomObjectEntry *entry = [FWDebugCustomObjectEntry new];
entry.entryName = entryName;
entry.title = title;
entry.filter = filter;
entry.actionBlock = actionBlock;

if (!fwDebugCustomObjectEntries) {
fwDebugCustomObjectEntries = [NSMutableArray new];
}
[fwDebugCustomObjectEntries addObject:entry];
}

+ (void)fwDebugRemoveEntry:(NSString *)entryName
{
if (!fwDebugCustomObjectEntries) return;

NSMutableArray *removeEntries = [NSMutableArray new];
for (FWDebugCustomObjectEntry *entry in fwDebugCustomObjectEntries) {
if ([entry.entryName isEqualToString:entryName]) {
[removeEntries addObject:entry];
}
}
[fwDebugCustomObjectEntries removeObjectsInArray:removeEntries];
}

#pragma mark - FWDebug

- (void)fwDebugSearchItem
Expand All @@ -75,7 +117,7 @@ - (void)fwDebugSearchItem
};
}

FLEXSingleRowSection *customSection = [FLEXSingleRowSection title:@"Custom" reuse:kFLEXDefaultCell cell:^(FLEXTableViewCell *cell) {
FLEXSingleRowSection *customSection = [FLEXSingleRowSection title:@"Time Profiler" reuse:kFLEXDefaultCell cell:^(FLEXTableViewCell *cell) {
cell.titleLabel.font = UIFont.flex_defaultTableCellFont;
cell.titleLabel.text = @"Time Profiler";
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
Expand All @@ -89,7 +131,7 @@ - (void)fwDebugSearchItem
};
[sections insertObject:customSection atIndex:0];
} else {
FLEXSingleRowSection *customSection = [FLEXSingleRowSection title:@"Custom" reuse:kFLEXDefaultCell cell:^(FLEXTableViewCell *cell) {
FLEXSingleRowSection *customSection = [FLEXSingleRowSection title:@"Runtime Headers" reuse:kFLEXDefaultCell cell:^(FLEXTableViewCell *cell) {
cell.titleLabel.font = UIFont.flex_defaultTableCellFont;
cell.titleLabel.text = @"Runtime Headers";
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
Expand Down Expand Up @@ -118,6 +160,27 @@ - (void)fwDebugSearchItem
};
[sections insertObject:customSection atIndex:0];
}

if (fwDebugCustomObjectEntries) {
for (FWDebugCustomObjectEntry *entry in [fwDebugCustomObjectEntries reverseObjectEnumerator]) {
if (entry.filter && !entry.filter(explorer.object)) continue;

FLEXSingleRowSection *customSection = [FLEXSingleRowSection title:entry.title reuse:kFLEXDefaultCell cell:^(FLEXTableViewCell *cell) {
cell.titleLabel.font = UIFont.flex_defaultTableCellFont;
cell.titleLabel.text = entry.entryName;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}];
customSection.filterMatcher = ^BOOL(NSString *filterText) {
return [entry.entryName localizedCaseInsensitiveContainsString:filterText];
};
customSection.selectionAction = ^(UIViewController *host) {
if (entry.actionBlock) {
entry.actionBlock(host, explorer.object);
}
};
[sections insertObject:customSection atIndex:0];
}
}
return sections.copy;
}

Expand Down
37 changes: 35 additions & 2 deletions FWDebug/Classes/Private/GCDWebServer/FWDebugWebServer.m
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,39 @@ + (void)setupServer
});
}];

[_webDebug addHandlerForMethod:@"GET"
path:@"/qrcode"
requestClass:[GCDWebServerRequest class]
asyncProcessBlock:^(__kindof GCDWebServerRequest *request, GCDWebServerCompletionBlock completionBlock) {
NSString *queryText = request.query[@"text"] ?: @"";
NSString *querySize = request.query[@"size"] ?: @"";
CGFloat size = querySize.doubleValue > 0 ? querySize.doubleValue : 375.0;

NSData *textData = [queryText dataUsingEncoding:NSUTF8StringEncoding];
CIFilter *fileter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
[fileter setValue:textData forKey:@"inputMessage"];
[fileter setValue:@"H" forKey:@"inputCorrectionLevel"];
CIImage *ciImage = fileter.outputImage;

CIFilter *colorFilter = [CIFilter filterWithName:@"CIFalseColor"];
[colorFilter setValue:ciImage forKey:@"inputImage"];
[colorFilter setValue:[CIColor colorWithCGColor:UIColor.blackColor.CGColor] forKey:@"inputColor0"];
[colorFilter setValue:[CIColor colorWithCGColor:UIColor.whiteColor.CGColor] forKey:@"inputColor1"];

CIImage *outImage = colorFilter.outputImage;
CGFloat outWidth = outImage.extent.size.width;
CGFloat scale = outWidth > 0 ? (size / outWidth) : 1;
outImage = [outImage imageByApplyingTransform:CGAffineTransformMakeScale(scale, scale)];
UIImage *qrcodeImage = [UIImage imageWithCIImage:outImage];

NSData *imageData = UIImageJPEGRepresentation(qrcodeImage, 1.0);
if (imageData != nil) {
completionBlock([GCDWebServerDataResponse responseWithData:imageData contentType:@"image/jpeg"]);
} else {
completionBlock([GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_NotFound message:@"\"%@\" does not exist", request.path]);
}
}];

[_webDebug addHandlerForMethod:@"DELETE"
path:@"/urls"
requestClass:[GCDWebServerRequest class]
Expand Down Expand Up @@ -624,7 +657,7 @@ + (NSArray *)transactionSections:(FLEXHTTPTransaction *)transaction
[sections addObject:detailSection];
} else {
[sections addObject:@{
@"name": [NSString stringWithFormat:@"%@: %@", row.title, mimeType ?: row.detailText],
@"name": [NSString stringWithFormat:@"%@: %@", row.title, requestData != nil ? (mimeType ?: row.detailText) : row.detailText],
@"action": @"view",
@"type": @"copy",
@"title": row.title ?: @"",
Expand All @@ -639,7 +672,7 @@ + (NSArray *)transactionSections:(FLEXHTTPTransaction *)transaction
[sections addObject:detailSection];
} else {
[sections addObject:@{
@"name": [NSString stringWithFormat:@"%@: %@", row.title, mimeType ?: row.detailText],
@"name": [NSString stringWithFormat:@"%@: %@", row.title, responseData != nil ? (mimeType ?: row.detailText) : row.detailText],
@"action": @"view",
@"type": @"copy",
@"title": row.title ?: @"",
Expand Down
Loading

0 comments on commit 6bb0518

Please sign in to comment.